Index: trunk/koffice/kspread/CHANGES =================================================================== --- trunk/koffice/kspread/CHANGES (revision 152991) +++ trunk/koffice/kspread/CHANGES (revision 152992) @@ -1,58 +1,61 @@ Changes from 1.1 to 1.2 ======================= Until beta2: ------------ - bug fixes - perfomance enhancements - added show/hide grid on printout option - paper layout now a property of sheet (not the whole workbook) - header/footer now a property of sheet (not the whole workbook) - Sort enhanced for - sorting by up to three rows or columns - possibility of putting the result of sorting some place else - you can use a custom lists (like days of week) as a primary key - option if you want to copy the layout or not - you can define a row header which gets copied but not sorted - auto continuation support for every direction and all types supported in KSpread and for more complex series like 1,3,4,6,... - just one "copy" instead of "copy" and "copy as text" - insertion of series supports now doubles and decreasing series - support for inserting data from SQL databases - implemented "Goal Seek" +- implemented new shortcuts for cell formating + (Excel like): Ctrl+!, $, %, #, ^, @, &, F4 (I will put a description of + them in the KSpread handbook later) Until beta1: ------------ - bug fixes :-) - performance enhancements - support up to 2^15 columns and rows, formerly it was 676 columns and 10000 rows - add support for spell-check - many new built-in functions (see detailed list below) - function name is now case-insensitive - "Related Function" in formula editor - move functions in kspread_interpreter into several kspread_functions_*.cc New functions added: conversion: INT2BOOL, CharToAscii, AsciiToChar, BOOL2STRING, NUM2STRING, BOOL2INT math: DIV, LCD, PRODUCT, LCM, TOGGLE, TRIM, ABS text: COMPARE, CLEAN, SLEEK, PROPER, REPLACE date/time: DAYS, WEEKS, MONTHS, YEARS financial: DB, SLN, SYD, EURO logical: XOR statistical: CHIDIST, FDIST, TDIST, CONFIDENCE, BETADIST, GAMMADIST, PHI, GAUSS, MEDIAN, POISSON, GAMMALN, NORMINV, NORMSINV, WEIBULL, EXPONDIST, NORMDIST, NORMSDIST, FISHER, FISHERINV, LOGNORMDIST Index: trunk/koffice/kspread/kspread_view.cc =================================================================== --- trunk/koffice/kspread/kspread_view.cc (revision 152991) +++ trunk/koffice/kspread/kspread_view.cc (revision 152992) @@ -1,4661 +1,4665 @@ /* This file is part of the KDE project Copyright (C) 1998, 1999 Torben Weis 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include // has to be first #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kspread_map.h" #include "kspread_dlg_scripts.h" #include "kspread_dlg_cons.h" #include "kspread_dlg_database.h" #include "kspread_dlg_goalseek.h" #include "kspread_canvas.h" #include "kspread_tabbar.h" #include "kspread_dlg_formula.h" #include "kspread_dlg_special.h" #include "kspread_dlg_sort.h" #include "kspread_dlg_anchor.h" #include "kspread_dlg_layout.h" #include "kspread_dlg_show.h" #include "kspread_dlg_insert.h" #include "kspread_handler.h" #include "kspread_events.h" #include "kspread_editors.h" #include "kspread_dlg_format.h" // #include "kspread_dlg_oszi.h" #include "kspread_dlg_conditional.h" #include "kspread_dlg_series.h" #include "kspread_dlg_reference.h" #include "kspread_dlg_area.h" #include "kspread_dlg_resize2.h" #include "kspread_dlg_preference.h" #include "kspread_dlg_comment.h" #include "kspread_dlg_angle.h" #include "kspread_dlg_goto.h" #include "kspread_dlg_validity.h" #include "kspread_dlg_pasteinsert.h" #include "kspread_dlg_showColRow.h" #include "kspread_dlg_list.h" #include "kspread_undo.h" #include "handler.h" #include "KSpreadViewIface.h" #include #include #include /***************************************************************************** * * KSpreadView * *****************************************************************************/ KSpreadScripts* KSpreadView::m_pGlobalScriptsDialog = 0L; // non flickering version of KSpell. class KSpreadSpell : public KSpell { public: KSpreadSpell(QWidget *parent, const QString &caption, QObject *receiver, const char *slot, KSpellConfig *kcs=0, bool progressbar = FALSE, bool modal = true ) : KSpell(parent, caption, receiver, slot, kcs, progressbar, modal) { } // override check(...) // mostly copied from kdelibs/kspell/kspell.cpp // the dialog gets created but it gets only shown if something // is misspelled. Otherwise for every cell the dialog would pop up // and disappear bool check( const QString &_buffer, bool _usedialog = true ) { QString qs; usedialog=_usedialog; setUpDialog (); //set the dialog signal handler dialog3slot = SLOT (check3 ()); kdDebug(750) << "KS: check" << endl; origbuffer = _buffer; if ( ( totalpos = origbuffer.length() ) == 0 ) { emit done(origbuffer); return FALSE; } // Torben: I corrected the \n\n problem directly in the // origbuffer since I got errors otherwise if ( origbuffer.right(2) != "\n\n" ) { if (origbuffer.at(origbuffer.length() - 1) != '\n') { origbuffer += '\n'; origbuffer += '\n'; //shouldn't these be removed at some point? } else origbuffer += '\n'; } newbuffer = origbuffer; // KProcIO calls check2 when read from ispell connect(proc, SIGNAL (readReady(KProcIO *)), this, SLOT (check2(KProcIO *))); proc->fputs ("!"); //lastpos is a position in newbuffer (it has offset in it) offset = lastlastline = lastpos = lastline = 0; emitProgress (); // send first buffer line int i = origbuffer.find('\n', 0) + 1; qs = origbuffer.mid (0, i); cleanFputs(qs, FALSE); lastline = i; //the character position, not a line number ksdlg->hide(); return TRUE; } // mostly copied from kdelibs/kspell/kspell.cpp void check2 (KProcIO *) { int e, tempe; QString word; QString line; do { tempe = proc->fgets (line); //get ispell's response if (tempe > 0) { e = parseOneResponse(line, word, sugg); if ( (e == 3) // mistake || (e == 2) ) // replace { dlgresult =- 1; // for multibyte encoding posinline needs correction if (ksconfig->encoding() == KS_E_UTF8) { // convert line to UTF-8, cut at pos, convert back to UCS-2 // and get string length posinline = (QString::fromUtf8(origbuffer.mid(lastlastline, lastline - lastlastline).utf8(), posinline)).length(); } lastpos = posinline + lastlastline + offset; //orig is set by parseOneResponse() if (e == 2) // replace { dlgreplacement = word; emit corrected (orig, replacement(), lastpos); offset += replacement().length() - orig.length(); newbuffer.replace (lastpos, orig.length(), word); } else //MISTAKE { cwword = word; if ( usedialog ) { // show the word in the dialog ksdlg->show(); dialog (word, sugg, SLOT (check3())); } else { // No dialog, just emit misspelling and continue emit misspelling (word, sugg, lastpos); dlgresult = KS_IGNORE; check3(); } return; } } } emitProgress (); //maybe } while (tempe > 0); proc->ackRead(); if (tempe == -1) //we were called, but no data seems to be ready... return; //If there is more to check, then send another line to ISpell. if ((unsigned int)lastline < origbuffer.length()) { int i; QString qs; lastpos = (lastlastline = lastline) + offset; //do we really want this? i = origbuffer.find('\n', lastline)+1; qs = origbuffer.mid (lastline, i-lastline); cleanFputs (qs, FALSE); lastline = i; return; } else //This is the end of it all { ksdlg->hide(); newbuffer.truncate (newbuffer.length()-2); emitProgress(); emit done (newbuffer); } } }; KSpreadView::KSpreadView( QWidget *_parent, const char *_name, KSpreadDoc* doc ) : KoView( doc, _parent, _name ) { kdDebug(36001) << "sizeof(KSpreadCell)=" << sizeof(KSpreadCell) <setRange( 0, 4096 ); m_pVertScrollBar->setOrientation( QScrollBar::Vertical ); // Horz. Scroll Bar m_pHorzScrollBar = new QScrollBar( this, "ScrollBar_1" ); m_pHorzScrollBar->setRange( 0, 4096 ); m_pHorzScrollBar->setOrientation( QScrollBar::Horizontal ); // Tab Bar m_pTabBarFirst = newIconButton( "tab_first" ); QObject::connect( m_pTabBarFirst, SIGNAL( clicked() ), SLOT( slotScrollToFirstTable() ) ); m_pTabBarLeft = newIconButton( "tab_left" ); QObject::connect( m_pTabBarLeft, SIGNAL( clicked() ), SLOT( slotScrollToLeftTable() ) ); m_pTabBarRight = newIconButton( "tab_right" ); QObject:: connect( m_pTabBarRight, SIGNAL( clicked() ), SLOT( slotScrollToRightTable() ) ); m_pTabBarLast = newIconButton( "tab_last" ); QObject::connect( m_pTabBarLast, SIGNAL( clicked() ), SLOT( slotScrollToLastTable() ) ); m_pTabBar = new KSpreadTabBar( this ); QObject::connect( m_pTabBar, SIGNAL( tabChanged( const QString& ) ), this, SLOT( changeTable( const QString& ) ) ); // Paper and Border widgets m_pFrame = new QWidget( this ); m_pFrame->raise(); // Edit Bar m_pToolWidget = new QFrame( this ); QHBoxLayout* hbox = new QHBoxLayout( m_pToolWidget ); hbox->addSpacing( 2 ); m_pPosWidget = new KSpreadLocationEditWidget( m_pToolWidget, this ); m_pPosWidget->setMinimumWidth( 100 ); hbox->addWidget( m_pPosWidget ); hbox->addSpacing( 6 ); m_pCancelButton = newIconButton( "abort", TRUE, m_pToolWidget ); hbox->addWidget( m_pCancelButton ); m_pOkButton = newIconButton( "done", TRUE, m_pToolWidget ); hbox->addWidget( m_pOkButton ); hbox->addSpacing( 6 ); // The widget on which we display the table m_pCanvas = new KSpreadCanvas( m_pFrame, this, doc ); // The line-editor that appears above the table and allows to // edit the cells content. It knows about the two buttons. m_pEditWidget = new KSpreadEditWidget( m_pToolWidget, m_pCanvas, m_pCancelButton, m_pOkButton ); m_pEditWidget->setFocusPolicy( QWidget::StrongFocus ); hbox->addWidget( m_pEditWidget, 2 ); hbox->addSpacing( 2 ); m_pCanvas->setEditWidget( m_pEditWidget ); m_pHBorderWidget = new KSpreadHBorder( m_pFrame, m_pCanvas,this ); m_pVBorderWidget = new KSpreadVBorder( m_pFrame, m_pCanvas ,this ); m_pCanvas->setFocusPolicy( QWidget::StrongFocus ); QWidget::setFocusPolicy( QWidget::StrongFocus ); setFocusProxy( m_pCanvas ); connect( this, SIGNAL( invalidated() ), m_pCanvas, SLOT( update() ) ); connect( this, SIGNAL( regionInvalidated( const QRegion&, bool ) ), m_pCanvas, SLOT( repaint( const QRegion&, bool ) ) ); QObject::connect( m_pVertScrollBar, SIGNAL( valueChanged(int) ), m_pCanvas, SLOT( slotScrollVert(int) ) ); QObject::connect( m_pHorzScrollBar, SIGNAL( valueChanged(int) ), m_pCanvas, SLOT( slotScrollHorz(int) ) ); KSpreadTable *tbl; for ( tbl = m_pDoc->map()->firstTable(); tbl != 0L; tbl = m_pDoc->map()->nextTable() ) addTable( tbl ); tbl = m_pDoc->map()->initialActiveTable(); if (tbl) setActiveTable(tbl); else //activate first table which is not hiding setActiveTable(m_pDoc->map()->findTable(m_pTabBar->listshow().first())); QObject::connect( m_pDoc, SIGNAL( sig_addTable( KSpreadTable* ) ), SLOT( slotAddTable( KSpreadTable* ) ) ); QObject::connect( m_pDoc, SIGNAL( sig_refreshView( ) ), this, SLOT( slotRefreshView() ) ); QObject::connect( m_pDoc, SIGNAL( sig_refreshLocale() ), this, SLOT( slotRefreshLocale())); // Handler for moving and resizing embedded parts ContainerHandler* h = new ContainerHandler( this, m_pCanvas ); connect( h, SIGNAL( popupMenu( KoChild*, const QPoint& ) ), this, SLOT( popupChildMenu( KoChild*, const QPoint& ) ) ); connect( this, SIGNAL( childSelected( KoDocumentChild* ) ), this, SLOT( slotChildSelected( KoDocumentChild* ) ) ); connect( this, SIGNAL( childUnselected( KoDocumentChild* ) ), this, SLOT( slotChildUnselected( KoDocumentChild* ) ) ); // If a selected part becomes active this is like it is deselected // just before. connect( this, SIGNAL( childActivated( KoDocumentChild* ) ), this, SLOT( slotChildUnselected( KoDocumentChild* ) ) ); QTimer::singleShot( 0, this, SLOT( initialPosition() ) ); m_findOptions = 0; KStatusBar * sb = statusBar(); Q_ASSERT(sb); m_sbCalcLabel = sb ? new KStatusBarLabel( QString::null, 0, sb ) : 0; addStatusBarItem( m_sbCalcLabel, 0 ); if(m_sbCalcLabel) connect(m_sbCalcLabel ,SIGNAL(itemPressed( int )),this,SLOT(statusBarClicked(int))); initializeCalcActions(); initializeInsertActions(); initializeEditActions(); initializeAreaOperationActions(); initializeGlobalOperationActions(); initializeCellOperationActions(); initializeCellPropertyActions(); initializeTextFormatActions(); initializeTextLayoutActions(); initializeTextPropertyActions(); initializeTableActions(); initializeSpellChecking(); initializeRowColumnActions(); initializeBorderActions(); } void KSpreadView::initializeCalcActions() { //menu calc /*******************************/ m_menuCalcSum = new KToggleAction( i18n("Sum"), 0, actionCollection(), "menu_sum"); connect( m_menuCalcSum, SIGNAL( toggled( bool ) ), this, SLOT( menuCalc( bool ) ) ); m_menuCalcSum->setExclusiveGroup( "Calc" ); m_menuCalcSum->setToolTip(i18n("Calculate using sum.")); /*******************************/ m_menuCalcMin = new KToggleAction( i18n("Min"), 0, actionCollection(), "menu_min"); connect( m_menuCalcMin, SIGNAL( toggled( bool ) ), this, SLOT( menuCalc( bool ) ) ); m_menuCalcMin->setExclusiveGroup( "Calc" ); m_menuCalcMin->setToolTip(i18n("Calculate using minimum.")); /*******************************/ m_menuCalcMax = new KToggleAction( i18n("Max"), 0, actionCollection(), "menu_max"); connect( m_menuCalcMax, SIGNAL( toggled( bool ) ), this, SLOT( menuCalc( bool ) ) ); m_menuCalcMax->setExclusiveGroup( "Calc" ); m_menuCalcMax->setToolTip(i18n("Calculate using maximum.")); /*******************************/ m_menuCalcAverage = new KToggleAction( i18n("Average"), 0, actionCollection(), "menu_average"); connect( m_menuCalcAverage, SIGNAL( toggled( bool ) ), this, SLOT( menuCalc( bool ) ) ); m_menuCalcAverage->setExclusiveGroup( "Calc" ); m_menuCalcAverage->setToolTip(i18n("Calculate using average.")); /*******************************/ m_menuCalcCount = new KToggleAction( i18n("Count"), 0, actionCollection(), "menu_count"); connect( m_menuCalcCount, SIGNAL( toggled( bool ) ), this, SLOT( menuCalc( bool ) ) ); m_menuCalcCount->setExclusiveGroup( "Calc" ); m_menuCalcCount->setToolTip(i18n("Calculate using the count.")); /*******************************/ m_menuCalcNone = new KToggleAction( i18n("None"), 0, actionCollection(), "menu_none"); connect( m_menuCalcNone, SIGNAL( toggled( bool ) ), this, SLOT( menuCalc( bool ) ) ); m_menuCalcNone->setExclusiveGroup( "Calc" ); m_menuCalcNone->setToolTip(i18n("No calculation.")); /*******************************/ } void KSpreadView::initializeInsertActions() { KAction* tmpAction = NULL; tmpAction = new KAction( i18n("&Math Expression..."), "funct", 0, this, SLOT( insertMathExpr() ), actionCollection(), "insertMathExpr" ); tmpAction->setToolTip(i18n("Insert math expression.")); tmpAction = new KAction( i18n("&Series..."),"series", 0, this, SLOT( insertSeries() ), actionCollection(), "series"); tmpAction ->setToolTip(i18n("Insert a series.")); tmpAction = new KAction( i18n("&Hyperlink..."), 0, this, SLOT( insertHyperlink() ), actionCollection(), "insertHyperlink" ); tmpAction->setToolTip(i18n("Insert an internet hyperlink.")); m_insertPart=new KoPartSelectAction( i18n("&Object..."), "frame_query", this, SLOT( insertObject() ), actionCollection(), "insertPart"); m_insertPart->setToolTip(i18n("Insert an object from another program.")); m_insertChartFrame=new KAction( i18n("&Chart"), "frame_chart", 0, this, SLOT( insertChart() ), actionCollection(), "insertChart" ); m_insertChartFrame->setToolTip(i18n("Insert a chart.")); m_insertFromDatabase = new KAction( i18n("From &Database"), 0, this, SLOT( insertFromDatabase() ), actionCollection(), "insertFromDatabase"); m_insertFromDatabase->setToolTip(i18n("Insert data from a SQL database")); m_insertFromTextfile = new KAction( i18n("From &Text File"), 0, this, SLOT( insertFromTextfile() ), actionCollection(), "insertFromTextfile"); m_insertFromTextfile->setToolTip(i18n("Insert data from a text file to the current cursor position/selection")); m_insertFromClipboard = new KAction( i18n("From &Clipboard"), 0, this, SLOT( insertFromClipboard() ), actionCollection(), "insertFromClipboard"); m_insertFromClipboard->setToolTip(i18n("Insert csv data from the clipboard to the current cursor position/selection")); } void KSpreadView::initializeEditActions() { m_copy = KStdAction::copy( this, SLOT( copySelection() ), actionCollection(), "copy" ); m_copy->setToolTip(i18n("Copy the cell object to the clipboard.")); m_paste = KStdAction::paste( this, SLOT( paste() ), actionCollection(), "paste" ); m_paste->setToolTip(i18n("Paste the contents of the clipboard at the cursor")); m_cut = KStdAction::cut( this, SLOT( cutSelection() ), actionCollection(), "cut" ); m_cut->setToolTip(i18n("Move the cell object to the clipboard.")); m_specialPaste = new KAction( i18n("Special Paste..."), "special_paste",0, this, SLOT( specialPaste() ), actionCollection(), "specialPaste" ); m_specialPaste->setToolTip (i18n("Paste the contents of the clipboard with special options.")); m_undo = KStdAction::undo( this, SLOT( undo() ), actionCollection(), "undo" ); m_undo->setEnabled( FALSE ); m_undo->setToolTip(i18n("Undo the previous action.")); m_redo = KStdAction::redo( this, SLOT( redo() ), actionCollection(), "redo" ); m_redo->setEnabled( FALSE ); m_redo->setToolTip(i18n("Redo the action that has been undone.")); KStdAction::find(this, SLOT(find()), actionCollection()); KStdAction::replace(this, SLOT(replace()), actionCollection()); } void KSpreadView::initializeAreaOperationActions() { m_areaName = new KAction( i18n("Area Name..."), 0, this, SLOT( setAreaName() ), actionCollection(), "areaname" ); m_areaName->setToolTip(i18n("Set a name for a region of the spreadsheet")); m_showArea = new KAction( i18n("Show Area..."), 0, this, SLOT( showAreaName() ), actionCollection(), "showArea" ); m_showArea->setToolTip(i18n("Display a named area")); m_sortList = new KAction( i18n("Custom Lists..."), 0, this, SLOT( sortList() ), actionCollection(), "sortlist" ); m_sortList->setToolTip(i18n("Create custom lists for sorting or auto fill")); m_sort = new KAction( i18n("Sort..."), 0, this, SLOT( sort() ), actionCollection(), "sort" ); m_sort->setToolTip(i18n("Sort a group of cells.")); m_autoSum = new KAction( i18n("AutoSum"), "black_sum", 0, this, SLOT( autoSum() ), actionCollection(), "autoSum" ); m_autoSum->setToolTip(i18n("Insert the 'sum' function")); m_sortDec = new KAction( i18n("Sort Decreasing"), "sort_decrease", 0, this, SLOT( sortDec() ), actionCollection(), "sortDec" ); m_sortDec->setToolTip(i18n("Sort a group of cells in decreasing (last to first) order.")); m_sortInc = new KAction( i18n("Sort Increasing"), "sort_incr", 0, this, SLOT( sortInc() ), actionCollection(), "sortInc" ); m_sortInc->setToolTip(i18n("Sort a group of cells in ascending (first to last) order.")); m_goalSeek = new KAction( i18n("Goal Seek"), 0, this, SLOT( goalSeek() ), actionCollection(), "goalSeek" ); m_goalSeek->setToolTip( i18n("Repeating calculation to find a specific value") ); m_consolidate = new KAction( i18n("Consolidate..."), 0, this, SLOT( consolidate() ), actionCollection(), "consolidate" ); m_consolidate->setToolTip(i18n("Create a region of summary data from a group of similar regions.")); } void KSpreadView::initializeGlobalOperationActions() { m_recalc_workbook = new KAction( i18n("Recalculate Workbook"), Key_F9, this, SLOT( RecalcWorkBook() ), actionCollection(), "RecalcWorkBook" ); m_recalc_workbook->setToolTip(i18n("Recalculate the value of every cell in all worksheets.")); m_recalc_worksheet = new KAction( i18n("Recalculate Sheet"), SHIFT + Key_F9, this, SLOT( RecalcWorkSheet() ), actionCollection(), "RecalcWorkSheet" ); m_recalc_worksheet->setToolTip(i18n("Recalculate the value of every cell in the current worksheet.")); m_preference = new KAction( i18n("Configure KSpread..."),"configure", 0, this, SLOT( preference() ), actionCollection(), "preference" ); m_preference->setToolTip(i18n("Set various KSpread options.")); m_editGlobalScripts = new KAction( i18n("Edit Global Scripts..."), 0, this, SLOT( editGlobalScripts() ), actionCollection(), "editGlobalScripts" ); m_editGlobalScripts->setToolTip("");//i18n("")); /* TODO - what is this? */ m_editLocalScripts = new KAction( i18n("Edit Local Scripts..."), 0, this, SLOT( editLocalScripts() ), actionCollection(), "editLocalScripts" ); m_editLocalScripts->setToolTip("");//i18n("")); /* TODO - what is this? */ m_reloadScripts = new KAction( i18n("Reload Scripts"), 0, this, SLOT( reloadScripts() ), actionCollection(), "reloadScripts" ); m_reloadScripts->setToolTip("");//i18n("")); /* TODO - what is this? */ m_showPageBorders = new KToggleAction( i18n("Show Page Borders"), 0, actionCollection(), "showPageBorders"); connect( m_showPageBorders, SIGNAL( toggled( bool ) ), this, SLOT( togglePageBorders( bool ) ) ); m_showPageBorders->setToolTip("Show on the spreadsheet where the page borders will be."); m_formulaSelection = new KSelectAction(i18n("Formula Selection"), 0, actionCollection(), "formulaSelection"); m_formulaSelection->setToolTip(i18n("Insert a formula.")); QStringList lst; lst.append( "SUM"); lst.append( "AVERAGE"); lst.append( "IF"); lst.append( "COUNT"); lst.append( "MIN"); lst.append( "MAX"); lst.append( i18n("Others...") ); ((KSelectAction*) m_formulaSelection)->setItems( lst ); m_formulaSelection->setComboWidth( 80 ); m_formulaSelection->setCurrentItem(0); connect( m_formulaSelection, SIGNAL( activated( const QString& ) ), this, SLOT( formulaSelection( const QString& ) ) ); m_transform = new KAction( i18n("Transform Object..."), "rotate", 0, this, SLOT( transformPart() ), actionCollection(), "transform" ); m_transform->setToolTip(i18n("Rotate the contents of the cell.")); m_transform->setEnabled( FALSE ); connect( m_transform, SIGNAL( activated() ), this, SLOT( transformPart() ) ); m_paperLayout = new KAction( i18n("Paper Layout..."), 0, this, SLOT( paperLayoutDlg() ), actionCollection(), "paperLayout" ); m_paperLayout->setToolTip(i18n("Specify the layout of the spreadsheet for a printout.")); } void KSpreadView::initializeCellOperationActions() { m_editCell = new KAction( i18n("Modify Cell"),"cell_edit", CTRL + Key_M, this, SLOT( editCell() ), actionCollection(), "editCell" ); m_editCell->setToolTip(i18n("Edit the highlighted cell.")); m_delete = new KAction( i18n("Delete"),"deletecell", 0, this, SLOT( deleteSelection() ), actionCollection(), "delete" ); m_delete->setToolTip(i18n("Delete all contents and formatting of the current cell.")); m_clearText = new KAction( i18n("Text"), 0, this, SLOT( clearTextSelection() ), actionCollection(), "cleartext" ); m_clearText->setToolTip(i18n("Remove the contents of the current cell.")); m_gotoCell = new KAction( i18n("Goto Cell..."),"goto", 0, this, SLOT( gotoCell() ), actionCollection(), "gotoCell" ); m_gotoCell->setToolTip(i18n("Move to a particular cell.")); m_mergeCell = new KAction( i18n("Merge Cells"),"mergecell" ,0, this, SLOT( mergeCell() ), actionCollection(), "mergecell" ); m_mergeCell->setToolTip(i18n("Merge the selected region into one large cell.")); m_dissociateCell = new KAction( i18n("Dissociate Cells"),"dissociatecell" ,0, this, SLOT( dissociateCell() ), actionCollection(), "dissociatecell" ); m_dissociateCell->setToolTip(i18n("Unmerge the current cell.")); m_removeCell = new KAction( i18n("Remove Cell(s)..."), "removecell", 0, this, SLOT( slotRemove() ), actionCollection(), "removeCell" ); m_removeCell->setToolTip(i18n("Removes the current cell from the spreadsheet.")); m_insertCellCopy = new KAction( i18n("Paste with Insertion..."), "insertcellcopy", 0, this, SLOT( slotInsertCellCopy() ), actionCollection(), "insertCellCopy" ); m_insertCellCopy->setToolTip(i18n("Inserts a cell from the clipboard into the spreadsheet.")); m_insertCell = new KAction( i18n("Insert Cell(s)..."), "insertcell", 0, this, SLOT( slotInsert() ), actionCollection(), "insertCell" ); m_insertCell->setToolTip(i18n("Insert a blank cell into the spreadsheet.")); } void KSpreadView::initializeCellPropertyActions() { m_addModifyComment = new KAction( i18n("&Add/Modify Comment..."),"comment", 0, this, SLOT( addModifyComment() ), actionCollection(), "addmodifycomment" ); m_addModifyComment->setToolTip(i18n("Edit a comment for this cell.")); m_removeComment = new KAction( i18n("&Remove Comment"),"removecomment", 0, this, SLOT( removeComment() ), actionCollection(), "removecomment" ); m_removeComment->setToolTip(i18n("Remove this cell's comment.")); m_conditional = new KAction( i18n("Conditional Cell Attributes..."), 0, this, SLOT( conditional() ), actionCollection(), "conditional" ); m_conditional->setToolTip(i18n("Set cell format based on certain conditions.")); m_validity = new KAction( i18n("Validity..."), 0, this, SLOT( validity() ), actionCollection(), "validity" ); m_validity->setToolTip(i18n("Set tests to confirm cell data is valid.")); m_clearComment = new KAction( i18n("Comment"), 0, this, SLOT( clearCommentSelection() ), actionCollection(), "clearcomment" ); m_clearComment->setToolTip(i18n("Remove this cell's comment.")); m_clearValidity = new KAction( i18n("Validity"), 0, this, SLOT( clearValiditySelection() ), actionCollection(), "clearvalidity" ); m_clearValidity->setToolTip(i18n("Remove the validity tests on this cell.")); m_clearConditional = new KAction( i18n("Conditional Cell Attributes"), 0, this, SLOT( clearConditionalSelection() ), actionCollection(), "clearconditional" ); m_clearConditional->setToolTip(i18n("Remove the conditional cell formatting.")); m_increaseIndent = new KAction( i18n("Increase Indent"), "format_increaseindent",0, this, SLOT( increaseIndent() ), actionCollection(), "increaseindent" ); m_increaseIndent->setToolTip(i18n("Increase the indentation.")); m_decreaseIndent = new KAction( i18n("Decrease Indent"), "format_decreaseindent" ,0, this, SLOT( decreaseIndent() ), actionCollection(), "decreaseindent"); m_decreaseIndent->setToolTip(i18n("Decrease the indentation.")); m_multiRow = new KToggleAction( i18n("Multi Row"), "multirow", 0, actionCollection(), "multiRow" ); connect( m_multiRow, SIGNAL( toggled( bool ) ), this, SLOT( multiRow( bool ) ) ); m_multiRow->setToolTip(i18n("Make the cell text wrap onto multiple lines.")); m_cellLayout = new KAction( i18n("Cell Format..."),"cell_layout", CTRL + ALT + Key_F, this, SLOT( layoutDlg() ), actionCollection(), "cellLayout" ); m_cellLayout->setToolTip(i18n("Set the cell formatting.")); m_default = new KAction( i18n("Default"), 0, this, SLOT( defaultSelection() ), actionCollection(), "default" ); m_default->setToolTip(i18n("Resets to the default format.")); m_bgColor = new TKSelectColorAction( i18n("Background color"), TKSelectColorAction::FillColor, actionCollection(), "backgroundColor", true ); connect(m_bgColor,SIGNAL(activated()),SLOT(changeBackgroundColor())); m_bgColor->setDefaultColor(QColor()); m_bgColor->setToolTip(i18n("Set the background color.")); } void KSpreadView::initializeTextFormatActions() { /*******************************/ m_percent = new KToggleAction( i18n("Percent Format"), "percent", 0, actionCollection(), "percent"); connect( m_percent, SIGNAL( toggled( bool ) ), this, SLOT( percent( bool ) ) ); m_percent->setToolTip(i18n("Set the cell formatting to look like a percentage.")); /*******************************/ m_precplus = new KAction( i18n("Increase Precision"), "prec_plus", 0, this, SLOT( precisionPlus() ), actionCollection(), "precplus"); m_precplus->setToolTip(i18n("Increase the decimal precision shown onscreen.")); /*******************************/ m_precminus = new KAction( i18n("Decrease Precision"), "prec_minus", 0, this, SLOT( precisionMinus() ), actionCollection(), "precminus"); m_precminus->setToolTip(i18n("Decrease the decimal precision shown onscreen.")); /*******************************/ m_money = new KToggleAction( i18n("Money Format"), "money", 0, actionCollection(), "money"); connect( m_money, SIGNAL( toggled( bool ) ), this, SLOT( moneyFormat( bool ) ) ); m_money->setToolTip(i18n("Set the cell formatting to look like your local currency.")); /*******************************/ m_upper = new KAction( i18n("Upper Case"), "upper", 0, this, SLOT( upper() ), actionCollection(), "upper" ); m_upper->setToolTip(i18n("Convert all letters to upper case.")); /*******************************/ m_lower = new KAction( i18n("Lower Case"), "lower", 0, this, SLOT( lower() ), actionCollection(), "lower" ); m_lower->setToolTip(i18n("Convert all letters to lower case.")); /*******************************/ m_firstLetterUpper = new KAction( i18n("Convert First Letter to Upper Case"), "first_letter_upper" ,0, this, SLOT( firstLetterUpper() ), actionCollection(), "firstletterupper" ); m_firstLetterUpper->setToolTip(i18n("Capitalize the first letter.")); } void KSpreadView::initializeTextLayoutActions() { /*******************************/ m_alignLeft = new KToggleAction( i18n("Align Left"), "text_left", 0, actionCollection(), "left"); connect( m_alignLeft, SIGNAL( toggled( bool ) ), this, SLOT( alignLeft( bool ) ) ); m_alignLeft->setExclusiveGroup( "Align" ); m_alignLeft->setToolTip(i18n("Left justify the cell contents.")); /*******************************/ m_alignCenter = new KToggleAction( i18n("Align Center"), "text_center", 0, actionCollection(), "center"); connect( m_alignCenter, SIGNAL( toggled( bool ) ), this, SLOT( alignCenter( bool ) ) ); m_alignCenter->setExclusiveGroup( "Align" ); m_alignCenter->setToolTip(i18n("Center the cell contents.")); /*******************************/ m_alignRight = new KToggleAction( i18n("Align Right"), "text_right", 0, actionCollection(), "right"); connect( m_alignRight, SIGNAL( toggled( bool ) ), this, SLOT( alignRight( bool ) ) ); m_alignRight->setExclusiveGroup( "Align" ); m_alignRight->setToolTip(i18n("Right justify the cell contents.")); /*******************************/ m_alignTop = new KToggleAction( i18n("Align Top"), "text_top", 0, actionCollection(), "top"); connect( m_alignTop, SIGNAL( toggled( bool ) ), this, SLOT( alignTop( bool ) ) ); m_alignTop->setExclusiveGroup( "Pos" ); m_alignTop->setToolTip(i18n("Align cell contents along the top of the cell.")); /*******************************/ m_alignMiddle = new KToggleAction( i18n("Align Middle"), "middle", 0, actionCollection(), "middle"); connect( m_alignMiddle, SIGNAL( toggled( bool ) ), this, SLOT( alignMiddle( bool ) ) ); m_alignMiddle->setExclusiveGroup( "Pos" ); m_alignMiddle->setToolTip(i18n("Align cell contents centered in the cell.")); /*******************************/ m_alignBottom = new KToggleAction( i18n("Align Bottom"), "text_bottom", 0, actionCollection(), "bottom"); connect( m_alignBottom, SIGNAL( toggled( bool ) ), this, SLOT( alignBottom( bool ) ) ); m_alignBottom->setExclusiveGroup( "Pos" ); m_alignBottom->setToolTip(i18n("Align cell contents along the bottom of the cell.")); /*******************************/ m_verticalText = new KToggleAction( i18n("Vertical Text"),"vertical_text" , 0 ,actionCollection(), "verticaltext" ); connect( m_verticalText, SIGNAL( toggled( bool ) ), this, SLOT( verticalText( bool ) ) ); m_verticalText->setToolTip(i18n("Print cell contents vertically.")); /*******************************/ m_changeAngle = new KAction( i18n("Change Angle..."), 0, this, SLOT( changeAngle() ), actionCollection(), "changeangle" ); m_changeAngle->setToolTip(i18n("Change the angle that cell contents are printed.")); } void KSpreadView::initializeTextPropertyActions() { /*******************************/ m_bold = new KToggleAction( i18n("Bold"), "text_bold", CTRL + Key_B, actionCollection(), "bold"); connect( m_bold, SIGNAL( toggled( bool ) ), this, SLOT( bold( bool ) ) ); /*******************************/ m_italic = new KToggleAction( i18n("Italic"), "text_italic", CTRL + Key_I, actionCollection(), "italic"); connect( m_italic, SIGNAL( toggled( bool ) ), this, SLOT( italic( bool ) ) ); /*******************************/ m_underline = new KToggleAction( i18n("Underline"), "text_under", CTRL + Key_U, actionCollection(), "underline"); connect( m_underline, SIGNAL( toggled( bool ) ), this, SLOT( underline( bool ) ) ); /*******************************/ m_strikeOut = new KToggleAction( i18n("Strike Out"), "text_strike", 0, actionCollection(), "strikeout"); connect( m_strikeOut, SIGNAL( toggled( bool ) ), this, SLOT( strikeOut( bool ) ) ); /*******************************/ m_selectFont = new KFontAction( i18n("Select Font"), 0, actionCollection(), "selectFont" ); connect( m_selectFont, SIGNAL( activated( const QString& ) ), this, SLOT( fontSelected( const QString& ) ) ); /*******************************/ m_selectFontSize = new KFontSizeAction( i18n("Select Font Size"), 0, actionCollection(), "selectFontSize" ); connect( m_selectFontSize, SIGNAL( fontSizeChanged( int ) ), this, SLOT( fontSizeSelected( int ) ) ); /*******************************/ m_fontSizeUp = new KAction( i18n("Increase Font Size"), "fontsizeup", 0, this, SLOT( increaseFontSize() ), actionCollection(), "increaseFontSize" ); /*******************************/ m_fontSizeDown = new KAction( i18n("Decrease Font Size"), "fontsizedown", 0, this, SLOT( decreaseFontSize() ), actionCollection(), "decreaseFontSize" ); /*******************************/ m_textColor = new TKSelectColorAction( i18n("Text Color"), TKSelectColorAction::TextColor, actionCollection(), "textColor",true ); connect( m_textColor, SIGNAL(activated()), SLOT(changeTextColor()) ); m_textColor->setDefaultColor(QColor()); /*******************************/ } void KSpreadView::initializeTableActions() { m_insertTable = new KAction( i18n("Insert Table"),"inserttable", 0, this, SLOT( insertTable() ), actionCollection(), "insertTable" ); m_insertTable->setToolTip(i18n("Insert a new spreadsheet.")); m_removeTable = new KAction( i18n("Remove Table"), "delete_table",0,this, SLOT( removeTable() ), actionCollection(), "removeTable" ); m_removeTable->setToolTip(i18n("Remove the spreadsheet.")); m_renameTable=new KAction( i18n("Rename Table..."),0,this, SLOT( slotRename() ), actionCollection(), "renameTable" ); m_renameTable->setToolTip(i18n("Rename the spreadsheet.")); m_nextTable = new KAction( i18n("Next Table"), CTRL + Key_PageDown, this, SLOT( nextTable() ), actionCollection(), "nextTable"); m_nextTable->setToolTip(i18n("Move to the next spreadsheet.")); m_prevTable = new KAction( i18n("Previous Table"), CTRL + Key_PageUp, this, SLOT( previousTable() ), actionCollection(), "previousTable"); m_prevTable->setToolTip(i18n("Move to the previous spreadsheet.")); m_firstTable = new KAction( i18n("First Table"), 0, this, SLOT( firstTable() ), actionCollection(), "firstTable"); m_firstTable->setToolTip(i18n("Move to the first spreadsheet.")); m_lastTable = new KAction( i18n("Last Table"), 0, this, SLOT( lastTable() ), actionCollection(), "lastTable"); m_lastTable->setToolTip(i18n("Move to the last spreadsheet.")); m_showTable = new KAction(i18n("Show Table"),0 ,this,SLOT( showTable()), actionCollection(), "showTable" ); m_showTable->setToolTip(i18n("Show a hidden spreadsheet.")); m_hideTable = new KAction(i18n("Hide Table"),0 ,this,SLOT( hideTable()), actionCollection(), "hideTable" ); m_hideTable->setToolTip(i18n("Hide the spreadsheet.")); m_tableFormat = new KAction( i18n("Table Style..."), 0, this, SLOT( tableFormat() ), actionCollection(), "tableFormat" ); m_tableFormat->setToolTip(i18n("Set the spreadsheet formatting.")); } void KSpreadView::initializeSpellChecking() { m_spellChecking = KStdAction::spelling( this, SLOT( extraSpelling() ), actionCollection(), "spelling" ); m_spellChecking->setToolTip(i18n("Check the spelling.")); } void KSpreadView::initializeRowColumnActions() { m_adjust = new KAction( i18n("Adjust Row and Column"), 0, this, SLOT( adjust() ), actionCollection(), "adjust" ); m_adjust->setToolTip(i18n("Adjusts row/column size so that the contents will fit.")); m_resizeRow = new KAction( i18n("Resize Row..."), "resizerow", 0, this, SLOT( resizeRow() ), actionCollection(), "resizeRow" ); m_resizeRow->setToolTip(i18n("Change the height of a row.")); m_resizeColumn = new KAction( i18n("Resize Column..."), "resizecol", 0, this, SLOT( resizeColumn() ), actionCollection(), "resizeCol" ); m_resizeColumn->setToolTip(i18n("Change the width of a column.")); m_equalizeRow = new KAction( i18n("Equalize Row"), "adjustrow", 0, this, SLOT( equalizeRow() ), actionCollection(), "equalizeRow" ); m_equalizeRow->setToolTip(i18n("Resizes selected rows to be the same size.")); m_equalizeColumn = new KAction( i18n("Equalize Column"), "adjustcol", 0, this, SLOT( equalizeColumn() ), actionCollection(), "equalizeCol" ); m_equalizeColumn->setToolTip(i18n("Resizes selected columns to be the same size.")); m_deleteColumn = new KAction( i18n("Delete Column(s)"), "delete_table_col", 0, this, SLOT( deleteColumn() ), actionCollection(), "deleteColumn" ); m_deleteColumn->setToolTip(i18n("Removes a column from the spreadsheet.")); m_deleteRow = new KAction( i18n("Delete Row(s)"), "delete_table_row", 0, this, SLOT( deleteRow() ), actionCollection(), "deleteRow" ); m_deleteRow->setToolTip(i18n("Removes a row from the spreadsheet.")); m_insertColumn = new KAction( i18n("Insert Column(s)"), "insert_table_col" , 0, this, SLOT( insertColumn() ), actionCollection(), "insertColumn" ); m_insertColumn->setToolTip(i18n("Inserts a new column into the spreadsheet.")); m_insertRow = new KAction( i18n("Insert Row(s)"), "insert_table_row", 0, this, SLOT( insertRow() ), actionCollection(), "insertRow" ); m_insertRow->setToolTip(i18n("Inserts a new row into the spreadsheet.")); m_hideRow = new KAction( i18n("Hide Row(s)"), "hide_table_row", 0, this, SLOT( hideRow() ), actionCollection(), "hideRow" ); m_hideRow->setToolTip(i18n("Hide a row from view.")); m_showRow = new KAction( i18n("Show Row(s)"), "show_table_row", 0, this, SLOT( showRow() ), actionCollection(), "showRow" ); m_showRow->setToolTip(i18n("Show hidden rows.")); m_showSelRows = new KAction( i18n("Show Row(s)"), "show_table_row", 0, this, SLOT( showSelRows() ), actionCollection(), "showSelRows" ); m_showSelRows->setEnabled(false); m_showSelRows->setToolTip(i18n("Show hidden rows in the selection.")); m_hideColumn = new KAction( i18n("Hide Column(s)"), "hide_table_column", 0, this, SLOT( hideColumn() ), actionCollection(), "hideColumn" ); m_hideColumn->setToolTip(i18n("Hide the column from view.")); m_showColumn = new KAction( i18n("Show Column(s)"), "show_table_column", 0, this, SLOT( showColumn() ), actionCollection(), "showColumn" ); m_showColumn->setToolTip(i18n("Show hidden columns.")); m_showSelColumns = new KAction( i18n("Show Column(s)"), "show_table_column", 0, this, SLOT( showSelColumns() ), actionCollection(), "showSelColumns" ); m_showSelColumns->setToolTip(i18n("Show hidden columns in the selection.")); m_showSelColumns->setEnabled(false); } void KSpreadView::initializeBorderActions() { m_borderLeft = new KAction( i18n("Border Left"), "border_left", 0, this, SLOT( borderLeft() ), actionCollection(), "borderLeft" ); m_borderLeft->setToolTip(i18n("Set a left border to the selected area.")); m_borderRight = new KAction( i18n("Border Right"), "border_right", 0, this, SLOT( borderRight() ), actionCollection(), "borderRight" ); m_borderRight->setToolTip(i18n("Set a right border to the selected area.")); m_borderTop = new KAction( i18n("Border Top"), "border_top", 0, this, SLOT( borderTop() ), actionCollection(), "borderTop" ); m_borderTop->setToolTip(i18n("Set a top border to the selected area.")); m_borderBottom = new KAction( i18n("Border Bottom"), "border_bottom", 0, this, SLOT( borderBottom() ), actionCollection(), "borderBottom" ); m_borderBottom->setToolTip(i18n("Set a bottom border to the selected area.")); m_borderAll = new KAction( i18n("All Borders"), "border_all", 0, this, SLOT( borderAll() ), actionCollection(), "borderAll" ); m_borderAll->setToolTip(i18n("Set a border around all cells in the selected area.")); m_borderRemove = new KAction( i18n("Remove Borders"), "border_remove", 0, this, SLOT( borderRemove() ), actionCollection(), "borderRemove" ); m_borderRemove->setToolTip(i18n("Remove all borders in the selected area.")); m_borderOutline = new KAction( i18n("Border Outline"), ("border_outline"), 0, this, SLOT( borderOutline() ), actionCollection(), "borderOutline" ); m_borderOutline->setToolTip(i18n("Set a border to the outline of the selected area.")); m_borderColor = new TKSelectColorAction( i18n("Border Color"), TKSelectColorAction::LineColor, actionCollection(), "borderColor" ); connect(m_borderColor,SIGNAL(activated()),SLOT(changeBorderColor())); m_borderColor->setToolTip(i18n("Select a new border color.")); } KSpreadView::~KSpreadView() { deleteEditor( true ); if ( !m_transformToolBox.isNull() ) delete (&*m_transformToolBox); /*if(m_sbCalcLabel) { disconnect(m_sbCalcLabel,SIGNAL(pressed( int )),this,SLOT(statusBarClicked(int))); }*/ if(m_spell.kspell) { delete m_spell.kspell; } m_pCanvas->endChoose(); m_pTable = 0; // set the active table to 0L so that when during destruction // of embedded child documents possible repaints in KSpreadTable are not // performed. The repains can happen if you delete an embedded document, // which leads to an regionInvalidated() signal emission in KoView, which calls // repaint, etc.etc. :-) (Simon) delete m_pPopupColumn; delete m_pPopupRow; delete m_pPopupMenu; delete m_popupChild; delete m_popupListChoose; delete m_sbCalcLabel; delete m_dcop; } void KSpreadView::initConfig() { KConfig *config = KSpreadFactory::global()->config(); if( config->hasGroup("Parameters" )) { config->setGroup( "Parameters" ); m_pDoc->setShowHorizontalScrollBar(config->readBoolEntry("Horiz ScrollBar",true)); m_pDoc->setShowVerticalScrollBar(config->readBoolEntry("Vert ScrollBar",true)); m_pDoc->setShowColHeader(config->readBoolEntry("Column Header",true)); m_pDoc->setShowRowHeader(config->readBoolEntry("Row Header",true)); m_pDoc->setCompletionMode((KGlobalSettings::Completion)config->readNumEntry("Completion Mode",(int)(KGlobalSettings::CompletionAuto))); m_pDoc->setMoveToValue((KSpread::MoveTo)config->readNumEntry("Move",(int)(KSpread::Bottom))); m_pDoc->setIndentValue(config->readNumEntry( "Indent",10 ) ); m_pDoc->setTypeOfCalc((MethodOfCalc)config->readNumEntry("Method of Calc",(int)(SumOfNumber))); m_pDoc->setShowTabBar(config->readBoolEntry("Tabbar",true)); m_pDoc->setShowMessageError(config->readBoolEntry( "Msg error" ,false) ); m_pDoc->setShowCommentIndicator(config->readBoolEntry("Comment Indicator",true)); m_pDoc->setShowFormulaBar(config->readBoolEntry("Formula bar",true)); m_pDoc->setShowStatusBar(config->readBoolEntry("Status bar",true)); changeNbOfRecentFiles(config->readNumEntry("NbRecentFile",10)); //autosave value is stored as a minute. //but default value is stored as seconde. m_pDoc->setAutoSave(config->readNumEntry("AutoSave",KoDocument::defaultAutoSave()/60)*60); } if( config->hasGroup("KSpread Color" ) ) { config->setGroup( "KSpread Color" ); QColor _col(Qt::lightGray); _col = config->readColorEntry("GridColor", &_col); m_pDoc->changeDefaultGridPenColor(_col); QColor _pbCol(Qt::red); _pbCol = config->readColorEntry("PageBorderColor", &_pbCol); m_pDoc->changePageBorderColor(_pbCol); } // Do we need a Page Layout in the congiguration file? Isn't this already in the template? Philipp /* if( config->hasGroup("KSpread Page Layout" ) ) { config->setGroup( "KSpread Page Layout" ); if( m_pTable->isEmpty()) { m_pTable->setPaperFormat((KoFormat)config->readNumEntry("Default size page",1)); m_pTable->setPaperOrientation((KoOrientation)config->readNumEntry("Default orientation page",0)); m_pTable->setPaperUnit((KoUnit::Unit)config->readNumEntry("Default unit page",0)); } } */ initCalcMenu(); resultOfCalc(); } void KSpreadView::changeNbOfRecentFiles(int _nb) { if(shell()) shell()->setMaxRecentItems( _nb ); } void KSpreadView::initCalcMenu() { switch( doc()->getTypeOfCalc()) { case SumOfNumber: m_menuCalcSum->setChecked(true); break; case Min: m_menuCalcMin->setChecked(true); break; case Max: m_menuCalcMax->setChecked(true); break; case Average: m_menuCalcAverage->setChecked(true); break; case Count: m_menuCalcCount->setChecked(true); break; case NoneCalc: m_menuCalcNone->setChecked(true); break; default : m_menuCalcSum->setChecked(true); break; } } void KSpreadView::RecalcWorkBook(){ KSpreadTable *tbl; for ( tbl = m_pDoc->map()->firstTable(); tbl != 0L; tbl = m_pDoc->map()->nextTable() ) { bool b = tbl->getAutoCalc(); tbl->setAutoCalc(true); tbl->recalc(); tbl->setAutoCalc(b); } // slotUpdateView( activeTable() ); } void KSpreadView::slotRefreshLocale() { kdDebug(36001)<<"KSpreadView::slotRefreshLocale()***************\n"; KSpreadTable *tbl; for ( tbl = m_pDoc->map()->firstTable(); tbl != 0L; tbl = m_pDoc->map()->nextTable() ){ tbl->updateLocale(); } } void KSpreadView::RecalcWorkSheet() { if (m_pTable != 0) { bool b = m_pTable->getAutoCalc(); m_pTable->setAutoCalc(true); m_pTable->recalc(); m_pTable->setAutoCalc(b); } //slotUpdateView( activeTable() ); } void KSpreadView::extraSpelling() { if (m_spell.kspell) return; // Already in progress if (m_pTable == 0L) return; // m_spell.macroCmdSpellCheck = 0L; m_spell.firstSpellTable = m_pTable; m_spell.currentSpellTable = m_spell.firstSpellTable; QRect selection = m_pTable->selectionRect(); // if nothing is selected, check every cell if (selection.left() == 0) { m_spell.spellStartCellX = 0; m_spell.spellStartCellY = 0; m_spell.spellEndCellX = 0; m_spell.spellEndCellY = 0; m_spell.spellCheckSelection = false; m_spell.currentCell = m_pTable->firstCell(); } else { m_spell.spellStartCellX = selection.left(); m_spell.spellStartCellY = selection.top(); m_spell.spellEndCellX = selection.right(); m_spell.spellEndCellY = selection.bottom(); m_spell.spellCheckSelection = true; m_spell.currentCell = 0L; // "-1" because X gets increased every time we go into spellCheckReady() m_spell.spellCurrCellX = m_spell.spellStartCellX - 1; m_spell.spellCurrCellY = m_spell.spellStartCellY; } startKSpell(); } void KSpreadView::startKSpell() { m_spell.kspell = new KSpreadSpell( this, i18n( "Spell Checking" ), this, SLOT( spellCheckerReady() ), m_pDoc->getKSpellConfig() ); m_spell.ignoreWord = m_ignoreWord; m_spell.kspell->ksConfig().setIgnoreList(m_spell.ignoreWord); m_spell.kspell->setIgnoreUpperWords(m_pDoc->dontCheckUpperWord()); m_spell.kspell->setIgnoreTitleCase(m_pDoc->dontCheckTitleCase()); QObject::connect( m_spell.kspell, SIGNAL( death() ), this, SLOT( spellCheckerFinished() ) ); QObject::connect( m_spell.kspell, SIGNAL( misspelling( const QString &, const QStringList &, unsigned int) ), this, SLOT( spellCheckerMisspelling( const QString &, const QStringList &, unsigned int) ) ); QObject::connect( m_spell.kspell, SIGNAL( corrected( const QString &, const QString &, unsigned int) ), this, SLOT( spellCheckerCorrected( const QString &, const QString &, unsigned int ) ) ); QObject::connect( m_spell.kspell, SIGNAL( done( const QString & ) ), this, SLOT( spellCheckerDone( const QString & ) ) ); } void KSpreadView::spellCheckerReady() { if (m_pCanvas) m_pCanvas->setCursor( WaitCursor ); // go on to the next cell if (!m_spell.spellCheckSelection) { // if nothing is selected we have to check every cell // we use a different way to make it faster while ( m_spell.currentCell ) { // check text only if ( !m_spell.currentCell->isDefault() && m_spell.currentCell->isString() ) { m_spell.kspell->check( m_spell.currentCell->text(), true ); return; } m_spell.currentCell = m_spell.currentCell->nextCell(); } if (spellSwitchToOtherTable()) spellCheckerReady(); else spellCleanup(); return; } // if something is selected: ++m_spell.spellCurrCellX; if (m_spell.spellCurrCellX > m_spell.spellEndCellX) { m_spell.spellCurrCellX = m_spell.spellStartCellX; ++m_spell.spellCurrCellY; } unsigned int y; unsigned int x; for ( y = m_spell.spellCurrCellY; y <= m_spell.spellEndCellY; ++y ) { for ( x = m_spell.spellCurrCellX; x <= m_spell.spellEndCellX; ++x ) { KSpreadCell * cell = m_spell.currentSpellTable->cellAt( x, y ); // check text only if (cell->isDefault() || !cell->isString()) continue; m_spell.spellCurrCellX = x; m_spell.spellCurrCellY = y; m_spell.kspell->check( cell->text(), true ); return; } m_spell.spellCurrCellX = m_spell.spellStartCellX; } // if the user selected something to be checked we are done // otherwise ask for checking the next table if any if (m_spell.spellCheckSelection) { // Done spellCleanup(); } else { if (spellSwitchToOtherTable()) spellCheckerReady(); else spellCleanup(); } } void KSpreadView::spellCleanup() { if (m_pCanvas) m_pCanvas->setCursor( ArrowCursor ); m_spell.kspell->cleanUp(); delete m_spell.kspell; m_spell.kspell = 0L; m_spell.firstSpellTable = 0L; m_spell.currentSpellTable = 0L; m_spell.currentCell = 0L; KMessageBox::information( this, i18n( "Spell checking is complete." ) ); // not supported yet // if(m_spell.macroCmdSpellCheck) // m_pDoc->addCommand(m_spell.macroCmdSpellCheck); } bool KSpreadView::spellSwitchToOtherTable() { // there is no other table if(m_pDoc->map()->count()==1) return false; // for optimization QPtrList tableList = m_pDoc->map()->tableList(); unsigned int curIndex = tableList.findRef(m_spell.currentSpellTable); ++curIndex; // last table? then start at the beginning if ( curIndex >= tableList.count() ) m_spell.currentSpellTable = tableList.first(); else m_spell.currentSpellTable = tableList.at(curIndex); // if the current table is the first one again, we are done. if( m_spell.currentSpellTable == m_spell.firstSpellTable ) { setActiveTable( m_spell.firstSpellTable ); return false; } if (m_spell.spellCheckSelection) { m_spell.spellEndCellX = m_spell.currentSpellTable->maxColumn(); m_spell.spellEndCellY = m_spell.currentSpellTable->maxRow(); m_spell.spellCurrCellX = m_spell.spellStartCellX - 1; m_spell.spellCurrCellY = m_spell.spellStartCellY; } else { m_spell.currentCell = m_spell.currentSpellTable->firstCell(); } if ( KMessageBox::questionYesNo( this, i18n( "Do you want to check the spelling in the next table?") ) != KMessageBox::Yes ) return false; setActiveTable(m_spell.currentSpellTable); return true; } void KSpreadView::spellCheckerMisspelling( const QString &, const QStringList &, unsigned int ) { // scroll to the cell if (!m_spell.spellCheckSelection) { m_spell.spellCurrCellX = m_spell.currentCell->column(); m_spell.spellCurrCellY = m_spell.currentCell->row(); } canvasWidget()->gotoLocation( m_spell.spellCurrCellX, m_spell.spellCurrCellY, activeTable() ); } void KSpreadView::spellCheckerCorrected( const QString & old, const QString & corr, unsigned int pos ) { KSpreadCell * cell; if (m_spell.spellCheckSelection) { cell = m_spell.currentSpellTable->cellAt( m_spell.spellCurrCellX, m_spell.spellCurrCellY ); } else { cell = m_spell.currentCell; m_spell.spellCurrCellX = cell->column(); m_spell.spellCurrCellY = cell->row(); } Q_ASSERT( cell ); if ( !cell ) return; QString content( cell->text() ); KSpreadUndoSetText* undo = new KSpreadUndoSetText( m_pDoc, m_pTable, content, m_spell.spellCurrCellX, m_spell.spellCurrCellY, cell->formatType()); m_pDoc->undoBuffer()->appendUndo( undo ); content.replace( pos, old.length(), corr ); cell->setCellText( content ); m_pEditWidget->setText( content ); // TODO ?: // if(!m_spell.macroCmdSpellCheck) // m_spell.macroCmdSpellCheck=new KMacroCommand(i18n("Correct misspelled word")); // m_spell.macroCmdSpellCheck->addCommand(textobj->textObject()->replaceSelectionCommand(&cursor, corr, KoTextObject::HighlightSelection, QString::null )); } void KSpreadView::spellCheckerDone( const QString & ) { int result = m_spell.kspell->dlgResult(); // store ignore word m_ignoreWord += m_spell.kspell->ksConfig().ignoreList(); m_spell.kspell->cleanUp(); delete m_spell.kspell; m_spell.kspell = 0L; if ( result != KS_CANCEL && result != KS_STOP ) { if (m_spell.spellCheckSelection) { if ( (m_spell.spellCurrCellY <= m_spell.spellEndCellY) && (m_spell.spellCurrCellX <= m_spell.spellEndCellX) ) { startKSpell(); return; } } else { if ( m_spell.currentCell ) { m_spell.currentCell = m_spell.currentCell->nextCell(); startKSpell(); return; } } } // Not implemented yet // if(m_spell.macroCmdSpellCheck) // m_pDoc->addCommand(m_spell.macroCmdSpellCheck); } void KSpreadView::spellCheckerFinished() { if (m_pCanvas) m_pCanvas->setCursor( ArrowCursor ); KSpell::spellStatus status = m_spell.kspell->status(); m_spell.kspell->cleanUp(); delete m_spell.kspell; m_spell.kspell = 0L; bool kspellNotConfigured=false; if (status == KSpell::Error) { KMessageBox::sorry(this, i18n("ISpell could not be started.\n" "Please make sure you have ISpell properly configured and in your PATH.")); kspellNotConfigured=true; } else if (status == KSpell::Crashed) { KMessageBox::sorry(this, i18n("ISpell seems to have crashed.")); } // Not implemented yet // if(m_spell.macroCmdSpellCheck) // m_pDoc->addCommand(m_spell.macroCmdSpellCheck); if(kspellNotConfigured) { KSpreadpreference configDlg( this, 0 ); configDlg.openPage( KSpreadpreference::KS_SPELLING); configDlg.exec(); } } void KSpreadView::initialPosition() { // Set the initial position for the marker as store in the XML file, // (1,1) otherwise int col = m_pDoc->map()->initialMarkerColumn(); if ( col <= 0 ) col = 1; int row = m_pDoc->map()->initialMarkerRow(); if ( row <= 0 ) row = 1; m_pCanvas->gotoLocation( col, row ); //init toggle button updateBorderButton(); m_tableFormat->setEnabled(false); m_mergeCell->setEnabled(false); m_insertChartFrame->setEnabled(false); // I don't think we should recalculate everything after loading, this takes much to much time // and shouldn't be necessary at all - Philipp // // /*recalc all dependent after loading*/ // KSpreadTable *tbl; // for ( tbl = m_pDoc->map()->firstTable(); tbl != 0L; tbl = m_pDoc->map()->nextTable() ) // { // if( tbl->getAutoCalc() ) // tbl->recalc(); // tbl->refreshMergedCell(); // } slotUpdateView( activeTable() ); m_bLoading =true; if ( koDocument()->isReadWrite() ) initConfig(); } void KSpreadView::updateEditWidgetOnPress() { int column = m_pCanvas->markerColumn(); int row = m_pCanvas->markerRow(); KSpreadCell* cell = m_pTable->cellAt( column, row ); if ( !cell ) { editWidget()->setText( "" ); return; } if ( cell->content() == KSpreadCell::VisualFormula ) editWidget()->setText( "" ); else editWidget()->setText( cell->text() ); } void KSpreadView::updateEditWidget() { bool active=activeTable()->getShowFormula(); m_alignLeft->setEnabled(!active); m_alignCenter->setEnabled(!active); m_alignRight->setEnabled(!active); m_toolbarLock = TRUE; int column = m_pCanvas->markerColumn(); int row = m_pCanvas->markerRow(); KSpreadCell* cell = m_pTable->cellAt( column, row ); if ( !cell ) { editWidget()->setText( "" ); return; } if ( cell->content() == KSpreadCell::VisualFormula ) { editWidget()->setText( "" ); } else { editWidget()->setText( cell->text() ); } QColor color=cell->textColor( column, row ); if(!color.isValid()) color=QApplication::palette().active().text(); m_textColor->setCurrentColor( color ); color=cell->bgColor( column, row ); if(!color.isValid()) color=QApplication::palette().active().base(); m_bgColor->setCurrentColor( color ); m_selectFontSize->setFontSize( cell->textFontSize( column, row ) ); m_selectFont->setFont( cell->textFontFamily( column,row ) ); m_bold->setChecked( cell->textFontBold( column, row ) ); m_italic->setChecked( cell->textFontItalic( column, row) ); m_underline->setChecked( cell->textFontUnderline( column, row ) ); m_strikeOut->setChecked( cell->textFontStrike( column, row ) ); m_alignLeft->setChecked( cell->align( column, row ) == KSpreadLayout::Left ); m_alignCenter->setChecked( cell->align( column, row ) == KSpreadLayout::Center ); m_alignRight->setChecked( cell->align( column, row ) == KSpreadLayout::Right ); m_alignTop->setChecked( cell->alignY( column, row ) == KSpreadLayout::Top ); m_alignMiddle->setChecked( cell->alignY( column, row ) == KSpreadLayout::Middle ); m_alignBottom->setChecked( cell->alignY( column, row ) == KSpreadLayout::Bottom ); m_verticalText->setChecked( cell->verticalText( column,row ) ); m_multiRow->setChecked( cell->multiRow( column,row ) ); KSpreadCell::FormatType ft = cell->formatType(); m_percent->setChecked( ft == KSpreadCell::Percentage ); m_money->setChecked( ft == KSpreadCell::Money ); m_removeComment->setEnabled( !cell->comment(column,row).isEmpty() ); m_decreaseIndent->setEnabled(cell->getIndent(column,row)>0); m_toolbarLock = FALSE; if ( m_pCanvas->editor() ) { m_pCanvas->editor()->setEditorFont(cell->textFont(column, row), true); m_pCanvas->editor()->setFocus(); } } void KSpreadView::activateFormulaEditor() { } void KSpreadView::updateReadWrite( bool readwrite ) { #ifdef __GNUC_ #warning TODO #endif // m_pCancelButton->setEnabled( readwrite ); // m_pOkButton->setEnabled( readwrite ); m_pEditWidget->setEnabled( readwrite ); QValueList actions = actionCollection()->actions(); QValueList::ConstIterator aIt = actions.begin(); QValueList::ConstIterator aEnd = actions.end(); for (; aIt != aEnd; ++aIt ) (*aIt)->setEnabled( readwrite ); m_transform->setEnabled( false ); m_redo->setEnabled( false ); m_undo->setEnabled( false ); m_showTable->setEnabled( true ); m_hideTable->setEnabled( true ); m_gotoCell->setEnabled( true ); // m_newView->setEnabled( true ); //m_pDoc->KXMLGUIClient::action( "newView" )->setEnabled( true ); // obsolete (Werner) // m_oszi->setEnabled( true ); } void KSpreadView::tableFormat() { KSpreadFormatDlg dlg( this ); dlg.exec(); } void KSpreadView::autoSum() { // ######## Torben: Make sure that this can not be called // when canvas has a running editor if ( m_pCanvas->editor() ) return; m_pCanvas->createEditor( KSpreadCanvas::CellEditor ); m_pCanvas->editor()->setText( "=SUM()" ); m_pCanvas->editor()->setCursorPosition( 5 ); // Try to find numbers above if ( m_pCanvas->markerRow() > 1 ) { KSpreadCell* cell = 0; int r = m_pCanvas->markerRow(); do { cell = activeTable()->cellAt( m_pCanvas->markerColumn(), --r ); } while ( cell && cell->isNumeric() ); if ( r + 1 < m_pCanvas->markerRow() ) { m_pTable->setChooseRect( QRect( m_pCanvas->markerColumn(), r + 1, 1, m_pCanvas->markerRow() - r - 1 ) ); return; } } // Try to find numbers left if ( m_pCanvas->markerColumn() > 1 ) { KSpreadCell* cell = 0; int c = m_pCanvas->markerColumn(); do { cell = activeTable()->cellAt( --c, m_pCanvas->markerRow() ); } while ( cell && cell->isNumeric() ); if ( c + 1 < m_pCanvas->markerColumn() ) { m_pTable->setChooseRect( QRect( c + 1, m_pCanvas->markerRow(), m_pCanvas->markerColumn() - c - 1, 1 ) ); return; } } } /* void KSpreadView::oszilloscope() { QDialog* dlg = new KSpreadOsziDlg( this ); dlg->show(); } */ void KSpreadView::changeTextColor() { if ( m_pTable != 0L ) { int col = m_pCanvas->markerColumn(); int row = m_pCanvas->markerRow(); m_pTable->setSelectionTextColor( QPoint( col, row ), m_textColor->color() ); } } void KSpreadView::changeBackgroundColor() { if ( m_pTable != 0L ) { m_pTable->setSelectionbgColor( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), m_bgColor->color() ); } } void KSpreadView::changeBorderColor() { if ( m_pTable != 0L ) { m_pTable->setSelectionBorderColor( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), m_borderColor->color() ); } } void KSpreadView::helpUsing() { kapp->invokeHelp( ); } QButton * KSpreadView::newIconButton( const char *_file, bool _kbutton, QWidget *_parent ) { if ( _parent == 0L ) _parent = this; QButton *pb; if ( !_kbutton ) pb = new QPushButton( _parent ); else pb = new QToolButton( _parent ); pb->setPixmap( QPixmap( KSBarIcon(_file) ) ); return pb; } void KSpreadView::enableUndo( bool _b ) { m_undo->setEnabled( _b ); m_undo->setText(i18n("Undo: %1").arg(m_pDoc->undoBuffer()->getUndoName())); } void KSpreadView::enableRedo( bool _b ) { m_redo->setEnabled( _b ); m_redo->setText(i18n("Redo: %1").arg(m_pDoc->undoBuffer()->getRedoName())); } void KSpreadView::undo() { m_pDoc->undo(); updateEditWidget(); resultOfCalc(); } void KSpreadView::redo() { m_pDoc->redo(); updateEditWidget(); resultOfCalc(); } void KSpreadView::deleteColumn() { if ( !m_pTable ) return; QRect r( activeTable()-> selectionRect() ); if( r.left()==0 || activeTable()->isRowSelected() ) m_pTable->removeColumn( m_pCanvas->markerColumn() ); else m_pTable->removeColumn( r.left(),(r.right()-r.left()) ); updateEditWidget(); m_pTable->setSelection(m_pTable->marker()); } void KSpreadView::deleteRow() { if ( !m_pTable ) return; QRect r( activeTable()-> selectionRect() ); if( r.left()==0 || activeTable()->isColumnSelected() ) m_pTable->removeRow( m_pCanvas->markerRow() ); else m_pTable->removeRow( r.top(),(r.bottom()-r.top()) ); updateEditWidget(); m_pTable->setSelection(m_pTable->marker()); } void KSpreadView::insertColumn() { if ( !m_pTable ) return; QRect r( activeTable()-> selectionRect() ); if( r.left()==0 || activeTable()->isRowSelected() ) m_pTable->insertColumn( m_pCanvas->markerColumn() ); else m_pTable->insertColumn( r.left(),(r.right()-r.left()) ); updateEditWidget(); } void KSpreadView::hideColumn() { if ( !m_pTable ) return; QRect r( activeTable()-> selectionRect() ); if( r.left()==0 || activeTable()->isRowSelected() ) m_pTable->hideColumn( m_pCanvas->markerColumn() ); else m_pTable->hideColumn( r.left(),(r.right()-r.left()) ); } void KSpreadView::showColumn() { if ( !m_pTable ) return; KSpreadShowColRow dlg( this,"showCol",KSpreadShowColRow::Column); dlg.exec(); } void KSpreadView::showSelColumns() { if ( !m_pTable ) return; int i; QRect rect = activeTable()->selectionRect(); ColumnLayout * col; QValueListhiddenCols; for ( i = rect.left(); i <= rect.right(); ++i ) { if (i == 2) // "B" { col = activeTable()->columnLayout( 1 ); if ( col->isHide() ) { hiddenCols.append( 1 ); } } col = m_pTable->columnLayout( i ); if ( col->isHide() ) { hiddenCols.append(i); } } if (hiddenCols.count() > 0) m_pTable->showColumn(0, -1, hiddenCols); } void KSpreadView::insertRow() { if ( !m_pTable ) return; QRect r( activeTable()-> selectionRect() ); if( r.left()==0 || activeTable()->isColumnSelected() ) m_pTable->insertRow( m_pCanvas->markerRow() ); else m_pTable->insertRow( r.top(),(r.bottom()-r.top()) ); updateEditWidget(); } void KSpreadView::hideRow() { if ( !m_pTable ) return; QRect r( activeTable()-> selectionRect() ); if( r.left()==0 || activeTable()->isColumnSelected() ) m_pTable->hideRow( m_pCanvas->markerRow() ); else m_pTable->hideRow( r.top(),(r.bottom()-r.top()) ); } void KSpreadView::showRow() { if ( !m_pTable ) return; KSpreadShowColRow dlg( this,"showRow",KSpreadShowColRow::Row); dlg.exec(); } void KSpreadView::showSelRows() { if ( !m_pTable ) return; int i; QRect rect = activeTable()->selectionRect(); RowLayout * row; QValueListhiddenRows; for ( i = rect.top(); i <= rect.bottom(); ++i ) { if (i == 2) { row = activeTable()->rowLayout( 1 ); if ( row->isHide() ) { hiddenRows.append(1); } } row = m_pTable->rowLayout( i ); if ( row->isHide() ) { hiddenRows.append(i); } } if (hiddenRows.count() > 0) m_pTable->showRow(0, -1, hiddenRows); } void KSpreadView::fontSelected( const QString &_font ) { if ( m_toolbarLock ) return; if ( m_pTable != 0L ) m_pTable->setSelectionFont( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), _font.latin1() ); // Dont leave the focus in the toolbars combo box ... if ( m_pCanvas->editor() ) { KSpreadCell * cell = m_pTable->cellAt( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); m_pCanvas->editor()->setEditorFont(cell->textFont(cell->column(), cell->row()), true); m_pCanvas->editor()->setFocus(); } else m_pCanvas->setFocus(); } void KSpreadView::decreaseFontSize() { if( !m_pTable ) return; m_pTable->setSelectionSize( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), -1 ); updateEditWidget(); } void KSpreadView::increaseFontSize() { if( !m_pTable ) return; m_pTable->setSelectionSize( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), 1 ); updateEditWidget(); } void KSpreadView::lower() { if( !m_pTable ) return; m_pTable->setSelectionUpperLower( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), -1 ); updateEditWidget(); } void KSpreadView::upper() { if( !m_pTable ) return; m_pTable->setSelectionUpperLower( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), 1 ); updateEditWidget(); } void KSpreadView::firstLetterUpper() { if( !m_pTable ) return; m_pTable->setSelectionfirstLetterUpper( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } void KSpreadView::verticalText(bool b) { if( !m_pTable ) return; m_pTable->setSelectionVerticalText( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ),b ); if( activeTable()->isRowSelected() == FALSE && activeTable()->isColumnSelected() == FALSE ) m_pCanvas->adjustArea(false); updateEditWidget(); } void KSpreadView::insertMathExpr() { if ( m_pTable == 0L ) return; KSpreadDlgFormula *dlg=new KSpreadDlgFormula( this, "Formula Editor" ); dlg->exec(); // #### Is the dialog deleted when it's closed ? (David) // Torben thinks that not. } void KSpreadView::formulaSelection( const QString &_math ) { if ( m_pTable == 0 ) return; if( _math == i18n("Others...") ) { insertMathExpr(); return; } KSpreadDlgFormula *dlg=new KSpreadDlgFormula( this, "Formula Editor",_math ); dlg->exec(); } void KSpreadView::fontSizeSelected( int _size ) { if ( m_toolbarLock ) return; if ( m_pTable != 0L ) m_pTable->setSelectionFont( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), 0L, _size ); // Dont leave the focus in the toolbars combo box ... if ( m_pCanvas->editor() ) { KSpreadCell * cell = m_pTable->cellAt( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); m_pCanvas->editor()->setEditorFont(cell->textFont(m_pCanvas->markerColumn(), m_pCanvas->markerRow()), true); m_pCanvas->editor()->setFocus(); } else m_pCanvas->setFocus(); } void KSpreadView::bold( bool b ) { if ( m_toolbarLock ) return; if ( m_pTable == 0 ) return; int col = m_pCanvas->markerColumn(); int row = m_pCanvas->markerRow(); m_pTable->setSelectionFont( QPoint( col, row ), 0L, -1, b ); if ( m_pCanvas->editor() ) { KSpreadCell * cell = m_pTable->cellAt( col, row ); m_pCanvas->editor()->setEditorFont(cell->textFont(col, row), true); } } void KSpreadView::underline( bool b ) { if ( m_toolbarLock ) return; if ( m_pTable == 0 ) return; int col = m_pCanvas->markerColumn(); int row = m_pCanvas->markerRow(); m_pTable->setSelectionFont( QPoint( col, row ), 0L, -1, -1, -1 ,b ); if ( m_pCanvas->editor() ) { KSpreadCell * cell = m_pTable->cellAt( col, row ); m_pCanvas->editor()->setEditorFont(cell->textFont(col, row), true); } } void KSpreadView::strikeOut( bool b ) { if ( m_toolbarLock ) return; if ( m_pTable == 0 ) return; int col = m_pCanvas->markerColumn(); int row = m_pCanvas->markerRow(); m_pTable->setSelectionFont( QPoint( col, row ), 0L, -1, -1, -1 ,-1,b ); if ( m_pCanvas->editor() ) { KSpreadCell * cell = m_pTable->cellAt( col, row ); m_pCanvas->editor()->setEditorFont(cell->textFont(col, row), true); } } void KSpreadView::italic( bool b ) { if ( m_toolbarLock ) return; if ( m_pTable == 0 ) return; int col = m_pCanvas->markerColumn(); int row = m_pCanvas->markerRow(); m_pTable->setSelectionFont( QPoint( col, row ), 0L, -1, -1, b ); if ( m_pCanvas->editor() ) { KSpreadCell * cell = m_pTable->cellAt( col, row ); m_pCanvas->editor()->setEditorFont(cell->textFont(col, row), true); } } void KSpreadView::sortInc() { QRect r( activeTable()-> selectionRect() ); if ( r.left() == 0 || r.top() == 0 || r.right() == 0 || r.bottom() == 0 ) { KMessageBox::error( this, i18n("You must select multiple cells.") ); return; } // Entire row(s) selected ? Or just one row ? if( activeTable()->isRowSelected() || r.top() == r.bottom() ) activeTable()->sortByRow( r.top(), KSpreadTable::Increase ); else activeTable()->sortByColumn( r.left(), KSpreadTable::Increase ); updateEditWidget(); } void KSpreadView::sortDec() { QRect r( activeTable()-> selectionRect() ); if ( r.left() == 0 || r.top() == 0 || r.right() == 0 || r.bottom() == 0 ) { KMessageBox::error( this, i18n("You must select multiple cells.") ); return; } // Entire row(s) selected ? Or just one row ? if( activeTable()->isRowSelected() || r.top() == r.bottom() ) activeTable()->sortByRow( r.top(), KSpreadTable::Decrease ); else activeTable()->sortByColumn( r.left(), KSpreadTable::Decrease ); updateEditWidget(); } void KSpreadView::reloadScripts() { // TODO } void KSpreadView::runLocalScript() { // TODO } void KSpreadView::editGlobalScripts() { if ( KSpreadView::m_pGlobalScriptsDialog == 0L ) KSpreadView::m_pGlobalScriptsDialog = new KSpreadScripts(); KSpreadView::m_pGlobalScriptsDialog->show(); KSpreadView::m_pGlobalScriptsDialog->raise(); } void KSpreadView::editLocalScripts() { // TODO /* if ( !m_pDoc->editPythonCode() ) { KMessageBox::error( i18n( "Could not start editor" ) ); return; } */ } void KSpreadView::borderBottom() { if ( m_pTable != 0L ) m_pTable->borderBottom( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ,m_borderColor->color()); } void KSpreadView::borderRight() { if ( m_pTable != 0L ) m_pTable->borderRight( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ,m_borderColor->color()); } void KSpreadView::borderLeft() { if ( m_pTable != 0L ) m_pTable->borderLeft( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ),m_borderColor->color() ); } void KSpreadView::borderTop() { if ( m_pTable != 0L ) m_pTable->borderTop( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ),m_borderColor->color() ); } void KSpreadView::borderOutline() { if ( m_pTable != 0L ) m_pTable->borderOutline( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ,m_borderColor->color()); } void KSpreadView::borderAll() { if ( m_pTable != 0L ) m_pTable->borderAll( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ),m_borderColor->color() ); } void KSpreadView::borderRemove() { if ( m_pTable != 0L ) m_pTable->borderRemove( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); } void KSpreadView::addTable( KSpreadTable *_t ) { insertTable( _t ); // Connect some signals QObject::connect( _t, SIGNAL( sig_updateView( KSpreadTable* ) ), SLOT( slotUpdateView( KSpreadTable* ) ) ); QObject::connect( _t, SIGNAL( sig_updateView( KSpreadTable *, const QRect& ) ), SLOT( slotUpdateView( KSpreadTable*, const QRect& ) ) ); QObject::connect( _t, SIGNAL( sig_unselect( KSpreadTable *, const QRect& ) ), SLOT( slotUnselect( KSpreadTable *, const QRect& ) ) ); QObject::connect( _t, SIGNAL( sig_updateHBorder( KSpreadTable * ) ), SLOT( slotUpdateHBorder( KSpreadTable * ) ) ); QObject::connect( _t, SIGNAL( sig_updateVBorder( KSpreadTable * ) ), SLOT( slotUpdateVBorder( KSpreadTable * ) ) ); QObject::connect( _t, SIGNAL( sig_changeSelection( KSpreadTable *, const QRect &, const QRect & ) ), SLOT( slotChangeSelection( KSpreadTable *, const QRect &, const QRect & ) ) ); QObject::connect( _t, SIGNAL( sig_changeChooseSelection( KSpreadTable *, const QRect &, const QRect & ) ), SLOT( slotChangeChooseSelection( KSpreadTable *, const QRect &, const QRect & ) ) ); QObject::connect( _t, SIGNAL( sig_nameChanged( KSpreadTable*, const QString& ) ), this, SLOT( slotTableRenamed( KSpreadTable*, const QString& ) ) ); QObject::connect( _t, SIGNAL( sig_TableHidden( KSpreadTable* ) ), this, SLOT( slotTableHidden( KSpreadTable* ) ) ); QObject::connect( _t, SIGNAL( sig_TableShown( KSpreadTable* ) ), this, SLOT( slotTableShown( KSpreadTable* ) ) ); QObject::connect( _t, SIGNAL( sig_TableRemoved( KSpreadTable* ) ), this, SLOT( slotTableRemoved( KSpreadTable* ) ) ); QObject::connect( _t, SIGNAL( sig_TableActivated( KSpreadTable* ) ), this, SLOT( slotTableActivated( KSpreadTable* ) ) ); // ########### Why do these signals not send a pointer to the table? // This will lead to bugs. QObject::connect( _t, SIGNAL( sig_updateChildGeometry( KSpreadChild* ) ), SLOT( slotUpdateChildGeometry( KSpreadChild* ) ) ); QObject::connect( _t, SIGNAL( sig_removeChild( KSpreadChild* ) ), SLOT( slotRemoveChild( KSpreadChild* ) ) ); QObject::connect( _t, SIGNAL( sig_maxColumn( int ) ), m_pCanvas, SLOT( slotMaxColumn( int ) ) ); QObject::connect( _t, SIGNAL( sig_maxRow( int ) ), m_pCanvas, SLOT( slotMaxRow( int ) ) ); QObject::connect( _t, SIGNAL( sig_polygonInvalidated( const QPointArray& ) ), this, SLOT( repaintPolygon( const QPointArray& ) ) ); if(m_bLoading) updateBorderButton(); } void KSpreadView::slotTableRemoved( KSpreadTable *_t ) { QString m_tableName=_t->tableName(); m_pTabBar->removeTab( _t->tableName() ); if(m_pDoc->map()->findTable( m_pTabBar->listshow().first())) setActiveTable( m_pDoc->map()->findTable( m_pTabBar->listshow().first() )); else m_pTable = 0L; QValueList::Iterator it; QValueList area=doc()->listArea(); for ( it = area.begin(); it != area.end(); ++it ) { //remove Area Name when table target is removed if((*it).table_name==m_tableName) { doc()->removeArea((*it).ref_name); //now area name is used in formula //so you must recalc tables when remove areaname KSpreadTable *tbl; for ( tbl = doc()->map()->firstTable(); tbl != 0L; tbl = doc()->map()->nextTable() ) { tbl->refreshRemoveAreaName((*it).ref_name); } } } m_pHorzScrollBar->setValue(activeTable()->getScrollPosX()); m_pVertScrollBar->setValue(activeTable()->getScrollPosY()); } void KSpreadView::removeAllTables() { m_pTabBar->removeAllTabs(); setActiveTable( 0L ); } void KSpreadView::setActiveTable( KSpreadTable *_t,bool updateTable ) { if ( _t == m_pTable ) return; m_pTable = _t; if ( m_pTable == 0L ) return; if(updateTable) { m_pTabBar->setActiveTab( _t->tableName() ); m_pVBorderWidget->repaint(); m_pHBorderWidget->repaint(); m_pCanvas->repaint(); m_pCanvas->slotMaxColumn( m_pTable->maxColumn() ); m_pCanvas->slotMaxRow( m_pTable->maxRow() ); } resultOfCalc(); } void KSpreadView::slotRefreshView( ) { refreshView(); } void KSpreadView::slotTableActivated( KSpreadTable* table ) { m_pTabBar->setActiveTab( table->tableName() ); } void KSpreadView::slotTableRenamed( KSpreadTable* table, const QString& old_name ) { m_pTabBar->renameTab( old_name, table->tableName() ); } void KSpreadView::slotTableHidden( KSpreadTable* table ) { m_pTabBar->hideTable( table->tableName() ); } void KSpreadView::slotTableShown( KSpreadTable* table ) { m_pTabBar->displayTable( table->tableName() ); } void KSpreadView::changeTable( const QString& _name ) { if ( activeTable()->tableName() == _name ) return; KSpreadTable *t = m_pDoc->map()->findTable( _name ); if ( !t ) { kdDebug(36001) << "Unknown table " << _name << endl; return; } m_pCanvas->closeEditor(); activeTable()->setScrollPosX(m_pHorzScrollBar->value()); activeTable()->setScrollPosY(m_pVertScrollBar->value()); setActiveTable( t,false ); t->setActiveTable(); updateEditWidget(); m_pHorzScrollBar->setValue(t->getScrollPosX()); m_pVertScrollBar->setValue(t->getScrollPosY()); //refresh toggle button updateBorderButton(); } void KSpreadView::slotScrollToFirstTable() { m_pTabBar->scrollFirst(); } void KSpreadView::slotScrollToLeftTable() { m_pTabBar->scrollLeft(); } void KSpreadView::slotScrollToRightTable() { m_pTabBar->scrollRight(); } void KSpreadView::slotScrollToLastTable() { m_pTabBar->scrollLast(); } void KSpreadView::insertTable() { m_pCanvas->closeEditor(); activeTable()->setScrollPosX(m_pHorzScrollBar->value()); activeTable()->setScrollPosY(m_pVertScrollBar->value()); KSpreadTable *t = m_pDoc->createTable(); m_pDoc->addTable( t ); m_pHorzScrollBar->setValue(t->getScrollPosX()); m_pVertScrollBar->setValue(t->getScrollPosY()); updateEditWidget(); KSpreadUndoAddTable *undo = new KSpreadUndoAddTable(m_pDoc, t); m_pDoc->undoBuffer()->appendUndo( undo ); } void KSpreadView::hideTable() { if ( !m_pTable ) return; m_pTabBar->hideTable(); } void KSpreadView::showTable() { if ( !m_pTable ) return; KSpreadshow dlg( this, "Table show"); dlg.exec(); } void KSpreadView::copySelection() { if ( !m_pTable ) return; if(!m_pCanvas->editor()) { m_pTable->copySelection( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } else m_pCanvas->editor()->copy(); } void KSpreadView::copyAsText() { if ( !m_pTable ) return; m_pTable->copyAsText( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); } void KSpreadView::cutSelection() { if ( !m_pTable ) return; //don't used this function when we edit a cell. if( !m_pCanvas->editor()) { m_pTable->cutSelection( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); resultOfCalc(); updateEditWidget(); } else m_pCanvas->editor()->cut(); } void KSpreadView::paste() { if ( !m_pTable ) return; if( !m_pCanvas->editor() ) { QRect r( activeTable()-> selectionRect() ); if( r.left()==0 ) r.setCoords( m_pCanvas->markerColumn(), m_pCanvas->markerRow() , m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); m_pTable->paste( QPoint( r.left(), r.top() ) ); if( m_pTable->getAutoCalc() ) m_pTable->recalc(); resultOfCalc(); updateEditWidget(); } else { m_pCanvas->editor()->paste(); } } void KSpreadView::specialPaste() { if ( !m_pTable ) return; KSpreadspecial dlg( this, "Special Paste" ); if( dlg.exec() ) { if (m_pTable->getAutoCalc()) m_pTable->recalc(); resultOfCalc(); updateEditWidget(); } } void KSpreadView::removeComment() { if ( !m_pTable ) return; m_pTable->setSelectionRemoveComment( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } void KSpreadView::changeAngle() { if ( !m_pTable ) return; KSpreadAngle dlg( this, "Angle" ,QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() )); if(dlg.exec()) { if( (activeTable()->isRowSelected() == FALSE) && (activeTable()->isColumnSelected() == FALSE) ) m_pCanvas->adjustArea(false); } } void KSpreadView::mergeCell() { if ( !m_pTable ) return; if((activeTable()->isRowSelected()) ||(activeTable()->isColumnSelected())) { KMessageBox::error( this, i18n("Area too large!")); } else { m_pTable->mergeCell( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); } } void KSpreadView::dissociateCell() { if ( !m_pTable ) return; m_pTable->dissociateCell( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); } void KSpreadView::increaseIndent() { if ( !m_pTable ) return; m_pTable->increaseIndent( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } void KSpreadView::decreaseIndent() { if ( !m_pTable ) return; int column=m_pCanvas->markerColumn(); int row=m_pCanvas->markerRow(); m_pTable->decreaseIndent( QPoint( column, row ) ); KSpreadCell* cell = m_pTable->cellAt( column, row ); if(cell) m_decreaseIndent->setEnabled(cell->getIndent(column,row)>0); } void KSpreadView::goalSeek() { if ( m_pCanvas->editor() ) { m_pCanvas->deleteEditor( true ); // save changes } KSpreadGoalSeekDlg dlg( this, QPoint(m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), "KSpreadGoalSeekDlg" ); dlg.exec(); } void KSpreadView::consolidate() { if ( m_pCanvas->editor() ) { m_pCanvas->deleteEditor( true ); // save changes } KSpreadConsolidate * dlg = new KSpreadConsolidate( this, "Consolidate" ); dlg->show(); // dlg destroys itself } void KSpreadView::sortList() { KSpreadList dlg(this,"List selection"); dlg.exec(); } void KSpreadView::gotoCell() { KSpreadGotoDlg dlg( this, "GotoCell" ); dlg.exec(); } void KSpreadView::find() { KoFindDialog dlg( this, "Find", m_findOptions, m_findStrings ); if ( KoFindDialog::Accepted != dlg.exec() ) { return; } m_findOptions = dlg.options(); m_findStrings = dlg.findHistory(); // Do the finding! QPoint m_marker=QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); activeTable()->find( m_marker, dlg.pattern(), dlg.options(), m_pCanvas ); } void KSpreadView::replace() { KoReplaceDialog dlg( this, "Replace", m_findOptions, m_findStrings, m_replaceStrings ); if ( KoReplaceDialog::Accepted != dlg.exec() ) { return; } m_findOptions = dlg.options(); m_findStrings = dlg.findHistory(); m_replaceStrings = dlg.replacementHistory(); // Do the replacement. QPoint m_marker=QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); activeTable()->replace( m_marker, dlg.pattern(), dlg.replacement(), dlg.options(), m_pCanvas ); // Refresh the editWidget KSpreadCell *cell = activeTable()->cellAt( canvasWidget()->markerColumn(), canvasWidget()->markerRow() ); if ( cell->text() != 0L ) editWidget()->setText( cell->text() ); else editWidget()->setText( "" ); } void KSpreadView::conditional() { QRect rect( activeTable()-> selectionRect() ); if( (activeTable()->isRowSelected()) || (activeTable()->isColumnSelected()) ) { KMessageBox::error( this, i18n("Area too large!")); } else { if ( rect.left() == 0 || rect.top() == 0 || rect.right() == 0 || rect.bottom() == 0 ) { rect.setCoords( m_pCanvas->markerColumn(), m_pCanvas->markerRow(),m_pCanvas->markerColumn(), m_pCanvas->markerRow()); } KSpreadconditional dlg(this,"conditional",rect); dlg.exec(); } } void KSpreadView::validity() { QRect rect( activeTable()-> selectionRect() ); if( (activeTable()->isRowSelected()) || (activeTable()->isColumnSelected()) ) { KMessageBox::error( this, i18n("Area too large!")); } else { if ( rect.left() == 0 || rect.top() == 0 || rect.right() == 0 || rect.bottom() == 0 ) { rect.setCoords( m_pCanvas->markerColumn(), m_pCanvas->markerRow(),m_pCanvas->markerColumn(), m_pCanvas->markerRow()); } KSpreadDlgValidity dlg( this,"validity",rect); dlg.exec(); } } void KSpreadView::insertSeries() { KSpreadSeriesDlg dlg( this, "Series", QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); dlg.exec(); } void KSpreadView::sort() { QRect selection( m_pTable->selectionRect() ); if(selection.left()==0) { KMessageBox::error( this, i18n("You must select multiple cells") ); return; } KSpreadSortDlg dlg( this, "Sort" ); dlg.exec(); } void KSpreadView::insertHyperlink() { KSpreadLinkDlg dlg( this, "Create Hyperlink" ); dlg.exec(); } void KSpreadView::insertFromDatabase() { if ( m_pCanvas->editor() ) { m_pCanvas->deleteEditor( true ); // save changes } QRect rect = activeTable()->selectionRect(); if (rect.left() <= 0) { rect.setLeft( m_pCanvas->markerColumn() ); rect.setRight( m_pCanvas->markerColumn() ); rect.setTop( m_pCanvas->markerRow() ); rect.setBottom( m_pCanvas->markerRow() ); } KSpreadDatabaseDlg dlg(this, rect, "KSpreadDatabaseDlg"); dlg.exec(); } void KSpreadView::insertFromTextfile() { if ( m_pCanvas->editor() ) { m_pCanvas->deleteEditor( true ); // save changes } QRect rect = activeTable()->selectionRect(); if (rect.left() <= 0) { rect.setLeft( m_pCanvas->markerColumn() ); rect.setRight( m_pCanvas->markerColumn() ); rect.setTop( m_pCanvas->markerRow() ); rect.setBottom( m_pCanvas->markerRow() ); } KMessageBox::information( this, "Not implemented yet, work in progress..."); // KSpreadTextfileDlg dlg(this, rect, "KSpreadDatabaseDlg"); // dlg.exec(); } void KSpreadView::insertFromClipboard() { if ( m_pCanvas->editor() ) { m_pCanvas->deleteEditor( true ); // save changes } QRect rect = activeTable()->selectionRect(); if (rect.left() <= 0) { rect.setLeft( m_pCanvas->markerColumn() ); rect.setRight( m_pCanvas->markerColumn() ); rect.setTop( m_pCanvas->markerRow() ); rect.setBottom( m_pCanvas->markerRow() ); } KMessageBox::information( this, "Not implemented yet, work in progress..."); // KSpreadClipboard dlg(this, rect, "KSpreadDatabaseDlg"); // dlg.exec(); } void KSpreadView::setupPrinter( KPrinter &prt ) { //apply page layout parameters KoFormat pageFormat = m_pTable->paperFormat(); prt.setPageSize( static_cast( KoPageFormat::printerPageSize( pageFormat ) ) ); if ( m_pTable->orientation() == PG_LANDSCAPE || pageFormat == PG_SCREEN ) prt.setOrientation( KPrinter::Landscape ); else prt.setOrientation( KPrinter::Portrait ); prt.setFullPage( TRUE ); prt.setResolution ( 72 ); } void KSpreadView::print( KPrinter &prt ) { //store the current setting in a temporary variable KoOrientation _orient = m_pTable->orientation(); QPainter painter; painter.begin( &prt ); //use the current orientation from print dialog if ( prt.orientation() == KPrinter::Landscape ) { m_pTable->setPaperOrientation( PG_LANDSCAPE ); } else { m_pTable->setPaperOrientation( PG_PORTRAIT ); } // Print the table and tell that m_pDoc is NOT embedded. m_pTable->print( painter, &prt ); painter.end(); //Restore original orientation m_pTable->setPaperOrientation( _orient ); } void KSpreadView::insertChart( const QRect& _geometry, KoDocumentEntry& _e ) { if ( !m_pTable ) return; // Transform the view coordinates to document coordinates QWMatrix m = matrix().invert(); QPoint tl = m.map( _geometry.topLeft() ); QPoint br = m.map( _geometry.bottomRight() ); if( (activeTable()->isRowSelected()) || (activeTable()->isColumnSelected()) ) { KMessageBox::error( this, i18n("Area too large!")); m_pTable->insertChart( QRect( tl, br ), _e, QRect( m_pCanvas->markerColumn(), m_pCanvas->markerRow(),1,1) ); } else { // Insert the new child in the active table. m_pTable->insertChart( QRect( tl, br ), _e, m_pTable->selectionRect() ); } } void KSpreadView::insertChild( const QRect& _geometry, KoDocumentEntry& _e ) { if ( !m_pTable ) return; // Transform the view coordinates to document coordinates QWMatrix m = matrix().invert(); QPoint tl = m.map( _geometry.topLeft() ); QPoint br = m.map( _geometry.bottomRight() ); // Insert the new child in the active table. m_pTable->insertChild( QRect( tl, br ), _e ); } void KSpreadView::slotRemoveChild( KSpreadChild *_child ) { if ( _child->table() != m_pTable ) return; // Make shure that this child has no active embedded view -> activate ourselfs partManager()->setActivePart( koDocument(), this ); partManager()->setSelectedPart( 0 ); } void KSpreadView::slotUpdateChildGeometry( KSpreadChild */*_child*/ ) { // ############## // TODO /* if ( _child->table() != m_pTable ) return; // Find frame for child KSpreadChildFrame *f = 0L; QPtrListIterator it( m_lstFrames ); for ( ; it.current() && !f; ++it ) if ( it.current()->child() == _child ) f = it.current(); assert( f != 0L ); // Are we already up to date ? if ( _child->geometry() == f->partGeometry() ) return; // TODO zooming f->setPartGeometry( _child->geometry() ); */ } void KSpreadView::togglePageBorders( bool mode ) { if ( !m_pTable ) return; m_pTable->setShowPageBorders( mode ); } void KSpreadView::preference() { if ( !m_pTable ) return; KSpreadpreference dlg( this, "Preference"); if(dlg.exec()) m_pTable->refreshPreference(); } void KSpreadView::addModifyComment() { if ( !m_pTable ) return; KSpreadComment dlg( this, "comment",QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() )); if(dlg.exec()) updateEditWidget(); } void KSpreadView::editCell() { if ( m_pCanvas->editor() ) return; m_pCanvas->createEditor(); } void KSpreadView::nextTable(){ KSpreadTable *t = m_pDoc->map()->nextTable( activeTable() ); if ( !t ) { kdDebug(36001) << "Unknown table " << endl; return; } m_pCanvas->closeEditor(); activeTable()->setScrollPosX(m_pHorzScrollBar->value()); activeTable()->setScrollPosY(m_pVertScrollBar->value()); setActiveTable( t,false ); t->setActiveTable(); } void KSpreadView::previousTable(){ KSpreadTable *t = m_pDoc->map()->previousTable( activeTable() ); if ( !t ) { kdDebug(36001) << "Unknown table " << endl; return; } m_pCanvas->closeEditor(); activeTable()->setScrollPosX(m_pHorzScrollBar->value()); activeTable()->setScrollPosY(m_pVertScrollBar->value()); setActiveTable( t,false ); t->setActiveTable(); } void KSpreadView::firstTable(){ KSpreadTable *t = m_pDoc->map()->firstTable(); if ( !t ) { kdDebug(36001) << "Unknown table " << endl; return; } m_pCanvas->closeEditor(); activeTable()->setScrollPosX(m_pHorzScrollBar->value()); activeTable()->setScrollPosY(m_pVertScrollBar->value()); setActiveTable( t,false ); t->setActiveTable(); } void KSpreadView::lastTable(){ KSpreadTable *t = m_pDoc->map()->lastTable( ); if ( !t ) { kdDebug(36001) << "Unknown table " << endl; return; } m_pCanvas->closeEditor(); activeTable()->setScrollPosX(m_pHorzScrollBar->value()); activeTable()->setScrollPosY(m_pVertScrollBar->value()); setActiveTable( t,false ); t->setActiveTable(); } void KSpreadView::keyPressEvent ( QKeyEvent* _ev ) { // Dont eat accelerators if ( _ev->state() & ( Qt::AltButton | Qt::ControlButton ) ){ if ( _ev->state() & ( Qt::ControlButton ) ){ switch( _ev->key() ){ #ifndef NDEBUG case Key_V: // Ctrl+Shift+V to show debug (similar to KWord) if ( _ev->state() & Qt::ShiftButton ) m_pTable->printDebug(); #endif default: QWidget::keyPressEvent( _ev ); return; } } QWidget::keyPressEvent( _ev ); } else QApplication::sendEvent( m_pCanvas, _ev ); } KoDocument* KSpreadView::hitTest( const QPoint &pos ) { // Code copied from KoView::hitTest KoViewChild *viewChild; QWMatrix m = matrix(); m.translate( m_pCanvas->xOffset(), m_pCanvas->yOffset() ); KoDocumentChild *docChild = selectedChild(); if ( docChild ) { if ( ( viewChild = child( docChild->document() ) ) ) { if ( viewChild->frameRegion( m ).contains( pos ) ) return 0; } else if ( docChild->frameRegion( m ).contains( pos ) ) return 0; } docChild = activeChild(); if ( docChild ) { if ( ( viewChild = child( docChild->document() ) ) ) { if ( viewChild->frameRegion( m ).contains( pos ) ) return 0; } else if ( docChild->frameRegion( m ).contains( pos ) ) return 0; } QPoint pos2( int(pos.x() / zoom()), int(pos.y() / zoom()) ); QPtrListIterator it( m_pDoc->children() ); for (; it.current(); ++it ) { // Is the child document on the visible table ? if ( ((KSpreadChild*)it.current())->table() == m_pTable ) { KoDocument *doc = it.current()->hitTest( pos2, m ); if ( doc ) return doc; } } return m_pDoc; } int KSpreadView::leftBorder() const { return YBORDER_WIDTH; } int KSpreadView::rightBorder() const { return m_pVertScrollBar->width(); } int KSpreadView::topBorder() const { return m_pToolWidget->height() + XBORDER_HEIGHT; } int KSpreadView::bottomBorder() const { return m_pHorzScrollBar->height(); } void KSpreadView::refreshView() { bool active=activeTable()->getShowFormula(); m_alignLeft->setEnabled(!active); m_alignCenter->setEnabled(!active); m_alignRight->setEnabled(!active); active=m_pDoc->getShowFormulaBar(); editWidget()->showEditWidget(active); int posFrame=30; if(active) posWidget()->show(); else { posWidget()->hide(); posFrame=0; } m_pToolWidget->show(); // If this value (30) is changed then topBorder() needs to // be changed, too. m_pToolWidget->setGeometry( 0, 0, width(), /*30*/posFrame ); int top = /*30*/posFrame; if(m_pDoc->getShowTabBar()) { m_pTabBarFirst->setGeometry( 0, height() - 16, 16, 16 ); m_pTabBarLeft->setGeometry( 16, height() - 16, 16, 16 ); m_pTabBarRight->setGeometry( 32, height() - 16, 16, 16 ); m_pTabBarLast->setGeometry( 48, height() - 16, 16, 16 ); m_pTabBarFirst->show(); m_pTabBarLeft->show(); m_pTabBarRight->show(); m_pTabBarLast->show(); } else { m_pTabBarFirst->hide(); m_pTabBarLeft->hide(); m_pTabBarRight->hide(); m_pTabBarLast->hide(); } if(!m_pDoc->getShowHorizontalScrollBar()) m_pTabBar->setGeometry( 64, height() - 16, width() -64, 16 ); else m_pTabBar->setGeometry( 64, height() - 16, width() / 2 - 64, 16 ); if(m_pDoc->getShowTabBar()) m_pTabBar->show(); else m_pTabBar->hide(); // David's suggestion: move the scrollbars to KSpreadCanvas, but keep those resize statements int widthScrollbarVertical=16; if(m_pDoc->getShowHorizontalScrollBar()) m_pHorzScrollBar->show(); else m_pHorzScrollBar->hide(); if(!m_pDoc->getShowTabBar() && !m_pDoc->getShowHorizontalScrollBar()) m_pVertScrollBar->setGeometry( width() - 16, top , 15, height() - top ); else m_pVertScrollBar->setGeometry( width() - 16, top , 15, height() - 16 - top ); m_pVertScrollBar->setSteps( 20 /*linestep*/, m_pVertScrollBar->height() /*pagestep*/); if(m_pDoc->getShowVerticalScrollBar()) m_pVertScrollBar->show(); else { widthScrollbarVertical=0; m_pVertScrollBar->hide(); } int widthRowHeader=YBORDER_WIDTH; if(m_pDoc->getShowRowHeader()) m_pVBorderWidget->show(); else { widthRowHeader=0; m_pVBorderWidget->hide(); } int heightColHeader=XBORDER_HEIGHT; if(m_pDoc->getShowColHeader()) m_pHBorderWidget->show(); else { heightColHeader=0; m_pHBorderWidget->hide(); } if(statusBar()) { if(m_pDoc->getShowStatusBar()) statusBar()->show(); else statusBar()->hide(); } m_pHorzScrollBar->setGeometry( width() / 2, height() - 16, width() / 2 - widthScrollbarVertical, 15 ); m_pHorzScrollBar->setSteps( 20 /*linestep*/, m_pHorzScrollBar->width() /*pagestep*/); if(!m_pDoc->getShowTabBar() && !m_pDoc->getShowHorizontalScrollBar()) m_pFrame->setGeometry( 0, top, width()-widthScrollbarVertical, height() - top ); else m_pFrame->setGeometry( 0, top, width()-widthScrollbarVertical, height() -16 - top ); m_pFrame->show(); m_pCanvas->setGeometry( widthRowHeader, heightColHeader, m_pFrame->width() -widthRowHeader, m_pFrame->height() - heightColHeader ); m_pHBorderWidget->setGeometry( widthRowHeader + 1, 0, m_pFrame->width() - widthRowHeader, heightColHeader ); m_pVBorderWidget->setGeometry( 0,heightColHeader + 1, widthRowHeader, m_pFrame->height() - heightColHeader ); } void KSpreadView::resizeEvent( QResizeEvent * ) { refreshView(); } void KSpreadView::popupChildMenu( KoChild* child, const QPoint& global_pos ) { if ( !child ) return; if ( m_popupChild != 0 ) delete m_popupChild; m_popupChildObject = static_cast(child); m_popupChild = new QPopupMenu( this ); m_popupChild->insertItem( i18n("Delete Embedded Document"), this, SLOT( slotPopupDeleteChild() ) ); m_popupChild->popup( global_pos ); } void KSpreadView::slotPopupDeleteChild() { if ( !m_popupChildObject || !m_popupChildObject->table() ) return; int ret = KMessageBox::warningYesNo(this,i18n("You are going to remove this embedded document.\nDo you want to continue?"),i18n("Delete Embedded Document")); if ( ret == KMessageBox::Yes ) { m_popupChildObject->table()->deleteChild( m_popupChildObject ); m_popupChildObject = 0; } } void KSpreadView::popupColumnMenu(const QPoint & _point) { assert( m_pTable ); if ( !koDocument()->isReadWrite() ) return; if (m_pPopupColumn != 0L ) delete m_pPopupColumn ; m_pPopupColumn = new QPopupMenu( this ); m_cellLayout->plug( m_pPopupColumn ); m_pPopupColumn->insertSeparator(); m_cut->plug( m_pPopupColumn ); m_copy->plug( m_pPopupColumn ); m_paste->plug( m_pPopupColumn ); m_specialPaste->plug( m_pPopupColumn ); m_insertCellCopy->plug( m_pPopupColumn ); m_pPopupColumn->insertSeparator(); m_default->plug( m_pPopupColumn ); // If there is no selection if((activeTable()->isRowSelected() == FALSE) && (activeTable()->isColumnSelected() == FALSE) ) { m_areaName->plug( m_pPopupColumn ); } m_resizeColumn->plug( m_pPopupColumn ); m_pPopupColumn->insertItem( i18n("Adjust Column"), this, SLOT(slotPopupAdjustColumn() ) ); m_pPopupColumn->insertSeparator(); m_insertColumn->plug( m_pPopupColumn ); m_deleteColumn->plug( m_pPopupColumn ); m_hideColumn->plug( m_pPopupColumn ); m_showSelColumns->setEnabled(false); int i; ColumnLayout * col; QRect rect = activeTable()->selectionRect(); kdDebug(36001) << "Column: L: " << rect.left() << endl; for ( i = rect.left(); i <= rect.right(); ++i ) { if (i == 2) // "B" { col = activeTable()->columnLayout( 1 ); if ( col->isHide() ) { m_showSelColumns->setEnabled(true); m_showSelColumns->plug( m_pPopupColumn ); break; } } col = activeTable()->columnLayout( i ); if ( col->isHide() ) { m_showSelColumns->setEnabled(true); m_showSelColumns->plug( m_pPopupColumn ); break; } } QObject::connect( m_pPopupColumn, SIGNAL(activated( int ) ), this, SLOT(slotActivateTool( int ) ) ); m_pPopupColumn->popup( _point ); } void KSpreadView::slotPopupAdjustColumn() { if ( !m_pTable ) return; canvasWidget()->adjustArea(); } void KSpreadView::popupRowMenu(const QPoint & _point ) { assert( m_pTable ); if ( !koDocument()->isReadWrite() ) return; if (m_pPopupRow != 0L ) delete m_pPopupRow ; m_pPopupRow= new QPopupMenu(); m_cellLayout->plug( m_pPopupRow ); m_pPopupRow->insertSeparator(); m_cut->plug( m_pPopupRow ); m_copy->plug( m_pPopupRow ); m_paste->plug( m_pPopupRow ); m_specialPaste->plug( m_pPopupRow ); m_insertCellCopy->plug( m_pPopupRow ); m_pPopupRow->insertSeparator(); m_default->plug( m_pPopupRow ); // If there is no selection if( (activeTable()->isRowSelected() == FALSE) && (activeTable()->isColumnSelected() == FALSE) ) { m_areaName->plug( m_pPopupRow ); } m_resizeRow->plug( m_pPopupRow ); m_pPopupRow->insertItem( i18n("Adjust Row"), this, SLOT( slotPopupAdjustRow() ) ); m_pPopupRow->insertSeparator(); m_insertRow->plug( m_pPopupRow ); m_deleteRow->plug( m_pPopupRow ); m_hideRow->plug( m_pPopupRow ); m_showSelColumns->setEnabled(false); int i; RowLayout * row; QRect rect = activeTable()->selectionRect(); for ( i = rect.top(); i <= rect.bottom(); ++i ) { kdDebug(36001) << "popupRow: " << rect.top() << endl; if (i == 2) { row = activeTable()->rowLayout( 1 ); if ( row->isHide() ) { m_showSelRows->setEnabled(true); m_showSelRows->plug( m_pPopupRow ); break; } } row = activeTable()->rowLayout( i ); if ( row->isHide() ) { m_showSelRows->setEnabled(true); m_showSelRows->plug( m_pPopupRow ); break; } } QObject::connect( m_pPopupRow, SIGNAL( activated( int ) ), this, SLOT( slotActivateTool( int ) ) ); m_pPopupRow->popup( _point ); } void KSpreadView::slotPopupAdjustRow() { if ( !m_pTable ) return; canvasWidget()->adjustArea(); } void KSpreadView::slotListChoosePopupMenu( ) { assert( m_pTable ); if ( m_popupListChoose != 0L ) delete m_popupListChoose; if(!koDocument()->isReadWrite() ) return; m_popupListChoose = new QPopupMenu(); int id = 0; QRect selection( m_pTable->selectionRect() ); if(selection.left()==0) selection.setCoords(m_pCanvas->markerColumn(),m_pCanvas->markerRow(), m_pCanvas->markerColumn(),m_pCanvas->markerRow()); KSpreadCell *cell = m_pTable->cellAt( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); QString tmp=cell->text(); QStringList itemList; KSpreadCell* c = m_pTable->firstCell(); for( ;c; c = c->nextCell() ) { int col = c->column(); if ( selection.left() <= col && selection.right() >= col &&!c->isObscuringForced()&& !(col==m_pCanvas->markerColumn()&& c->row()==m_pCanvas->markerRow())) { if(c->isString() && c->text()!=tmp && !c->text().isEmpty()) { if(itemList.findIndex(c->text())==-1) itemList.append(c->text()); } } } for ( QStringList::Iterator it = itemList.begin(); it != itemList.end();++it ) m_popupListChoose->insertItem( (*it), id++ ); if(id==0) return; RowLayout *rl = m_pTable->rowLayout( m_pCanvas->markerRow()); int tx = m_pTable->columnPos( m_pCanvas->markerColumn(), m_pCanvas ); int ty = m_pTable->rowPos(m_pCanvas->markerRow(), m_pCanvas ); int h = rl->height( m_pCanvas ); if ( cell->extraYCells()) h = cell->extraHeight(); ty += h; QPoint p( tx, ty ); QPoint p2 = m_pCanvas->mapToGlobal( p ); m_popupListChoose->popup( p2 ); QObject::connect( m_popupListChoose, SIGNAL( activated( int ) ), this, SLOT( slotItemSelected( int ) ) ); } void KSpreadView::slotItemSelected( int id) { QString tmp=m_popupListChoose->text(id); KSpreadCell *cell = m_pTable->nonDefaultCell( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); if(tmp==cell->text()) return; if ( !m_pDoc->undoBuffer()->isLocked() ) { KSpreadUndoSetText* undo = new KSpreadUndoSetText( m_pDoc, m_pTable, cell->text(), m_pCanvas->markerColumn(), m_pCanvas->markerRow(), cell->formatType()); m_pDoc->undoBuffer()->appendUndo( undo ); } cell->setCellText( tmp, true ); editWidget()->setText( tmp ); } void KSpreadView::openPopupMenu( const QPoint & _point ) { assert( m_pTable ); if ( m_pPopupMenu != 0L ) delete m_pPopupMenu; if(!koDocument()->isReadWrite() ) return; m_pPopupMenu = new QPopupMenu(); m_cellLayout->plug( m_pPopupMenu ); m_pPopupMenu->insertSeparator(); m_cut->plug( m_pPopupMenu ); m_copy->plug( m_pPopupMenu ); m_paste->plug( m_pPopupMenu ); m_specialPaste->plug( m_pPopupMenu ); m_insertCellCopy->plug( m_pPopupMenu ); m_pPopupMenu->insertSeparator(); m_delete->plug( m_pPopupMenu ); m_adjust->plug( m_pPopupMenu ); m_default->plug( m_pPopupMenu ); // If there is no selection if( (activeTable()->isRowSelected() == FALSE) && (activeTable()->isColumnSelected() == FALSE) ) { m_areaName->plug( m_pPopupMenu ); m_pPopupMenu->insertSeparator(); m_insertCell->plug( m_pPopupMenu ); m_removeCell->plug( m_pPopupMenu ); } KSpreadCell *cell = m_pTable->cellAt( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); m_pPopupMenu->insertSeparator(); m_addModifyComment->plug( m_pPopupMenu ); if( !cell->comment(m_pCanvas->markerColumn(), m_pCanvas->markerRow()).isEmpty() ) { m_removeComment->plug( m_pPopupMenu ); } if(activeTable()->testListChoose(QPoint(m_pCanvas->markerColumn(), m_pCanvas->markerRow()))) { m_pPopupMenu->insertSeparator(); m_pPopupMenu->insertItem( i18n("Selection List..."), this, SLOT( slotListChoosePopupMenu() ) ); } // Remove informations about the last tools we offered m_lstTools.clear(); m_lstTools.setAutoDelete( true ); if(!activeTable()->getWordSpelling( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() )).isEmpty()) { m_popupMenuFirstToolId = 10; int i = 0; QValueList tools = KDataToolInfo::query( "QString", "text/plain", m_pDoc->instance() ); if( tools.count() > 0 ) { m_pPopupMenu->insertSeparator(); QValueList::Iterator entry = tools.begin(); for( ; entry != tools.end(); ++entry ) { QStringList lst = (*entry).userCommands(); QStringList::ConstIterator it = lst.begin(); // ### Torben: Insert pixmaps here, too for (; it != lst.end(); ++it ) m_pPopupMenu->insertItem( *it, m_popupMenuFirstToolId + i++ ); lst = (*entry).commands(); it = lst.begin(); for (; it != lst.end(); ++it ) { ToolEntry *t = new ToolEntry; t->command = *it; t->info = *entry; m_lstTools.append( t ); } } QObject::connect( m_pPopupMenu, SIGNAL( activated( int ) ), this, SLOT( slotActivateTool( int ) ) ); } } m_pPopupMenu->popup( _point ); } void KSpreadView::slotActivateTool( int _id ) { Q_ASSERT( m_pTable ); // Is it the id of a tool in the latest popupmenu ? if( _id < m_popupMenuFirstToolId ) return; ToolEntry* entry = m_lstTools.at( _id - m_popupMenuFirstToolId ); KDataTool* tool = entry->info.createTool(); if ( !tool ) { kdDebug(36001) << "Could not create Tool" << endl; return; } QString text = activeTable()->getWordSpelling( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() )); if ( tool->run( entry->command, &text, "QString", "text/plain") ) { activeTable()->setWordSpelling( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ),text); KSpreadCell *cell = m_pTable->cellAt( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); editWidget()->setText( cell->text() ); } } void KSpreadView::deleteSelection() { Q_ASSERT( m_pTable ); m_pTable->deleteSelection( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); resultOfCalc(); updateEditWidget(); } void KSpreadView::adjust() { if( (activeTable()->isRowSelected()) || (activeTable()->isColumnSelected()) ) { KMessageBox::error( this, i18n("Area too large!")); } else { canvasWidget()->adjustArea(); } } void KSpreadView::clearTextSelection() { Q_ASSERT( m_pTable ); m_pTable->clearTextSelection( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } void KSpreadView::clearCommentSelection() { Q_ASSERT( m_pTable ); m_pTable->setSelectionRemoveComment( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } void KSpreadView::clearValiditySelection() { Q_ASSERT( m_pTable ); m_pTable->clearValiditySelection( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } void KSpreadView::clearConditionalSelection() { Q_ASSERT( m_pTable ); m_pTable->clearConditionalSelection( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } void KSpreadView::defaultSelection() { Q_ASSERT( m_pTable ); m_pTable->defaultSelection( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ); updateEditWidget(); } void KSpreadView::slotInsert() { QRect r( activeTable()-> selectionRect() ); if(r.left()==0) r.setCoords(m_pCanvas->markerColumn(), m_pCanvas->markerRow() ,m_pCanvas->markerColumn(), m_pCanvas->markerRow()); KSpreadinsert dlg( this, "Insert", r,KSpreadinsert::Insert ); dlg.exec(); } void KSpreadView::slotRemove() { QRect r( activeTable()-> selectionRect() ); if(r.left()==0) r.setCoords(m_pCanvas->markerColumn(), m_pCanvas->markerRow() ,m_pCanvas->markerColumn(), m_pCanvas->markerRow()); KSpreadinsert dlg( this, "Remove", r,KSpreadinsert::Remove ); dlg.exec(); } void KSpreadView::slotInsertCellCopy() { if ( !m_pTable ) return; QRect r( activeTable()->selectionRect() ); if(r.left()==0 ) r.setCoords(m_pCanvas->markerColumn(), m_pCanvas->markerRow() , m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); if( !m_pTable->testAreaPasteInsert()) m_pTable->paste( QPoint( r.left(), r.top() ) ,true, Normal,OverWrite,true); else { QRect r( activeTable()-> selectionRect() ); KSpreadpasteinsert dlg( this, "Remove", r ); dlg.exec(); } if(m_pTable->getAutoCalc()) m_pTable->recalc(); updateEditWidget(); } void KSpreadView::setAreaName() { KSpreadarea dlg( this, "Area Name",QPoint(m_pCanvas->markerColumn(), m_pCanvas->markerRow()) ); dlg.exec(); } void KSpreadView::showAreaName() { KSpreadreference dlg( this, "Show Area" ); dlg.exec(); } void KSpreadView::resizeRow() { if( activeTable()->isColumnSelected() ) KMessageBox::error( this, i18n("Area too large!")); else { KSpreadresize2 dlg( this, "Resize Row", KSpreadresize2::resize_row ); dlg.exec(); } } void KSpreadView::resizeColumn() { if( activeTable()->isRowSelected() ) KMessageBox::error( this, i18n("Area too large!")); else { KSpreadresize2 dlg( this, "Resize Column", KSpreadresize2::resize_column ); dlg.exec(); } } void KSpreadView::equalizeRow() { if( activeTable()->isColumnSelected() ) KMessageBox::error( this, i18n("Area too large!")); else canvasWidget()->equalizeRow(); } void KSpreadView::equalizeColumn() { if( activeTable()->isRowSelected() ) KMessageBox::error( this, i18n("Area too large!")); else canvasWidget()->equalizeColumn(); } void KSpreadView::layoutDlg() { QRect selection( m_pTable->selectionRect() ); if ( selection.contains( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ) ) CellLayoutDlg dlg( this, m_pTable, selection.left(), selection.top(), selection.right(), selection.bottom() ); else CellLayoutDlg dlg( this, m_pTable, m_pCanvas->markerColumn(), m_pCanvas->markerRow(), m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); } void KSpreadView::paperLayoutDlg() { m_pTable->paperLayoutDlg(); } void KSpreadView::multiRow( bool b ) { if ( m_toolbarLock ) return; if ( m_pTable != 0L ) m_pTable->setSelectionMultiRow( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), b ); } void KSpreadView::alignLeft( bool b ) { if ( m_toolbarLock ) return; if ( m_pTable != 0L ) { if ( !b ) m_pTable->setSelectionAlign( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Undefined ); else m_pTable->setSelectionAlign( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Left ); } } void KSpreadView::alignRight( bool b ) { if ( m_toolbarLock ) return; if ( m_pTable != 0L ) { if ( !b ) m_pTable->setSelectionAlign( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Undefined ); else m_pTable->setSelectionAlign( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Right ); } } void KSpreadView::alignCenter( bool b ) { if ( m_toolbarLock ) return; if ( m_pTable != 0L ) { if ( !b ) m_pTable->setSelectionAlign( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Undefined ); else m_pTable->setSelectionAlign( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Center ); } } void KSpreadView::alignTop( bool b ) { if ( m_toolbarLock ) return; if ( !b ) return; if ( m_pTable != 0L ) m_pTable->setSelectionAlignY( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Top ); } void KSpreadView::alignBottom( bool b ) { if ( m_toolbarLock ) return; if ( !b ) return; if ( m_pTable != 0L ) m_pTable->setSelectionAlignY( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Bottom ); } void KSpreadView::alignMiddle( bool b ) { if ( m_toolbarLock ) return; if ( !b ) return; if ( m_pTable != 0L ) m_pTable->setSelectionAlignY( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), KSpreadLayout::Middle ); } void KSpreadView::moneyFormat(bool b) { if ( m_toolbarLock ) return; if ( m_pTable != 0L ) m_pTable->setSelectionMoneyFormat( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ),b ); updateEditWidget(); } void KSpreadView::precisionPlus() { if ( m_pTable != 0L ) m_pTable->setSelectionPrecision( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), 1 ); } void KSpreadView::precisionMinus() { if ( m_pTable != 0L ) m_pTable->setSelectionPrecision( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ), -1 ); } void KSpreadView::percent( bool b) { if ( m_toolbarLock ) return; if ( m_pTable != 0L ) m_pTable->setSelectionPercent( QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ) ,b ); updateEditWidget(); } void KSpreadView::insertObject() { KoDocumentEntry e = m_insertPart->documentEntry();//KoPartSelectDia::selectPart( m_pCanvas ); if ( e.isEmpty() ) return; (void)new KSpreadInsertHandler( this, m_pCanvas, e ); } void KSpreadView::insertChart() { if( activeTable()->isColumnSelected() || activeTable()->isRowSelected() ) { KMessageBox::error( this, i18n("Area too large!")); return; } QValueList vec = KoDocumentEntry::query( "'KOfficeChart' in ServiceTypes" ); if ( vec.isEmpty() ) { KMessageBox::error( this, i18n("No charting component registered") ); return; } (void)new KSpreadInsertHandler( this, m_pCanvas, vec[0], TRUE ); } /* // TODO Use KoView setScaling/xScaling/yScaling instead void KSpreadView::zoomMinus() { if ( m_fZoom <= 0.25 ) return; m_fZoom -= 0.25; if ( m_pTable != 0L ) m_pTable->setLayoutDirtyFlag(); m_pCanvas->repaint(); m_pVBorderWidget->repaint(); m_pHBorderWidget->repaint(); } void KSpreadView::zoomPlus() { if ( m_fZoom >= 3 ) return; m_fZoom += 0.25; if ( m_pTable != 0L ) m_pTable->setLayoutDirtyFlag(); m_pCanvas->repaint(); m_pVBorderWidget->repaint(); m_pHBorderWidget->repaint(); } */ void KSpreadView::removeTable() { if ( doc()->map()->count() <= 1||(m_pTabBar->listshow().count()<=1) ) { KNotifyClient::beep(); KMessageBox::sorry( this, i18n("You cannot delete the only table of the map."), i18n("Remove Table") ); // FIXME bad english? no english! return; } KNotifyClient::beep(); int ret = KMessageBox::warningYesNo(this,i18n("You are going to remove the active table.\nDo you want to continue?"),i18n("Remove Table")); if ( ret == KMessageBox::Yes ) { if ( m_pCanvas->editor() ) { m_pCanvas->deleteEditor( false ); } m_pDoc->setModified( true ); KSpreadTable *tbl = activeTable(); KSpreadUndoRemoveTable* undo = new KSpreadUndoRemoveTable(m_pDoc, tbl); m_pDoc->undoBuffer()->appendUndo( undo ); tbl->map()->takeTable( tbl ); doc()->takeTable( tbl ); } } void KSpreadView::slotRename() { m_pTabBar->slotRename(); } void KSpreadView::setText( const QString& _text ) { if ( m_pTable == 0L ) return; m_pTable->setText( m_pCanvas->markerRow(), m_pCanvas->markerColumn(), _text ); KSpreadCell* cell = m_pTable->cellAt( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); if(cell->isString() && !_text.isEmpty() && !_text.at(0).isDigit()) m_pDoc->addStringCompletion(_text); } //------------------------------------------------ // // Document signals // //------------------------------------------------ void KSpreadView::slotAddTable( KSpreadTable *_table ) { addTable( _table ); } void KSpreadView::slotUpdateView( KSpreadTable *_table ) { // kdDebug(36001)<<"void KSpreadView::slotUdateView( KSpreadTable *_table )\n"; // Do we display this table ? if ( _table != m_pTable ) return; m_pCanvas->update(); } void KSpreadView::slotUpdateView( KSpreadTable *_table, const QRect& _rect ) { // qDebug("void KSpreadView::slotUpdateView( KSpreadTable *_table, const QRect& %i %i|%i %i )\n",_rect.left(),_rect.top(),_rect.right(),_rect.bottom()); // Do we display this table ? if ( _table != m_pTable ) return; m_pCanvas->updateCellRect( _rect ); } void KSpreadView::slotUpdateHBorder( KSpreadTable *_table ) { // kdDebug(36001)<<"void KSpreadView::slotUpdateHBorder( KSpreadTable *_table )\n"; // Do we display this table ? if ( _table != m_pTable ) return; m_pHBorderWidget->update(); } void KSpreadView::slotUpdateVBorder( KSpreadTable *_table ) { // kdDebug("void KSpreadView::slotUpdateVBorder( KSpreadTable *_table )\n"; // Do we display this table ? if ( _table != m_pTable ) return; m_pVBorderWidget->update(); } void KSpreadView::slotChangeChooseSelection( KSpreadTable *_table, const QRect &_old, const QRect &_new ) { // Do we display this table ? if ( _table != m_pTable ) return; m_pCanvas->updateChooseMarker( _old, _new ); // Emit a signal for internal use emit sig_chooseSelectionChanged( _table, _new ); } void KSpreadView::slotChangeSelection( KSpreadTable *_table, const QRect &_old, const QRect& _old_marker ) { QRect n = _table->selectionRect(); // QRect m = _table->marker(); // printf ("void KSpreadView::slotChangeSelection( KSpreadTable *_table, const QRect &_old %i %i|%i %i, const QPoint &m %i %i )\n",_old.left(),_old.top(),_old.right(),_old.bottom(),_old_marker.x(),_old_marker.y() ); // printf (" const QRect &_new %i %i|%i %i, const QPoint &m %i %i )\n",n.left(),n.top(),n.right(),n.bottom(),m.x(),m.y() ); // Emit a signal for internal use emit sig_selectionChanged( _table, n ); // Empty selection ? // Activate or deactivate some actions. This code is duplicated // in KSpreadView::slotUnselect if ( ( n.left() == 0 && n.top() == 0 ) || _table->isRowSelected() || _table->isColumnSelected() ) { m_tableFormat->setEnabled( FALSE ); m_mergeCell->setEnabled(false); m_insertChartFrame->setEnabled(false); } else if ( (n.left() != n.right()) || (n.top() != n.bottom()) ) { m_tableFormat->setEnabled( TRUE ); m_mergeCell->setEnabled(true); m_insertChartFrame->setEnabled(true); } if( _table->isColumnSelected() ) { m_resizeRow->setEnabled(false); m_equalizeRow->setEnabled(false); } else { m_resizeRow->setEnabled(true); m_equalizeRow->setEnabled(true); } if( _table->isRowSelected() ) { m_resizeColumn->setEnabled(false); m_equalizeColumn->setEnabled(false); } else { m_resizeColumn->setEnabled(true); m_equalizeColumn->setEnabled(true); } resultOfCalc(); // Send some event around. This is read for example // by the calculator plugin. KSpreadSelectionChanged ev( n, activeTable()->name() ); QApplication::sendEvent( this, &ev ); // Do we display this table ? if ( _table != m_pTable ) return; m_pCanvas->updateSelection( _old, _old_marker ); m_pVBorderWidget->update(); m_pHBorderWidget->update(); } void KSpreadView::resultOfCalc() { double result=0.0; int nbCell=0; QRect n = activeTable()->selectionRect(); QRect tmpRect(n); if(n.left()==0) tmpRect.setCoords( m_pCanvas->markerColumn(), m_pCanvas->markerRow(), m_pCanvas->markerColumn(), m_pCanvas->markerRow()); MethodOfCalc tmpMethod=m_pDoc->getTypeOfCalc() ; if ( tmpMethod != NoneCalc ) { if( activeTable()->isColumnSelected() ) { KSpreadCell* c = activeTable()->firstCell(); for( ;c; c = c->nextCell() ) { int col = c->column(); if ( tmpRect.left() <= col && tmpRect.right() >= col &&!c->isObscuringForced()) { if(c->isNumeric()) { double val=c->valueDouble(); switch(tmpMethod) { case SumOfNumber: result+=val; break; case Average: result+=val; break; case Min: if(result!=0) result=QMIN(val,result); else result=val; break; case Max: if(result!=0) result=QMAX(val,result); else result=val; break; case Count: case NoneCalc: break; default: break; } nbCell++; } } } } else if( activeTable()->isRowSelected() ) { KSpreadCell* c = activeTable()->firstCell(); for( ; c; c = c->nextCell() ) { int row = c->row(); if ( tmpRect.top() <= row && tmpRect.bottom() >= row &&!c->isObscuringForced()) { if(c->isNumeric()) { double val=c->valueDouble(); switch(tmpMethod ) { case SumOfNumber: result+=val; break; case Average: result+=val; break; case Min: if(result!=0) result=QMIN(val,result); else result=val; break; case Max: if(result!=0) result=QMAX(val,result); else result=val; break; case Count: case NoneCalc: break; default: break; } nbCell++; } } } } else { for (int i=tmpRect.left();i<=tmpRect.right();i++) for(int j=tmpRect.top();j<=tmpRect.bottom();j++) { KSpreadCell *cell = activeTable()->cellAt( i, j ); if(!cell->isDefault() && cell->isNumeric()) { double val= cell->valueDouble(); switch(tmpMethod ) { case SumOfNumber: result+=val; break; case Average: result+=val; break; case Min: if(result!=0) result=QMIN(val,result); else result=val; break; case Max: if(result!=0) result=QMAX(val,result); else result=val; break; case Count: case NoneCalc: break; default: break; } nbCell++; } } } } QString tmp; switch(tmpMethod ) { case SumOfNumber: tmp=i18n(" Sum: %1").arg(result); break; case Average: result=result/nbCell; tmp=i18n("Average: %1").arg(result); break; case Min: tmp=i18n("Min: %1").arg(result); break; case Max: tmp=i18n("Max: %1").arg(result); break; case Count: tmp=i18n("Count: %1").arg(nbCell); break; case NoneCalc: tmp=""; break; } if ( m_sbCalcLabel ) m_sbCalcLabel->setText(QString(" ")+tmp+' '); } void KSpreadView::statusBarClicked(int _id) { if(!koDocument()->isReadWrite() ) return; if(_id==0) //menu calc { QPoint mousepos =QCursor::pos(); ((QPopupMenu*)factory()->container("calc_popup",this))->popup(mousepos); } } void KSpreadView::menuCalc(bool) { if( m_menuCalcMin->isChecked()) { doc()->setTypeOfCalc(Min); } else if(m_menuCalcMax->isChecked()) { doc()->setTypeOfCalc(Max); } else if(m_menuCalcCount->isChecked()) { doc()->setTypeOfCalc(Count); } else if(m_menuCalcAverage->isChecked()) { doc()->setTypeOfCalc(Average); } else if(m_menuCalcSum->isChecked()) { doc()->setTypeOfCalc(SumOfNumber); } else if( m_menuCalcNone->isChecked()) doc()->setTypeOfCalc(NoneCalc); resultOfCalc(); } void KSpreadView::slotUnselect( KSpreadTable *_table, const QRect& _old ) { // Do we display this table ? if ( _table != m_pTable ) return; // Unselect the action which only works on a selection // with mutiple cells. m_tableFormat->setEnabled( FALSE ); m_mergeCell->setEnabled(false); m_insertChartFrame->setEnabled(false); m_pCanvas->updateSelection( _old, _table->marker() ); m_pVBorderWidget->update(); m_pHBorderWidget->update(); } void KSpreadView::repaintPolygon( const QPointArray& polygon ) { QPointArray arr = polygon; QWMatrix m = matrix()/*.invert()*/; for( int i = 0; i < 4; ++i ) arr.setPoint( i, m.map( arr.point( i ) ) ); emit regionInvalidated( QRegion( arr ), TRUE ); } void KSpreadView::paintContent( QPainter& painter, const QRect& rect, bool transparent ) { m_pDoc->paintContent( painter, rect, transparent, activeTable() ); } QWMatrix KSpreadView::matrix() const { QWMatrix m; m.translate( -m_pCanvas->xOffset(), -m_pCanvas->yOffset() ); m.scale( zoom(), zoom() ); return m; } void KSpreadView::transformPart() { Q_ASSERT( selectedChild() ); if ( m_transformToolBox.isNull() ) { m_transformToolBox = new KoTransformToolBox( selectedChild(), topLevelWidget() ); m_transformToolBox->show(); m_transformToolBox->setDocumentChild( selectedChild() ); } else { m_transformToolBox->show(); m_transformToolBox->raise(); } } void KSpreadView::slotChildSelected( KoDocumentChild* ch ) { m_transform->setEnabled( TRUE ); if ( !m_transformToolBox.isNull() ) { m_transformToolBox->setEnabled( TRUE ); m_transformToolBox->setDocumentChild( ch ); } } void KSpreadView::slotChildUnselected( KoDocumentChild* ) { m_transform->setEnabled( FALSE ); if ( !m_transformToolBox.isNull() ) { m_transformToolBox->setEnabled( FALSE ); } } void KSpreadView::deleteEditor( bool saveChanges ) { m_pCanvas->deleteEditor( saveChanges ); } DCOPObject* KSpreadView::dcopObject() { if ( !m_dcop ) m_dcop = new KSpreadViewIface( this ); return m_dcop; } QWidget *KSpreadView::canvas() { return canvasWidget(); } int KSpreadView::canvasXOffset() const { return canvasWidget()->xOffset(); } int KSpreadView::canvasYOffset() const { return canvasWidget()->yOffset(); } void KSpreadView::guiActivateEvent( KParts::GUIActivateEvent *ev ) { if ( ev->activated() ) { if ( m_sbCalcLabel ) { resultOfCalc(); } } else { /*if(m_sbCalcLabel) { disconnect(m_sbCalcLabel,SIGNAL(pressed( int )),this,SLOT(statusBarClicked(int))); }*/ } KoView::guiActivateEvent( ev ); } void KSpreadView::openPopupMenuMenuPage( const QPoint & _point ) { if(!koDocument()->isReadWrite() ) return; if( m_pTabBar ) { m_removeTable->setEnabled( m_pTabBar->listshow().count()>1); static_cast(factory()->container("menupage_popup",this))->popup(_point); } } void KSpreadView::updateBorderButton() { m_showPageBorders->setChecked( m_pTable->isShowPageBorders() ); } void KSpreadView::removeTable( KSpreadTable *_t ) { QString m_tablName=_t->tableName(); m_pTabBar->removeTab( m_tablName ); setActiveTable( m_pDoc->map()->findTable( m_pTabBar->listshow().first() )); } void KSpreadView::insertTable( KSpreadTable* table ) { QString tabName = table->tableName(); if( !table->isHidden() ) { m_pTabBar->addTab(tabName); setActiveTable(table); } else { m_pTabBar->addHiddenTab(tabName); } } +QColor KSpreadView::borderColor() const +{ + return m_borderColor->color(); +} #include "kspread_view.moc" Index: trunk/koffice/kspread/kspread_view.h =================================================================== --- trunk/koffice/kspread/kspread_view.h (revision 152991) +++ trunk/koffice/kspread/kspread_view.h (revision 152992) @@ -1,703 +1,704 @@ /* This file is part of the KDE project Copyright (C) 1998, 1999 Torben Weis 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __kspread_gui_h__ #define __kspread_gui_h__ class QFrame; class QScrollBar; class QButton; class KSpreadView; class KSpreadEditWidget; class KSpreadCanvas; class KSpreadHBorder; class KSpreadVBorder; class KSpreadScripts; class KSpreadTable; class KSpreadDoc; class KSpreadPaperLayout; class KSpreadChildPicture; class KSpreadChildFrame; class KSpreadShell; class KSpreadTabBar; class KSpreadEditWidget; class KSpreadCanvas; class KSpreadHBorder; class KSpreadVBorder; class KSpreadChild; class KSpreadCell; class KSpreadLocationEditWidget; class KoDocumentEntry; class KStatusBarLabel; class TKSelectColorAction; class KAction; class KSelectAction; class KFontAction; class KFontSizeAction; class KToggleAction; class KoPartSelectAction; class KSpreadSpell; //class KMacroCommand; class KActionMenu; class DCOPObject; #include #include #include #include #include #include #include #include #include /** */ class KSpreadView : public KoView { friend class KSpreadCanvas; Q_OBJECT public: KSpreadView( QWidget *_parent, const char *_name, KSpreadDoc *_doc ); ~KSpreadView(); KSpreadCanvas* canvasWidget() const { return m_pCanvas; } KSpreadHBorder* hBorderWidget()const { return m_pHBorderWidget; } KSpreadVBorder* vBorderWidget()const { return m_pVBorderWidget; } QScrollBar* horzScrollBar()const { return m_pHorzScrollBar; } QScrollBar* vertScrollBar()const { return m_pVertScrollBar; } KSpreadEditWidget* editWidget()const { return m_pEditWidget; } //QLabel* posWidget() { return m_pPosWidget; } KSpreadLocationEditWidget* posWidget()const { return m_pPosWidget; } KSpreadDoc* doc()const { return m_pDoc; } void addTable( KSpreadTable *_t ); //void removeTable( KSpreadTable *_t ); void removeAllTables(); void setActiveTable( KSpreadTable *_t,bool updateTable=true ); const KSpreadTable* activeTable() const { return m_pTable; } KSpreadTable* activeTable() { return m_pTable; } KSpreadTabBar* tabBar()const { return m_pTabBar;} void openPopupMenu( const QPoint &_global ); void popupRowMenu(const QPoint & _point ) ; void popupColumnMenu( const QPoint & _point); // void showFormulaToolBar( bool show ); /** * Used by @ref KSpreadEditWidget. Sets the text of the active cell. */ void setText( const QString& _text ); void enableUndo( bool _b ); void enableRedo( bool _b ); /** * Called by @ref KSpreadInsertHandler * * @param _geometry is the zoomed geometry of the new child. */ void insertChart( const QRect& _geometry, KoDocumentEntry& _entry ); /** * Called by @ref KSpreadInsertHandler * * @param _geometry is the geometry of the new child. */ void insertChild( const QRect& _geometry, KoDocumentEntry& _entry ); virtual void print( KPrinter &printer ); virtual void setupPrinter( KPrinter &printer ); void paintContent( QPainter& painter, const QRect& rect, bool transparent ); /** * Fills the @ref KSpreadEditWidget with the current cells * content. This function is usually called after the * cursor moved. */ void updateEditWidget(); /** * Same as updateEditEidget() but no update of menus and toolbars */ void updateEditWidgetOnPress(); /** * Called before saving, to finish the current edition (if any) */ void deleteEditor( bool saveChanges = true ); virtual DCOPObject* dcopObject(); virtual QWidget *canvas(); virtual int canvasXOffset() const; virtual int canvasYOffset() const; /** * @reimp */ KoDocument *hitTest( const QPoint &pos ); void initConfig(); /** * refresh view when you hide/show vertical scrollbar */ void refreshView(); bool isLoading()const {return m_bLoading;} /** * write in statusBar result of calc (Min, or Max, average, sum, count) */ void resultOfCalc(); void initCalcMenu(); void changeNbOfRecentFiles(int _nb); void openPopupMenuMenuPage( const QPoint & _point ); void updateBorderButton(); void removeTable( KSpreadTable *_t ); void insertTable( KSpreadTable* table ); + QColor borderColor() const; public slots: void initialPosition(); /** * Actions */ void transformPart(); void copySelection(); void cutSelection(); void deleteSelection(); void clearTextSelection(); void clearCommentSelection(); void clearValiditySelection(); void clearConditionalSelection(); void RecalcWorkBook(); void RecalcWorkSheet(); void paste(); void specialPaste(); void editCell(); void setAreaName(); void showAreaName(); void undo(); void redo(); void adjust(); void defaultSelection(); void paperLayoutDlg(); void insertObject(); void insertFromDatabase(); void insertFromTextfile(); void insertFromClipboard(); void editGlobalScripts(); void editLocalScripts(); void reloadScripts(); void runLocalScript(); void togglePageBorders( bool ); void find(); void replace(); void conditional(); void validity(); void insertSeries(); void sort(); void insertHyperlink(); void goalSeek(); void consolidate(); void insertTable(); void removeTable(); void hideTable(); void showTable(); void helpUsing(); void insertChart(); void moneyFormat(bool b); void alignLeft( bool b ); void alignRight( bool b ); void alignCenter( bool b ); void alignTop( bool b ); void alignMiddle( bool b ); void alignBottom( bool b ); void multiRow( bool b ); void precisionMinus(); void precisionPlus(); void percent(bool b); void fontSelected( const QString &_font ); void fontSizeSelected( int size ); void bold( bool b ); void italic( bool b ); void underline( bool b ); void strikeOut( bool b ); void deleteColumn(); void insertColumn(); void deleteRow(); void insertRow(); void hideRow(); void showRow(); void showSelRows(); void hideColumn(); void showColumn(); void showSelColumns(); void insertMathExpr(); void formulaSelection( const QString &_math ); void changeTextColor(); void changeBackgroundColor(); void sortInc(); void sortDec(); void layoutDlg(); void borderBottom(); void borderRight(); void borderLeft(); void borderTop(); void borderOutline(); void borderAll(); void borderRemove(); void changeBorderColor(); void tableFormat(); // void oszilloscope(); void autoSum(); void resizeRow(); void resizeColumn(); void increaseFontSize(); void decreaseFontSize(); void upper(); void lower(); void equalizeColumn(); void equalizeRow(); void preference(); void firstLetterUpper(); void verticalText(bool ); void addModifyComment(); void removeComment(); void changeAngle(); void mergeCell(); void dissociateCell(); void gotoCell(); void increaseIndent(); void decreaseIndent(); void copyAsText(); /** * @ref #tabBar is connected to this slot. * When the user selects a new table using the @ref #tabBar this slot * is signaled. */ void changeTable( const QString& _name ); void nextTable(); void previousTable(); void firstTable(); void lastTable(); void sortList(); void statusBarClicked(int _id); void menuCalc(bool); protected slots: /** * Popup menu */ void slotActivateTool( int _id ); void slotInsert(); void slotInsertCellCopy(); void slotRemove(); void slotRename(); /** * Invoked if the popup menu for an embedded document should be opened. */ void popupChildMenu( KoChild*, const QPoint& global_pos ); void slotPopupDeleteChild(); /** * Border popup menu */ void slotPopupAdjustColumn(); void slotPopupAdjustRow(); /** * Scroll @ref #tabBar. */ void slotScrollToFirstTable(); /** * Scroll @ref #tabBar. */ void slotScrollToLeftTable(); /** * Scroll @ref #tabBar. */ void slotScrollToRightTable(); /** * Scroll @ref #tabBar. */ void slotScrollToLastTable(); /** * list from list choose */ void slotItemSelected( int ); void slotListChoosePopupMenu( ); protected slots: void repaintPolygon( const QPointArray& ); void slotChildSelected( KoDocumentChild* ch ); void slotChildUnselected( KoDocumentChild* ); public slots: // Document signals void slotUnselect( KSpreadTable *_table, const QRect& _old ); void slotUpdateView( KSpreadTable *_table ); void slotUpdateView( KSpreadTable *_table, const QRect& ); void slotUpdateHBorder( KSpreadTable *_table ); void slotUpdateVBorder( KSpreadTable *_table ); void slotChangeSelection( KSpreadTable *_table, const QRect &_old, const QRect &_old_marker ); void slotChangeChooseSelection( KSpreadTable *_table, const QRect &_old, const QRect &_new ); void slotAddTable( KSpreadTable *_table ); void slotRemoveChild( KSpreadChild *_child ); void slotUpdateChildGeometry( KSpreadChild *_child ); void slotTableRenamed( KSpreadTable* table, const QString& old_name ); void slotTableHidden( KSpreadTable*_table ); void slotTableShown( KSpreadTable*_table ); void slotTableRemoved( KSpreadTable*_table ); void slotTableActivated( KSpreadTable* table ); void slotRefreshView( ); void slotRefreshLocale(); void extraSpelling(); void spellCheckerReady(); void spellCheckerMisspelling( const QString &, const QStringList &, unsigned int); void spellCheckerCorrected( const QString &, const QString &, unsigned int); void spellCheckerDone( const QString & ); void spellCheckerFinished( ); void startKSpell(); virtual int leftBorder() const; virtual int rightBorder() const; virtual int topBorder() const; virtual int bottomBorder() const; signals: void sig_selectionChanged( KSpreadTable* _table, const QRect& _selection ); void sig_chooseSelectionChanged( KSpreadTable* _table, const QRect& _selection ); protected: // bool eventKeyPressed( QKeyEvent* _event, bool choose ); virtual void keyPressEvent ( QKeyEvent * _ev ); virtual void resizeEvent( QResizeEvent *_ev ); virtual QWMatrix matrix() const; /** * Activates the formula editor for the current cell. * This function is usually called if the user presses * a button in the formula toolbar. */ void activateFormulaEditor(); virtual void updateReadWrite( bool readwrite ); virtual void guiActivateEvent( KParts::GUIActivateEvent *ev ); private: // GUI stuff QButton* newIconButton( const char *_file, bool _kbutton = false, QWidget *_parent = 0L ); QScrollBar *m_pHorzScrollBar; QScrollBar *m_pVertScrollBar; KSpreadCanvas *m_pCanvas; KSpreadVBorder *m_pVBorderWidget; KSpreadHBorder *m_pHBorderWidget; KSpreadEditWidget *m_pEditWidget; QWidget *m_pFrame; QFrame *m_pToolWidget; QButton *m_pTabBarFirst; QButton *m_pTabBarLeft; QButton *m_pTabBarRight; QButton *m_pTabBarLast; QButton *m_pOkButton; QButton *m_pCancelButton; KSpreadTabBar *m_pTabBar; //QLabel *m_pPosWidget; KSpreadLocationEditWidget *m_pPosWidget; KToggleAction* m_bold; KToggleAction* m_italic; KToggleAction* m_underline; KToggleAction* m_strikeOut; KToggleAction* m_percent; KAction* m_precplus; KAction* m_precminus; KToggleAction* m_money; KToggleAction* m_alignLeft; KToggleAction* m_alignCenter; KToggleAction* m_alignRight; KToggleAction* m_alignTop; KToggleAction* m_alignMiddle; KToggleAction* m_alignBottom; KAction* m_transform; KAction* m_copy; KAction* m_paste; KAction* m_cut; KAction* m_specialPaste; KAction* m_delete; KAction* m_clearText; KAction* m_clearComment; KAction* m_clearValidity; KAction* m_clearConditional; KAction* m_recalc_workbook; KAction* m_recalc_worksheet; KAction* m_adjust; KAction* m_editCell; KAction* m_undo; KAction* m_redo; KAction* m_paperLayout; KAction* m_insertFromDatabase; KAction* m_insertFromTextfile; KAction* m_insertFromClipboard; KAction* m_insertTable; KAction* m_removeTable; KAction* m_renameTable; KAction* m_nextTable; KAction* m_prevTable; KAction* m_firstTable; KAction* m_lastTable; KAction* m_editGlobalScripts; KAction* m_editLocalScripts; KAction* m_reloadScripts; KAction* m_conditional; KAction* m_validity; KAction* m_sort; KAction* m_goalSeek; KAction* m_consolidate; KAction* m_help; KAction* m_insertCellCopy; KToggleAction* m_multiRow; KFontAction* m_selectFont; KFontSizeAction* m_selectFontSize; KAction* m_deleteColumn; KAction* m_hideColumn; KAction* m_showColumn; KAction* m_showSelColumns; KAction* m_insertColumn; KAction* m_deleteRow; KAction* m_insertRow; KAction* m_hideRow; KAction* m_showRow; KAction* m_showSelRows; KSelectAction* m_formulaSelection; KAction* m_sortDec; KAction* m_sortInc; TKSelectColorAction* m_textColor; TKSelectColorAction* m_bgColor; KAction* m_cellLayout; KAction* m_hideTable; KAction* m_showTable; KAction* m_borderLeft; KAction* m_borderRight; KAction* m_borderTop; KAction* m_borderBottom; KAction* m_borderAll; KAction* m_borderOutline; KAction* m_borderRemove; TKSelectColorAction* m_borderColor; KAction* m_tableFormat; // KAction* m_oszi; KAction* m_autoSum; KToggleAction* m_showPageBorders; KActionMenu* m_scripts; KAction* m_default; KAction* m_areaName; KAction* m_showArea; KAction* m_resizeRow; KAction* m_resizeColumn; KAction* m_fontSizeUp; KAction* m_fontSizeDown; KAction* m_upper; KAction* m_lower; KAction* m_equalizeRow; KAction* m_equalizeColumn; KAction* m_preference; KAction* m_firstLetterUpper; KToggleAction* m_verticalText; KAction* m_addModifyComment; KAction* m_removeComment; KAction* m_insertCell; KAction* m_removeCell; KAction* m_changeAngle; KAction* m_mergeCell; KAction* m_dissociateCell; KAction* m_gotoCell; KAction* m_increaseIndent; KAction* m_decreaseIndent; KAction* m_sortList; KAction* m_spellChecking; KAction* m_insertChartFrame; KToggleAction* m_menuCalcMin; KToggleAction* m_menuCalcMax; KToggleAction* m_menuCalcAverage; KToggleAction* m_menuCalcCount; KToggleAction* m_menuCalcSum; KToggleAction* m_menuCalcNone; KoPartSelectAction *m_insertPart; // Spell-checking QStringList m_ignoreWord; struct { KSpreadSpell * kspell; KSpreadTable * firstSpellTable; KSpreadTable * currentSpellTable; KSpreadCell * currentCell; unsigned int spellCurrCellX; unsigned int spellCurrCellY; unsigned int spellStartCellX; unsigned int spellStartCellY; unsigned int spellEndCellX; unsigned int spellEndCellY; bool spellCheckSelection; QStringList ignoreWord; // KMacroCommand * macroCmdSpellCheck; } m_spell; bool spellSwitchToOtherTable(); void spellCleanup(); /** * Pointer to the last popup menu. * Since only one popup menu can be opened at once, its pointer is stored here. * Delete the old one before you store a pointer to anotheron here. * May be 0L. */ QPopupMenu *m_pPopupMenu; int m_popupMenuFirstToolId; QPopupMenu *m_pPopupRow; QPopupMenu *m_pPopupColumn; /** * Used for embedded children. */ QPopupMenu* m_popupChild; /** * used for list of choose */ QPopupMenu* m_popupListChoose; /** * Holds a pointer of the child for which the popup menu has been opened. */ KSpreadChild* m_popupChildObject; /** * This DCOP object represents the view. */ DCOPObject* m_dcop; /** * Tells whether the user modfied the current cell. * Some key events are passed to the @ref EditWindow. When this flag is set and you * want to leave the cell with the marker then you must first save the new text * in the cell before moving the marker. */ bool m_bEditDirtyFlag; /** * The active KSpreadTable. This table has the input focus. It may be 0L, too. */ KSpreadTable* m_pTable; KSpreadDoc *m_pDoc; /** * Flags that indicate whether we should display additional * GUI stuff like rulers and scrollbars. * * @see #showGUI */ bool m_bShowGUI; /** * If @ref #updateEditWidget is called it changes some KToggleActions. * That causes them to emit a signal. If this lock is TRUE, then these * signals are ignored. */ bool m_toolbarLock; struct ToolEntry { QString command; KDataToolInfo info; }; QPtrList m_lstTools; static KSpreadScripts *m_pGlobalScriptsDialog; //used to allow to refresh menubar //otherwise kspread crash when I try to refresh menubar //when I start kspread bool m_bLoading; /** * Holds a guarded pointer to the transformation toolbox. */ QGuardedPtr m_transformToolBox; /** * Find and Replace context. We remember the options and the strings used * previously. */ long m_findOptions; QStringList m_findStrings; QStringList m_replaceStrings; KStatusBarLabel* m_sbCalcLabel; /* helper functions */ void initializeCalcActions(); void initializeInsertActions(); void initializeEditActions(); void initializeAreaOperationActions(); void initializeGlobalOperationActions(); void initializeCellOperationActions(); void initializeCellPropertyActions(); void initializeTextFormatActions(); void initializeTextLayoutActions(); void initializeTextPropertyActions(); void initializeTableActions(); void initializeSpellChecking(); void initializeRowColumnActions(); void initializeBorderActions(); }; #endif Index: trunk/koffice/kspread/kspread_canvas.h =================================================================== --- trunk/koffice/kspread/kspread_canvas.h (revision 152991) +++ trunk/koffice/kspread/kspread_canvas.h (revision 152992) @@ -1,592 +1,599 @@ #ifndef __kspread_canvas_h__ #define __kspread_canvas_h__ #include #include #include #include #include class KSpreadEditWidget; class KSpreadCanvas; class KSpreadHBorder; class KSpreadVBorder; class KSpreadTable; class KSpreadDoc; class KSpreadPoint; class KSpreadRange; class KSpreadCellEditor; class KSpreadCell; class QWidget; class QTimer; class QPainter; class QLabel; #define YBORDER_WIDTH 50 #define XBORDER_HEIGHT 20 /** * A widget that allows the user to enter an arbitrary * cell location to goto or cell selection to highlight */ class KSpreadLocationEditWidget : public QLineEdit { Q_OBJECT public: KSpreadLocationEditWidget( QWidget *_parent, KSpreadView * _canvas ); protected: virtual void keyPressEvent( QKeyEvent * _ev ); private: KSpreadView * m_pView; signals: void gotoLocation( int, int ); }; /** * The widget that appears above the table and allows to * edit the cells content. */ class KSpreadEditWidget : public QLineEdit { Q_OBJECT public: KSpreadEditWidget( QWidget *parent, KSpreadCanvas *canvas, QButton *cancelButton, QButton *okButton); virtual void setText( const QString& t ); // Go into edit mode (enable the buttons) void setEditMode( bool mode ); void showEditWidget(bool _show); public slots: void slotAbortEdit(); void slotDoneEdit(); protected: virtual void keyPressEvent ( QKeyEvent* _ev ); virtual void focusOutEvent( QFocusEvent* ev ); private: QButton* m_pCancelButton; QButton* m_pOkButton; KSpreadCanvas* m_pCanvas; }; /** * The canvas builds a part of the GUI of KSpread. * It contains the borders, scrollbars, * editwidget and of course it displays the table. * Especially most of the user interface logic is implemented here. * That means that this class knows what to do when a key is pressed * or if the mouse button was clicked. */ class KSpreadCanvas : public QWidget { friend class KSpreadHBorder; friend class KSpreadVBorder; friend class KSpreadView; Q_OBJECT public: /** * The current action associated with the mouse. * Default is 'NoAction'. */ enum MouseActions { NoAction = 0, Mark = 1, ResizeCell = 2, AutoFill = 3 }; enum EditorType { CellEditor, FormulaEditor, EditWidget }; KSpreadCanvas( QWidget *_parent, KSpreadView *_view, KSpreadDoc* _doc ); /** * Called from @ref KSpreadView to complete the construction. Has to * be called before any other method on this object may be invoced. */ void init(); KSpreadCellEditor* editor() { return m_pEditor ; } // ###### Torben: Many of these functions are not used or can be made private QPoint chooseMarker() const { return QPoint( m_i_chooseMarkerColumn, m_i_chooseMarkerRow ); } int chooseMarkerColumn() const { return m_i_chooseMarkerColumn; } int chooseMarkerRow() const { return m_i_chooseMarkerRow; } /** * Sets the marker and redraws it if it is visible. * It does not scroll the canvas. If you want to do that, use * @ref #chooseGotoLocation. * * In addition it does not handel selection * of multiple cells. After calling setChooseMarker() the selection will * consist of the single cell given by @p p. */ void setChooseMarker( const QPoint& p ); /** * Internal. DONT USE. */ void setChooseMarkerColumn( int _c ) { m_i_chooseMarkerColumn = _c; } /** * Internal. DONT USE. */ void setChooseMarkerRow( int _r ) { m_i_chooseMarkerRow = _r; } /** * Move the choose selection. That may include switching the table. * The canvas is scrolled to the appropriate position if needed. * * @param make_select determines wether this move if the marker is part of a * selection, that means: The user holds the shift key and * moves the cursor keys. */ void chooseGotoLocation( int x, int y, KSpreadTable* table = 0, bool make_select = FALSE ); /** * Internal. DONT USE. */ void showChooseMarker(){if(choose_visible==true) {return;} drawChooseMarker();choose_visible=true;} /** * Internal. DONT USE. */ void hideChooseMarker(){if(choose_visible==false) {return;} drawChooseMarker();choose_visible=false;} /** * Internal. DONT USE. */ bool isChooseMarkerVisible() const { return choose_visible; } /** * Called from @ref KSpreadView::slotChangeChooseSelection to * draw the selection with a rubber band. */ void updateChooseMarker( const QRect& _old, const QRect& _new ); /** * If the user chooses some cells during editing a formula, then * this function returns the length of the textual representation. * For example the user selects "Table1!A1:B2" then this function * returns 12. */ int chooseTextLen() const { return length_namecell; } QPoint marker() const; int markerColumn() const; int markerRow() const; void updateCellRect( const QRect &_rect ); void updateSelection( const QRect& _old, const QRect& _old_marker ); const QPen& defaultGridPen() { return m_defaultGridPen; } double zoom() { return m_pView->zoom(); } /** * Returns the width of the columns before the current screen */ int xOffset() { return m_iXOffset; } /** * Returns the height of the rows before the current screen */ int yOffset() { return m_iYOffset; } const KSpreadTable* activeTable() const; KSpreadTable* activeTable(); KSpreadTable* findTable( const QString& _name ); /** * A convenience function. */ void gotoLocation( const KSpreadRange & _range ); /** * A convenience function. */ void gotoLocation( const KSpreadPoint& _cell ); /** * Move the cursor to the specified cell. This may include switching * the table. In addition @ref #KSpreadView::updateEditWidget is called. * * @param make_select determines wether this move of the marker is part of a * selection, that means: The user holds the shift key and * moves the cursor keys. In this case the selection is * updated accordingly. */ void gotoLocation( int x, int y, KSpreadTable* table = 0, bool make_select = FALSE,bool move_into_area=false,bool keypress=false); /** * Chooses the correct @ref #EditorType by looking at * the current cells value. By default CellEditor is chosen. */ void createEditor(); void createEditor( EditorType type, bool addFocus=true ); /** * Deletes the current cell editor. * * @see #createEditor * @see #editor * @param saveChanges if true, the edited text is stored in the cell. * if false, the changes are discarded. */ void deleteEditor( bool saveChanges ); /** * Called from @ref KSpreadEditWidget and KSpreadCellEditor * if they loose the focus becuase the user started a "choose selection". * This is done because the editor wants to get its focus back afterwards. * But somehow KSpreadCanvas must know whether the EditWidget or the CellEditor * lost the focus when the user clicked on the canvas. */ void setLastEditorWithFocus( EditorType type ) { m_focusEditorType = type; } /** * Switches to choose mode and sets the inital selection to the * position returned by @ref #marker. */ void startChoose(); /** * Switches to choose mode and sets the inital @p selection. */ void startChoose( const QRect& selection ); void endChoose(); /** * Adjust a area in height and width */ void adjustArea(bool makeUndo=true); void equalizeRow(); void equalizeColumn(); void updatePosWidget(); void closeEditor(); // Created by the view since it's layout is managed there, // but is in fact a sibling of the canvas, which needs to know about it. void setEditWidget( KSpreadEditWidget * ew ) { m_pEditWidget = ew; } KSpreadView* view() { return m_pView; } KSpreadDoc* doc() { return m_pDoc; } /** * Find support. */ void find( const QPoint &_marker, QString _find, long options ); /** * Find'n'Replace support. */ void replace( const QPoint &_marker, QString _find, QString _replace, long options ); virtual bool focusNextPrevChild( bool ); public slots: void slotScrollVert( int _value ); void slotScrollHorz( int _value ); void slotMaxColumn( int _max_column ); void slotMaxRow( int _max_row ); // Connected to KoFind/KoReplace by KSpreadTable during a search and replace void highlight( const QString &text, int matchingIndex, int matchedLength, const QRect &cellRect ); void replace( const QString &newText, int index, int replacedLength,int searchWordLenght, const QRect &cellRect ); protected: virtual void keyPressEvent ( QKeyEvent* _ev ); virtual void paintEvent ( QPaintEvent* _ev ); virtual void mousePressEvent( QMouseEvent* _ev ); virtual void mouseReleaseEvent( QMouseEvent* _ev ); virtual void mouseMoveEvent( QMouseEvent* _ev ); virtual void mouseDoubleClickEvent( QMouseEvent* ); virtual void wheelEvent( QWheelEvent* ); virtual void focusInEvent( QFocusEvent* ); virtual void focusOutEvent( QFocusEvent* ); virtual void resizeEvent( QResizeEvent * _ev ); private slots: void doAutoScroll(); private: virtual void chooseMousePressEvent( QMouseEvent* _ev ); virtual void chooseMouseReleaseEvent( QMouseEvent* _ev ); virtual void chooseMouseMoveEvent( QMouseEvent* _ev ); virtual bool eventFilter( QObject *o, QEvent *e ); KSpreadHBorder* hBorderWidget(); KSpreadVBorder* vBorderWidget(); QScrollBar* horzScrollBar(); QScrollBar* vertScrollBar(); KSpreadEditWidget* editWidget() { return m_pEditWidget; } void drawChooseMarker( ); void drawChooseMarker( const QRect& ); /** * @see #setLastEditorWithFocus */ EditorType lastEditorWithFocus() const { return m_focusEditorType; } /** * Hides the marker. Hiding it multiple times means that it has to be shown ( using @ref #showMarker ) multiple times * to become visible again. This function is optimized since it does not create a new painter. */ // void hideMarker( QPainter& ); // void showMarker( QPainter& ); // void drawMarker( QPainter * _painter = 0L ); bool choose_visible; int length_namecell; int length_text; KSpreadView *m_pView; KSpreadDoc* m_pDoc; QTimer * m_scrollTimer; /** * If the user is dragging around with the mouse then this tells us what he is doing. * The user may want to mark cells or he started in the lower right corner * of the marker which is something special. The values for the 2 above * methods are called 'Mark' and 'ResizeCell' or 'AutoFill' depending * on the mouse button used. By default this variable holds * the value 'NoAction'. */ MouseActions m_eMouseAction; /** * Used to indicate whether the user started drawing a rubber band rectangle. */ bool m_bGeometryStarted; QPoint m_ptGeometryStart; QPoint m_ptGeometryEnd; /** * The column in which a mouse drag started. */ int m_iMouseStartColumn; /** * The row in which a mouse drag started. */ int m_iMouseStartRow; /** * Tells whether the user selected more than one cell. * If the user presses the left mouse button and if he marks more * than one cell until he releases the button again, then this flag * is set. If this flag is set, then one should repaint all visible * cells once the button is released. */ bool m_bMouseMadeSelection; /** * True when the mouse button is pressed */ bool m_bMousePressed; /** * If we use the lower right corner of the marker to start autofilling, then this * rectangle conatins all cells that were already marker when the user started * to mark the rectangle which he wants to become autofilled. * * @see #mousePressEvent * @see #mouseReleeaseEvent */ QRect m_rctAutoFillSrc; /** * If the mouse is over some anchor ( in the sense of HTML anchors ) * then this one is stored here. */ QString m_strAnchor; float m_fZoom; /** * Non visible range left from current screen * Example: * If the first visible column is 'E', then m_iXOffset stores * the width of the invisible columns 'A' to 'D'. */ int m_iXOffset; /** * Non visible range on top of the current screen * Example: * If the first visible row is '5', then m_iYOffset stores * the height of the invisible rows '1' to '4'. */ int m_iYOffset; KSpreadLocationEditWidget *m_pPosWidget; KSpreadEditWidget *m_pEditWidget; KSpreadCellEditor *m_pEditor; /** * Used to draw the grey grid that is usually only visible on the * screen, but not by printing on paper. */ QPen m_defaultGridPen; // int m_iMarkerColumn; // int m_iMarkerRow; /** * A value of 1 means that it is visible, every lower value means it is * made invisible multiple times. * * @see #hideMarker * @see #showMarker */ // int m_iMarkerVisible; int m_i_chooseMarkerRow; int m_i_chooseMarkerColumn; /** * Is true if the user is to choose a cell. * * @see #startChoose * @see #endChoose * @see KSpreadAssistant2 */ bool m_bChoose; /** * If a choose selection is started (@ref #startChoose) the current * table is saved here. */ KSpreadTable* m_chooseStartTable; // int m_choosePos; /** * @see #setLastEditorWithFocus * @see #lastEditorWithFocus */ EditorType m_focusEditorType; private: /** * Small helper function to take a rect representing a selection onscreen and * extend it one cell in every direction (taking into account hidden columns * and rows) */ void ExtendRectBorder(QRect& area); void PaintRegion(QRect paintRegion, QRect viewRegion, QPainter &painter); + bool formatKeyPress( QKeyEvent * _ev ); + double getDouble( KSpreadCell * cell ); + void convertToDouble( KSpreadCell * cell ); + void convertToPercent( KSpreadCell * cell ); + void convertToMoney( KSpreadCell * cell ); + void convertToTime( KSpreadCell * cell ); + void convertToDate( KSpreadCell * cell ); }; /** */ class KSpreadHBorder : public QWidget { Q_OBJECT public: KSpreadHBorder( QWidget *_parent, KSpreadCanvas *_canvas, KSpreadView *_view ); int markerColumn() { return m_iSelectionAnchor; } void resizeColumn( int resize, int nb = -1, bool makeUndo=true ); void adjustColumn( int _col = -1, bool makeUndo=true ); void equalizeColumn( int resize ); protected: virtual void paintEvent ( QPaintEvent* _ev ); virtual void mousePressEvent( QMouseEvent* _ev ); virtual void mouseReleaseEvent( QMouseEvent* _ev ); virtual void mouseDoubleClickEvent( QMouseEvent* _ev ); virtual void mouseMoveEvent( QMouseEvent* _ev ); virtual void wheelEvent( QWheelEvent* ); void paintSizeIndicator( int mouseX, bool firstTime ); KSpreadCanvas *m_pCanvas; KSpreadView *m_pView; /** * Flag that inidicates whether the user wants to mark columns. * The user may mark columns by dragging the mouse around in th XBorder widget. * If he is doing that right now, this flag is TRUE. Mention that the user may * also resize columns by dragging the mouse. This case is not covered by this flag. */ bool m_bSelection; /** * The column over which the user pressed the mouse button. * If the user marks columns in the XBorder widget, then this is the initial * column on which he pressed the mouse button. */ int m_iSelectionAnchor; /** * Flag that indicates whether the user resizes a column * The user may resize columns by dragging the mouse around in the HBorder widget. * If he is doing that right now, this flag is TRUE. */ bool m_bResize; /** * The column over which the user pressed the mouse button. * The user may resize columns by dragging the mouse around the XBorder widget. * This is the column over which he pressed the mouse button. This column is going * to be resized. */ int m_iResizedColumn; /** * Last position of the mouse, when resizing. */ int m_iResizePos; /** * The label used for showing the current size, when resizing */ QLabel *m_lSize; }; /** */ class KSpreadVBorder : public QWidget { Q_OBJECT public: KSpreadVBorder( QWidget *_parent, KSpreadCanvas *_canvas, KSpreadView *_view ); int markerRow() { return m_iSelectionAnchor; } void resizeRow( int resize, int nb = -1, bool makeUndo=true ); void adjustRow( int _row = -1, bool makeUndo=true ); void equalizeRow( int resize ); protected: virtual void paintEvent ( QPaintEvent* _ev ); virtual void mousePressEvent( QMouseEvent* _ev ); virtual void mouseReleaseEvent( QMouseEvent* _ev ); virtual void mouseMoveEvent( QMouseEvent* _ev ); virtual void mouseDoubleClickEvent( QMouseEvent* _ev ); virtual void wheelEvent( QWheelEvent* ); void paintSizeIndicator( int mouseY, bool firstTime ); KSpreadCanvas *m_pCanvas; KSpreadView *m_pView; bool m_bSelection; int m_iSelectionAnchor; bool m_bResize; int m_iResizedRow; int m_iResizePos; /** * The label used for showing the current size, when resizing */ QLabel *m_lSize; }; class KSpreadToolTip : public QToolTip { public: KSpreadToolTip( KSpreadCanvas* canvas ); protected: /** * @reimp */ void maybeTip( const QPoint& p ); private: KSpreadCanvas* m_canvas; }; #endif Index: trunk/koffice/kspread/TODO =================================================================== --- trunk/koffice/kspread/TODO (revision 152991) +++ trunk/koffice/kspread/TODO (revision 152992) @@ -1,192 +1,189 @@ Please put your name in "(...)" to the bug/feature you work on or you want to work on. For bugs: look into the KBugBuster if somebody else is working on it.d Others bugs not in BT system (Report by - taken by): - Clicking into canvas causes to much flickering if many items (especially multirow cells) are in visible rect - MultiRow cells will only be drawn if obscuring is forced! - Merged cells are always obscured by others even if something is in there ---(John) - I'm not convinced this is a bug. If you merge a group of cells where more than one has text in it, there's no good consistant way to "merge" the data. Currently, the top-left corner cell's data will become the large merged cell's data. Maybe that isn't ideal but what is a better solution? Other things: (please add the things you are working on!) - Zoom - inserting data from text files - inserting formated data (csv) from clipboard - "Freeze/Unfreeze Panes", started but had some problems caused by the scrollbars, it works, but not very nice (not commited (Norbert)) - AutoFormat (already exists in a very limited way: Format -> table style) - Script, Script-Editor (like VBA in Excel) - Tools->Auditing: Trace Precedents Trace Dependants Trace Error Remove all arrows - Printing: - expand selection to page - fit selection to page - print selection only - Sheet layout: - Move sheet properties to seperate dialog (they are currently part of KSpread config dialog) - Scenerios - Locked areas (for formulas with a matrix as result) - Multible Operations (in Excel: "Data"->"Table") - more chart types - much more formulas (financial,...) - Scrollbar that supports jumping one row/column forward or back - Named areas with something like "=x+5" ("='x'+5" works already) - other bug fixes (everybody, every time) ********* * Taken: ********* John ======= - Reimplimenting the "obscuring" structure of cells -- there is currently no way to keep track of a cell being obscured by more than one other cell. - various painting issues. Cell borders aren't always painted/cleared correctly and the entire canvas painting routines are far too complex. - Pulling the cell 'result' into it's own class for future enhancements to calculation precision, new datatypes (matrix?), and cleaner code (KSpreadCell is absolutely HUGE) -- I haven't started on this and may not for several weeks so let me know if you want to take this. Philipp ======= - printing enhancements (printing a selection only, ...) (Philipp) - Filter, Autofilter (Philipp, but will take long, haven't started yet) - Performance improvements at end of ranges - last column/row (Philipp, started) - Support "unlimited" columns/rows, unlimited means a reasonable defined value (Philipp, concept finished, will include after beta1) Norbert ======= - insert data from databases (Norbert - almost done) - Styles ( after 1.2 cause it requires bigger changes than expected ) -- implement more Excel shortcuts like CTRL+Shift+!, *, ^, ... (Norbert - almost done) +- implement more Excel shortcuts like CTRL+Shift+!, *, ^, ... (done) (see Todo-list below) - GoalSeek ( done ) Ariya ===== - more "Related Functions" in function help/desc text - add more functions (helps welcomed!) - add support for matrices operation - improve function compatibility with MS Excel - more choices for Data -> Consolidate - dBASE import filter (Done, need some improvements) - improve/fix MS Excel import filter - start working on MS Excel export filter (with 'wildfox') - ported export filter (CSV,html) not to use KoDocument anymore *************************************************************************************** Explanations to features: ========================= Named areas: I would like to ask one thing about "Named areas". In Excel you can assign names to cells (you can do this in KSpread, too) like this: A B 1 45 46 2 x=A1, y= B1 Now, I would like to put "=x+y" in A2. This works with Excel but not in KSpread. But it is an important feature (I was told :-) So if you evaluate "=x+y", 'x' has be replaced by "A1" and 'y' by "B1" TODO-List: ---------- Please everyone working on KSpread: Get yourself a copy of Excel 97 or 2000 and create a really big sheet, and I mean really big and insert Graphs and lots of dependencies and regressions etc. use external add-ins if you have any and real time links. Make links between sheets and then see how well Excel behaves. 1. UNDERSTAND that putting a table->recalc() or table->recalc(true) in your code is an abosolute NO-NO! Complex spreadsheets with possible heavy mathematical calculations via dll/so add-ins as well as real time feeds will not be managable if you do not painstakingly check wether table->getAutoCalc() is true. 2. Learn to understand that without the following short cut actions you are lost ( try to scroll down a list of 10,000 obersvations ...not using CTRL Down for example) CTRL Up/Down/Left/Right CTRL Shift Up/Down/Left/Right CTRL Home/End CTRL Shift Home/End Shift F9 versus F9 Let's try to get them working well in Kspread as well. I tried my hand at it but wasn't able to get them to be efficient. -Furthermore try stuff like CTRL + SHIFT + # or @ or ! in Excel -This is neat stuff and makes one's life so much more enjoyable. - 3. Familiarize yourself with the concept of array formulas and why they are necessary (area protection, partial argument evaluation) Who would be willing to implement them? This will be an absolute must if we want to make progress on the mathematical/financial/statistical function side of things. I would be willing to implement a miriad of these functions but I believe doing that without having array formulae first will be a big mistake. (In case you wonder why I feel so strongly about these things: I am a professional user of Excel. I eat, sleap and work with Excel on my trading desk on Wall-Street.) Bernd Improvement : ------------- - Add zoom (Bernd: Yes, this is important. KSpread is much to cluttered up at this point. you can hardly do any real work with it even on a 17inch screen. Torben? Please?) -create a script editor for execute script (Use KWrite) Bug fix : --------- -and also bug fix :) Torbens TODO-List: ------------------ - Write-Protect cells Index: trunk/koffice/kspread/kspread_canvas.cc =================================================================== --- trunk/koffice/kspread/kspread_canvas.cc (revision 152991) +++ trunk/koffice/kspread/kspread_canvas.cc (revision 152992) @@ -1,4089 +1,4501 @@ #include "kspread_canvas.h" #include "kspread_util.h" #include "kspread_editors.h" #include "kspread_map.h" #include "kspread_undo.h" #include "kspread_doc.h" #include #include #include #include #include #include #include #include #include #include #include KSpreadLocationEditWidget::KSpreadLocationEditWidget( QWidget * _parent, KSpreadView * _view ) : QLineEdit( _parent, "KSpreadLocationEditWidget" ), m_pView(_view) { m_pView = _view; } void KSpreadLocationEditWidget::keyPressEvent( QKeyEvent * _ev ) { // Do not handle special keys and accelerators. This is // done by QLineEdit. if ( _ev->state() & ( Qt::AltButton | Qt::ControlButton ) ) { QLineEdit::keyPressEvent( _ev ); // Never allow that keys are passed on to the parent. _ev->accept(); return; } // Handle some special keys here. Eve switch( _ev->key() ) { case Key_Return: case Key_Enter: { QString tmp; QString ltext = text(); tmp = ltext.lower(); QValueList::Iterator it; QValueList area = m_pView->doc()->listArea(); for ( it = area.begin(); it != area.end(); ++it ) { if ((*it).ref_name == tmp) { QString tmp; tmp = (*it).table_name; tmp += "!"; tmp += util_rangeName((*it).rect); m_pView->canvasWidget()->gotoLocation( KSpreadRange(tmp, m_pView->doc()->map())); return; } } int pos; // Set the cell component to uppercase: // Table1!a1 -> Table1!A2 pos = ltext.find('!'); if( pos !=- 1 ) tmp = ltext.left(pos)+ltext.mid(pos).upper(); else tmp = ltext.upper(); // Selection entered in location widget if ( ltext.contains( ':' ) ) m_pView->canvasWidget()->gotoLocation( KSpreadRange( tmp, m_pView->doc()->map() ) ); // Location entered in location widget else { KSpreadPoint point( tmp, m_pView->doc()->map()); bool validName = true; for (unsigned int i = 0; i < ltext.length(); ++i) { if (!ltext[i].isLetter()) { validName = false; break; } } if ( !point.isValid() && validName) { QRect rect( m_pView->activeTable()->selectionRect() ); KSpreadTable * t = m_pView->activeTable(); if ( rect.left() == 0 || rect.top() == 0 || rect.right() == 0 || rect.bottom() == 0 ) { rect.setCoords( t->marker().x(), t->marker().y(), t->marker().x(), t->marker().y() ); } // set area name on current selection/cell m_pView->doc()->addAreaName(rect, ltext.lower(), t->tableName()); } if (!validName) m_pView->canvasWidget()->gotoLocation( point ); } // Set the focus back on the canvas. m_pView->canvasWidget()->setFocus(); _ev->accept(); } break; // Escape pressed, restore original value case Key_Escape: // #### Torben says: This is duplicated code. Bad. if ( m_pView->activeTable()->selectionRect().left() == 0 ) { setText( util_encodeColumnLabelText( m_pView->canvasWidget()->markerColumn() ) + QString::number( m_pView->canvasWidget()->markerRow() ) ); } else { setText( util_encodeColumnLabelText( m_pView->activeTable()->selectionRect().left() ) + QString::number( m_pView->activeTable()->selectionRect().top() ) + ":" + util_encodeColumnLabelText( m_pView->activeTable()->selectionRect().right() ) + QString::number( m_pView->activeTable()->selectionRect().bottom() ) ); } m_pView->canvasWidget()->setFocus(); _ev->accept(); break; default: QLineEdit::keyPressEvent( _ev ); // Never allow that keys are passed on to the parent. _ev->accept(); } } /**************************************************************** * * KSpreadEditWidget * The line-editor that appears above the table and allows to * edit the cells content. * ****************************************************************/ KSpreadEditWidget::KSpreadEditWidget( QWidget *_parent, KSpreadCanvas *_canvas, QButton *cancelButton, QButton *okButton ) : QLineEdit( _parent, "KSpreadEditWidget" ) { m_pCanvas = _canvas; // Those buttons are created by the caller, so that they are inserted // properly in the layout - but they are then managed here. m_pCancelButton = cancelButton; m_pOkButton = okButton; if ( !m_pCanvas->doc()->isReadWrite() ) setEnabled( false ); else { QObject::connect( m_pCancelButton, SIGNAL( clicked() ), this, SLOT( slotAbortEdit() ) ); QObject::connect( m_pOkButton, SIGNAL( clicked() ), this, SLOT( slotDoneEdit() ) ); } setEditMode( false ); // disable buttons } void KSpreadEditWidget::showEditWidget(bool _show) { if(_show) { m_pCancelButton->show(); m_pOkButton->show(); show(); } else { m_pCancelButton->hide(); m_pOkButton->hide(); hide(); } } void KSpreadEditWidget::slotAbortEdit() { m_pCanvas->deleteEditor( false /*discard changes*/ ); // will take care of the buttons } void KSpreadEditWidget::slotDoneEdit() { m_pCanvas->deleteEditor( true /*keep changes*/ ); // will take care of the buttons } void KSpreadEditWidget::keyPressEvent ( QKeyEvent* _ev ) { // Dont handle special keys and accelerators if ( _ev->state() & ( Qt::AltButton | Qt::ControlButton ) ) { QLineEdit::keyPressEvent( _ev ); return; } if ( !m_pCanvas->doc()->isReadWrite() ) return; if ( !m_pCanvas->editor() ) { // Start editing the current cell m_pCanvas->createEditor( KSpreadCanvas::CellEditor,false ); } KSpreadTextEditor* cellEditor = (KSpreadTextEditor*) m_pCanvas->editor(); switch ( _ev->key() ) { case Key_Down: case Key_Up: case Key_Return: case Key_Enter: cellEditor->setText( text()); // Don't allow to start a chooser when pressing the arrow keys // in this widget, since only up and down would work anyway. // This is why we call slotDoneEdit now, instead of sending // to the canvas. //QApplication::sendEvent( m_pCanvas, _ev ); slotDoneEdit(); m_pCanvas->view()->updateEditWidget(); _ev->accept(); break; case Key_F2: cellEditor->setFocus(); cellEditor->setText( text()); cellEditor->setCursorPosition(cursorPosition()); break; default: QLineEdit::keyPressEvent( _ev ); setFocus(); cellEditor->blockCheckChoose( TRUE ); cellEditor->setText( text() ); cellEditor->blockCheckChoose( FALSE ); cellEditor->setCursorPosition( cursorPosition() ); } } void KSpreadEditWidget::setEditMode( bool mode ) { m_pCancelButton->setEnabled(mode); m_pOkButton->setEnabled(mode); } void KSpreadEditWidget::focusOutEvent( QFocusEvent* ev ) { //kdDebug(36001) << "EditWidget lost focus" << endl; // See comment about setLastEditorWithFocus m_pCanvas->setLastEditorWithFocus( KSpreadCanvas::EditWidget ); QLineEdit::focusOutEvent( ev ); } void KSpreadEditWidget::setText( const QString& t ) { if ( t == text() ) // Why this? (David) return; QLineEdit::setText( t ); } /**************************************************************** * * KSpreadCanvas * ****************************************************************/ KSpreadCanvas::KSpreadCanvas( QWidget *_parent, KSpreadView *_view, KSpreadDoc* _doc ) : QWidget( _parent, "", /*WNorthWestGravity*/ WStaticContents| WResizeNoErase | WRepaintNoErase ) { length_namecell = 0; m_chooseStartTable = 0; m_pEditor = 0; m_bChoose = FALSE; QWidget::setFocusPolicy( QWidget::StrongFocus ); m_defaultGridPen.setColor( lightGray ); m_defaultGridPen.setWidth( 1 ); m_defaultGridPen.setStyle( SolidLine ); m_iXOffset = 0; m_iYOffset = 0; m_pView = _view; m_pDoc = _doc; // m_eAction = DefaultAction; m_eMouseAction = NoAction; m_bGeometryStarted = false; // m_bEditDirtyFlag = false; //Now built afterwards(David) //m_pEditWidget = m_pView->editWidget(); m_pPosWidget = m_pView->posWidget(); setBackgroundMode( PaletteBase ); setMouseTracking( TRUE ); m_bMousePressed = false; m_scrollTimer = new QTimer( this ); connect (m_scrollTimer, SIGNAL( timeout() ), this, SLOT( doAutoScroll() ) ); choose_visible = false; setFocus(); installEventFilter( this ); (void)new KSpreadToolTip( this ); } bool KSpreadCanvas::eventFilter( QObject *o, QEvent *e ) { if ( !o || !e ) return TRUE; switch ( e->type() ) { case QEvent::AccelOverride: { QKeyEvent * keyev = static_cast(e); if (keyev->key()==Key_Tab && !m_pEditor) { keyPressEvent ( keyev ); return true; } } default: break; } return false; } bool KSpreadCanvas::focusNextPrevChild( bool ) { return TRUE; // Don't allow to go out of the canvas widget by pressing "Tab" } QPoint KSpreadCanvas::marker() const { return activeTable()->marker().topLeft(); } int KSpreadCanvas::markerColumn() const { return activeTable()->marker().left(); } int KSpreadCanvas::markerRow() const { return activeTable()->marker().top(); } void KSpreadCanvas::startChoose() { if ( m_bChoose ) return; // Clear a selection if there is any m_i_chooseMarkerColumn = markerColumn(); m_i_chooseMarkerRow = markerRow(); activeTable()->setChooseRect( QRect( 0, 0, 0, 0 ) ); // It is important to enable this AFTER we set the rect! m_bChoose = TRUE; m_chooseStartTable = activeTable(); } void KSpreadCanvas::startChoose( const QRect& rect ) { activeTable()->setChooseRect( rect ); m_i_chooseMarkerColumn = rect.right(); m_i_chooseMarkerRow = rect.bottom(); // It is important to enable this AFTER we set the rect! m_bChoose = TRUE; m_chooseStartTable = activeTable(); } void KSpreadCanvas::endChoose() { if ( !m_bChoose ) return; activeTable()->setChooseRect( QRect( 0, 0, 0, 0 ) ); //m_pView->setActiveTable( m_chooseStartTable ); KSpreadTable *table=m_pView->doc()->map()->findTable(m_chooseStartTable->tableName()); if(table) table->setActiveTable(); //kdDebug(36001) << "endChoose len=0" << endl; length_namecell = 0; m_bChoose = FALSE; m_chooseStartTable = 0; } KSpreadHBorder* KSpreadCanvas::hBorderWidget() { return m_pView->hBorderWidget(); } KSpreadVBorder* KSpreadCanvas::vBorderWidget() { return m_pView->vBorderWidget(); } QScrollBar* KSpreadCanvas::horzScrollBar() { return m_pView->horzScrollBar(); } QScrollBar* KSpreadCanvas::vertScrollBar() { return m_pView->vertScrollBar(); } KSpreadTable* KSpreadCanvas::findTable( const QString& _name ) { return m_pDoc->map()->findTable( _name ); } const KSpreadTable* KSpreadCanvas::activeTable() const { return m_pView->activeTable(); } KSpreadTable* KSpreadCanvas::activeTable() { return m_pView->activeTable(); } void KSpreadCanvas::gotoLocation( const KSpreadRange & _range ) { if ( !_range.isValid() ) { KMessageBox::error( this, i18n( "Invalid cell reference" ) ); return; } KSpreadTable * table = activeTable(); if ( _range.isTableKnown() ) table = _range.table; if ( !table ) { KMessageBox::error( this, i18n("Unknown table name %1" ).arg( _range.tableName ) ); return; } gotoLocation( _range.range.left(), _range.range.top(), table, false ); gotoLocation( _range.range.right(), _range.range.bottom(), table, true ); } void KSpreadCanvas::gotoLocation( const KSpreadPoint& _cell ) { if ( !_cell.isValid() ) { KMessageBox::error( this, i18n("Invalid cell reference") ); return; } KSpreadTable* table = activeTable(); if ( _cell.isTableKnown() ) table = _cell.table; if ( !table ) { KMessageBox::error( this, i18n("Unknown table name %1").arg( _cell.tableName ) ); return; } gotoLocation( _cell.pos.x(), _cell.pos.y(), table ); } void KSpreadCanvas::gotoLocation( int x, int y, KSpreadTable* table, bool make_select, bool move_into_area, bool keyPress ) { // kdDebug(36001) << "KSpreadCanvas::gotoLocation" << " x=" << x << " y=" << y << // " table=" << table << " make_select=" << (make_select ? "true" : "false" ) << endl; if ( table ) table->setActiveTable(); else table = activeTable(); QRect extraArea; QRect tmpArea; KSpreadCell* cell = table->cellAt( x, y ); if ( cell->isObscured() && cell->isObscuringForced() ) { cell = cell->obscuringCells().getFirst(); int moveX=cell->column(); int moveY=cell->row(); QRect extraCell; extraCell.setCoords( moveX, moveY, moveX+cell->extraXCells(), moveY+cell->extraYCells() ); if( (x - markerColumn()) != 0 && extraCell.contains(QPoint(markerColumn(),markerRow()))) { extraArea.setCoords( markerColumn(), 1, QMIN(KS_colMax, cell->extraXCells()+x-1), KS_rowMax ); if(keyPress) { tmpArea.setCoords( 1, markerRow(), KS_colMax, QMIN(KS_rowMax, cell->extraYCells()+markerRow()) ); if(!extraArea.contains(table->getOldPos().x(), 1) && tmpArea.contains(1, table->getOldPos().y())) { y = table->getOldPos().y(); } else if( extraArea.contains(table->getOldPos().x(), 1) && table->getOldPos().y()==(cell->extraYCells()+y+1)) { y = table->getOldPos().y()-1; } x = cell->extraXCells()+x; } } else if( (y - markerRow()) != 0 && extraCell.contains( QPoint(markerColumn(), markerRow()) ) ) { extraArea.setCoords( 1, markerRow(), KS_colMax, QMIN(KS_rowMax, cell->extraYCells()+y-1) ); tmpArea.setCoords( markerColumn(), 1, QMIN(KS_colMax, cell->extraXCells()+markerColumn()), KS_rowMax ); if(keyPress) { if( !extraArea.contains(1, table->getOldPos().y()) && tmpArea.contains(table->getOldPos().x(), 1)) { x=table->getOldPos().x(); } else if( table->getOldPos().x() == (cell->extraXCells() + markerColumn() + 1)) { x=table->getOldPos().x()-1; } } y=cell->extraYCells()+y; } else { y = moveY; x = moveX; } } else { cell = table->cellAt( table->marker().x(), table->marker().y() ); if ( cell->isForceExtraCells() ) { if(keyPress && (x-markerColumn())!=0) { extraArea.setCoords( markerColumn(), 1, QMIN(KS_colMax, cell->extraXCells() + markerColumn()), KS_rowMax ); tmpArea.setCoords( 1, markerRow(), KS_colMax, QMIN(KS_rowMax, cell->extraYCells()+markerRow()) ); if( !extraArea.contains(QPoint(table->getOldPos().x(),1))&& tmpArea.contains(1,table->getOldPos().y())) y=table->getOldPos().y(); else if( extraArea.contains(table->getOldPos().x(),1)&& table->getOldPos().y()==(cell->extraYCells()+markerRow()+1)) y=table->getOldPos().y()-1; } else if(keyPress && (y-markerRow())!=0 ) { tmpArea.setCoords( markerColumn(), 1, QMIN(KS_colMax, cell->extraXCells()+markerColumn()), KS_rowMax ); extraArea.setCoords( 1, markerRow(), KS_colMax, QMIN(KS_rowMax, cell->extraYCells()+markerRow()) ); if( !extraArea.contains(QPoint(1,table->getOldPos().y()))&&tmpArea.contains(table->getOldPos().x(),1)) x=table->getOldPos().x(); else if( /*extraArea.contains(QPoint(1,table->getOldPos().y()))&&*/ table->getOldPos().x()==(cell->extraXCells()+markerColumn()+1)) x=table->getOldPos().x()-1; } } } cell= table->cellAt( x, y, true /* update scrollbar when necessary */ ); if( cell->isObscured() && cell->isObscuringForced() ) { x = cell->obscuringCells().getFirst()->column(); y = cell->obscuringCells().getFirst()->row(); } int xpos = table->columnPos( x, this ); int ypos = table->rowPos( y, this ); //kdDebug(36001) << "KSpreadCanvas::gotoLocation : zoom=" << zoom() << endl; int minX = (int) (100 * zoom()); // less than that, we scroll int minY = (int) (50 * zoom()); int maxX = (int) (width() - 100 * zoom()); // more than that, we scroll int maxY = (int) (height() - 50 * zoom()); //kdDebug(36001) << "KSpreadCanvas::gotoLocation : height=" << height() << endl; //kdDebug(36001) << "KSpreadCanvas::gotoLocation : width=" << width() << endl; // do we need to scroll left if ( xpos < minX ) horzScrollBar()->setValue( xOffset() + xpos - minX ); //do we need to scroll right else if ( xpos > maxX ) { int horzScrollBarValue; unsigned long horzScrollBarValueMax = table->sizeMaxX() - width(); horzScrollBarValue = xOffset() + xpos - maxX; //We don't want to display any area > KS_colMax widths if ( (unsigned long)horzScrollBarValue > horzScrollBarValueMax ) horzScrollBarValue = horzScrollBarValueMax; horzScrollBar()->setValue( horzScrollBarValue ); } // do we need to scroll up if ( ypos < minY ) vertScrollBar()->setValue( yOffset() + ypos - minY ); // do we need to scroll down else if ( ypos > maxY ) { int vertScrollBarValue; unsigned long vertScrollBarValueMax = table->sizeMaxY() - height(); vertScrollBarValue = yOffset() + ypos - maxY; //We don't want to display any area > KS_rowMax heights if ( (unsigned long)vertScrollBarValue > vertScrollBarValueMax ) vertScrollBarValue = vertScrollBarValueMax; vertScrollBar()->setValue( vertScrollBarValue ); } QRect selection = activeTable()->selectionRect(); if ( !make_select ) { if ( selection.left() != 0 && !move_into_area) activeTable()->setMarker( QPoint( x, y ) ); else if(selection.left() != 0 && move_into_area) activeTable()->setSelection(selection,QPoint( x, y ),this); else activeTable()->setMarker( QPoint( x, y ) ); } else { if ( selection.left() == 0 ) selection.setCoords( markerColumn(), markerRow(), markerColumn(), markerRow() ); if ( markerColumn() == selection.left() ) selection.setLeft( x ); else selection.setRight( x ); if ( markerRow() == selection.top() ) selection.setTop( y ); else selection.setBottom( y ); selection = selection.normalize(); // m_iMarkerColumn = x; // m_iMarkerRow = y; activeTable()->setSelection( selection, QPoint( x, y ) ); } // Perhaps the user is entering a value in the cell. // In this case we may not touch the EditWidget if ( !m_pEditor ) m_pView->updateEditWidget(); updatePosWidget(); } void KSpreadCanvas::chooseGotoLocation( int x, int y, KSpreadTable* table, bool make_select ) { if ( table ) table->setActiveTable( ); else table = activeTable(); KSpreadCell* cell = table->cellAt( x, y, true /* update scrollbar when necessary */ ); if ( cell->isObscured() && cell->isObscuringForced() ) { cell = cell->obscuringCells().getFirst(); int moveX=cell->column(); int moveY=cell->row(); cell = table->cellAt( moveX, moveY, true /* update scrollbar when necessary */ ); QRect extraCell; extraCell.setCoords( moveX, moveY, moveX+cell->extraXCells(), moveY+cell->extraYCells() ); if( (x-chooseMarkerColumn())!=0 && extraCell.contains(chooseMarker())) x=cell->extraXCells()+x; else if((y-chooseMarkerRow())!=0 && extraCell.contains(chooseMarker())) y=cell->extraYCells()+y; else { y = moveY; x = moveX; } } int xpos = table->columnPos( x, this ); int ypos = table->rowPos( y, this ); int minX = (int) (100 * zoom()); // less than that, we scroll int minY = (int) (50 * zoom()); int maxX = (int) (width() - 100 * zoom()); // more than that, we scroll int maxY = (int) (height() - 50 * zoom()); // do we need to scroll left if ( xpos < minX ) horzScrollBar()->setValue( xOffset() + xpos - minX ); //do we need to scroll right else if ( xpos > maxX ) { int horzScrollBarValue; int horzScrollBarValueMax = table->sizeMaxX() - width(); horzScrollBarValue = xOffset() + xpos - maxX; //We don't want to display any area > KS_colMax value if ( horzScrollBarValue > horzScrollBarValueMax ) horzScrollBarValue = horzScrollBarValueMax; horzScrollBar()->setValue( horzScrollBarValue ); } // do we need to scroll up if ( ypos < minY ) vertScrollBar()->setValue( yOffset() + ypos - minY ); // do we need to scroll down else if ( ypos > maxY ) { int vertScrollBarValue; unsigned long vertScrollBarValueMax = table->sizeMaxY() - height(); vertScrollBarValue = yOffset() + ypos - maxY; //We don't want to display any area > KS_rowMax value if ( (unsigned long)vertScrollBarValue > vertScrollBarValueMax ) vertScrollBarValue = vertScrollBarValueMax; vertScrollBar()->setValue( vertScrollBarValue ); } if ( !make_select ) setChooseMarker( QPoint( x, y ) ); else { QRect selection = activeTable()->chooseRect(); if ( chooseMarkerColumn() == selection.left() ) selection.setLeft( x ); else selection.setRight( x ); if ( chooseMarkerRow() == selection.top() ) selection.setTop( y ); else selection.setBottom( y ); selection = selection.normalize(); m_i_chooseMarkerColumn = x; m_i_chooseMarkerRow = y; activeTable()->setChooseRect( selection ); } } void KSpreadCanvas::highlight( const QString &/*text*/, int /*matchingIndex*/, int /*matchedLength*/, const QRect &cellRect ) { // Which cell was this again? //KSpreadCell *cell = cellAt( cellRect.left(), cellRect.top() ); // ...now I remember, update it! // TBD: highlight it! gotoLocation( cellRect.left(), cellRect.top(), activeTable() ); } // Used by replace() logic to modify a cell. void KSpreadCanvas::replace( const QString &newText, int /*index*/, int /*replacedLength*/, int /*searchWordLenght*/,const QRect &cellRect ) { // Which cell was this again? KSpreadCell *cell = activeTable()->cellAt( cellRect.left(), cellRect.top() ); // ...now I remember, update it! cell->setDisplayDirtyFlag(); cell->setCellText( newText ); cell->clearDisplayDirtyFlag(); activeTable()->updateCell( cell, cellRect.left(), cellRect.top() ); } void KSpreadCanvas::slotScrollHorz( int _value ) { if ( activeTable() == 0L ) return; if ( _value < 0 ) { _value = 0; kdDebug (36001) << "KSpreadCanvas::slotScrollHorz: value out of range (_value: " << _value << ")" << endl; } int xpos = activeTable()->columnPos( QMIN( KS_colMax, m_pView->activeTable()->maxColumn()+10 ), this ); if(_value>(xpos + m_iXOffset)) _value=xpos + m_iXOffset; activeTable()->enableScrollBarUpdates( false ); // Relative movement int dx = m_iXOffset - _value; // New absolute position m_iXOffset = _value; scroll( dx, 0 ); hBorderWidget()->scroll( dx, 0 ); activeTable()->enableScrollBarUpdates( true ); } void KSpreadCanvas::slotScrollVert( int _value ) { if ( activeTable() == 0L ) return; if ( _value < 0 ) { _value = 0; kdDebug (36001) << "KSpreadCanvas::slotScrollVert: value out of range (_value: " << _value << ")" << endl; } int ypos = activeTable()->rowPos( QMIN( KS_rowMax, m_pView->activeTable()->maxRow()+10 ) , this ); if(_value>(ypos + m_iYOffset)) _value=ypos + m_iYOffset; activeTable()->enableScrollBarUpdates( false ); // Relative movement int dy = m_iYOffset - _value; // New absolute position m_iYOffset = _value; scroll( 0, dy ); vBorderWidget()->scroll( 0, dy ); activeTable()->enableScrollBarUpdates( true ); } void KSpreadCanvas::slotMaxColumn( int _max_column ) { int xpos = activeTable()->columnPos( QMIN( KS_colMax, _max_column + 10 ), this ); //Don't go beyond the maximum column range (KS_colMax) const int _sizeMaxX = activeTable()->sizeMaxX(); if ( ( xOffset() + xpos ) > ( _sizeMaxX - width() ) ) xpos = _sizeMaxX - width() - xOffset(); horzScrollBar()->setRange( 0, xpos + xOffset() ); } void KSpreadCanvas::slotMaxRow( int _max_row ) { int ypos = activeTable()->rowPos( QMIN( KS_rowMax, _max_row + 10 ), this ); //Don't go beyond the maximum row range (KS_rowMax) unsigned long _sizeMaxY = activeTable()->sizeMaxY(); if ( (unsigned long)( yOffset() + ypos ) > ( _sizeMaxY - height() ) ) ypos = _sizeMaxY - height() - yOffset(); vertScrollBar()->setRange( 0, ypos + yOffset() ); } void KSpreadCanvas::mouseMoveEvent( QMouseEvent * _ev ) { // Dont allow modifications if document is readonly. if ( !m_pView->koDocument()->isReadWrite() ) return; // Special handling for choose mode. if( m_bChoose ) { chooseMouseMoveEvent( _ev ); return; } // Working on this table ? KSpreadTable *table = activeTable(); if ( !table ) return; // Get the current selected rectangle QRect selection( table->selectionRect() ); int xpos; int ypos; int row = table->topRow( _ev->pos().y(), ypos, this ); int col = table->leftColumn( _ev->pos().x(), xpos, this ); if( col > KS_colMax || row > KS_rowMax ) { kdDebug(36001) << "KSpreadCanvas::mouseMoveEvent: col or row is out of range: col: " << col << " row: " << row << endl; return; } // Find out where the little "corner" (in lower right direction) is. QRect corner; // No selection or just complete rows/columns ? if ( selection.left() == 0 || table->isRowSelected() || table->isColumnSelected() ) { int x = table->columnPos( markerColumn(), this ); int y = table->rowPos( markerRow(), this ); KSpreadCell *cell = table->cellAt( markerColumn(), markerRow() ); int w = cell->width( markerColumn(), this ); int h = cell->height( markerRow(), this ); if(cell->extraXCells()) w= cell->extraWidth(); corner = QRect( x + w - 2, y + h -1, 5, 5 ); } else // if we have a rectangular selection ( not complete rows or columns ) { int x = table->columnPos( selection.left(), this ); int y = table->rowPos( selection.top(), this ); int x2 = table->columnPos( selection.right(), this ); KSpreadCell *cell = table->cellAt( selection.right(), selection.top() ); int tw = cell->width( selection.right(), this ); int w = ( x2 - x ) + tw; cell = table->cellAt( selection.left(), selection.bottom() ); int y2 = table->rowPos( selection.bottom(), this ); int th = cell->height( selection.bottom(), this ); int h = ( y2 - y ) + th; corner = QRect( x + w - 2, y + h -1, 5, 5 ); } // Test whether the mouse is over some anchor { KSpreadCell *cell = table->visibleCellAt( col, row ); QString anchor = cell->testAnchor( _ev->pos().x() - xpos, _ev->pos().y() - ypos ); if ( !anchor.isEmpty() && anchor != m_strAnchor ) setCursor( KCursor::handCursor() ); m_strAnchor = anchor; } // // Now set the cursor correctly. // if ( corner.contains( _ev->pos() ) ) setCursor( sizeFDiagCursor ); else if ( !m_strAnchor.isEmpty() ) setCursor( KCursor::handCursor() ); else setCursor( arrowCursor ); // No marking, selecting etc. in progess? Then quit here. if ( m_eMouseAction == NoAction ) return; // Set the new lower right corner of the selection if ( col <= m_iMouseStartColumn ) { selection.setLeft( col ); selection.setRight( m_iMouseStartColumn ); } else selection.setRight( col ); if ( row <= m_iMouseStartRow ) { selection.setTop( row ); selection.setBottom( m_iMouseStartRow ); } else selection.setBottom( row ); selection=table->selectionCellMerged(selection); // If nothing changed, then quit if ( selection == table->selectionRect() ) return; // Set the new selection table->setSelection( selection, QPoint( col, row ), this ); // Scroll the table if necessary if ( _ev->pos().x() < 0 ) horzScrollBar()->setValue( xOffset() + xpos ); else if ( _ev->pos().x() > width() ) { if ( col < KS_colMax ) { ColumnLayout *cl = table->columnLayout( col + 1 ); xpos = table->columnPos( col + 1, this ); horzScrollBar()->setValue( xOffset() + ( xpos + cl->width( this ) - width() ) ); } } if ( _ev->pos().y() < 0 ) vertScrollBar()->setValue( yOffset() + ypos ); else if ( _ev->pos().y() > height() ) { if ( row < KS_rowMax ) { RowLayout *rl = table->rowLayout( row + 1 ); ypos = table->rowPos( row + 1, this ); vertScrollBar()->setValue( yOffset() + ( ypos + rl->height( this ) - height() ) ); } } // Show where we are now. updatePosWidget(); m_bMouseMadeSelection = true; } void KSpreadCanvas::mouseReleaseEvent( QMouseEvent* _ev ) { if ( m_scrollTimer->isActive() ) m_scrollTimer->stop(); m_bMousePressed = false; if( m_bChoose ) { chooseMouseReleaseEvent( _ev ); return; } KSpreadTable *table = activeTable(); if ( !table ) return; QRect selection( table->selectionRect() ); // The user started the drag in the lower right corner of the marker ? if ( m_eMouseAction == ResizeCell ) { int x=m_iMouseStartColumn; int y=m_iMouseStartRow; if( m_iMouseStartColumn>selection.left()) x=selection.left(); if( m_iMouseStartRow > selection.top() ) y =selection.top(); KSpreadCell *cell = table->nonDefaultCell( x, y ); if ( !m_pView->doc()->undoBuffer()->isLocked() ) { KSpreadUndoMergedCell *undo = new KSpreadUndoMergedCell( m_pView->doc(), table, x, y,cell->extraXCells() ,cell->extraYCells()); m_pView->doc()->undoBuffer()->appendUndo( undo ); } cell->forceExtraCells( x,y, abs(selection.right() - selection.left()), abs(selection.bottom() - selection.top()) ); selection.setCoords( 0, 0, 0, 0 ); table->setSelection( selection, this ); m_pView->updateEditWidget(); if(table->getAutoCalc()) table->recalc(); } else if ( m_eMouseAction == AutoFill ) { QRect dest = table->selectionRect(); table->autofill( m_rctAutoFillSrc, dest ); selection.setCoords( 0, 0, 0, 0 ); table->setSelection( selection, this ); m_pView->updateEditWidget(); } // The user started the drag in the middle of a cell ? else if ( m_eMouseAction == Mark ) { // Get the object in the lower right corner KSpreadCell *cell = table->cellAt( m_iMouseStartColumn, m_iMouseStartRow ); // Did we mark only a single cell ? // Take care: One cell may obscure other cells ( extra size! ). if ( selection.left() + cell->extraXCells() == selection.right() && selection.top() + cell->extraYCells() == selection.bottom() ) { // Delete the selection selection.setCoords( 0, 0, 0, 0 ); table->setSelection( selection, this ); gotoLocation(KSpreadPoint(util_cellName(m_iMouseStartColumn, m_iMouseStartRow))); } else m_pView->updateEditWidget(); } m_eMouseAction = NoAction; m_bMouseMadeSelection = FALSE; } void KSpreadCanvas::mousePressEvent( QMouseEvent * _ev ) { if ( _ev->button() == LeftButton ) m_bMousePressed = true; // If in choose mode, we handle the mouse differently. if( m_bChoose ) { chooseMousePressEvent( _ev ); return; } KSpreadTable *table = activeTable(); if ( !table ) return; // We were editing a cell -> save value and get out of editing mode if ( m_pEditor ) { deleteEditor( true ); // save changes } m_scrollTimer->start( 50 ); // Remember current values. QRect selection( table->selectionRect() ); int old_column = markerColumn(); int old_row = markerRow(); // Check whether we clicked in the little marker in the lower right // corner of a cell or a marked area. { // Get the position and size of the marker/marked-area int xpos; int ypos; int w, h; // No selection or complete rows/columns are selected if ( selection.left() == 0 || table->isRowSelected() || table->isColumnSelected() ) { xpos = table->columnPos( markerColumn(), this ); ypos = table->rowPos( markerRow(), this ); KSpreadCell *cell = table->cellAt( markerColumn(), markerRow() ); w = cell->width( markerColumn() ); h = cell->height( markerRow() ); if(cell->extraXCells()) w= cell->extraWidth(); } else // if we have a rectangular selection ( not complete rows or columns ) { xpos = table->columnPos( selection.left(), this ); ypos = table->rowPos( selection.top(), this ); int x = table->columnPos( selection.right(), this ); KSpreadCell *cell = table->cellAt( selection.right(), selection.top() ); int tw = cell->width( selection.right(), this ); w = ( x - xpos ) + tw; cell = table->cellAt( selection.left(), selection.bottom() ); int y = table->rowPos( selection.bottom(), this ); int th = cell->height( selection.bottom(), this ); h = ( y - ypos ) + th; } // Did we click in the lower right corner of the marker/marked-area ? if ( _ev->pos().x() >= xpos + w - 2 && _ev->pos().x() <= xpos + w + 3 && _ev->pos().y() >= ypos + h - 1 && _ev->pos().y() <= ypos + h + 4 ) { // Auto fill ? That is done using the left mouse button. if ( _ev->button() == LeftButton ) { m_eMouseAction = AutoFill; // Do we have a selection already ? if ( selection.left() != 0 && table->isRowSelected() == FALSE && table->isColumnSelected() == FALSE) { /* Selection is ok */ m_rctAutoFillSrc = selection; } else // Select the current cell { KSpreadCell *cell = table->cellAt( markerColumn(), markerRow() ); selection.setCoords( markerColumn(), markerRow(), QMIN(KS_colMax, markerColumn() + cell->extraXCells()), QMIN(KS_rowMax, markerRow() + cell->extraYCells()) ); m_rctAutoFillSrc.setCoords( markerColumn(), markerRow(), markerColumn(), markerRow() ); } m_iMouseStartColumn = QMIN(markerColumn(),selection.left()); m_iMouseStartRow = QMIN(markerRow(),selection.top()); } // Resize a cell (dont with the right mouse button) ? // But for that to work there must not be a selection. else if ( _ev->button() == MidButton && selection.left() == 0 ) { m_eMouseAction = ResizeCell; KSpreadCell *cell = table->cellAt( markerColumn(), markerRow() ); selection.setCoords( markerColumn(), markerRow(), QMIN(KS_colMax, markerColumn() + cell->extraXCells()), QMIN(KS_rowMax, markerRow() + cell->extraYCells()) ); m_iMouseStartColumn = markerColumn(); m_iMouseStartRow = markerRow(); } table->setSelection( selection, this ); return; } } // In which cell did the user click ? int xpos, ypos; int row = table->topRow( _ev->pos().y(), ypos, this ); int col = table->leftColumn( _ev->pos().x(), xpos, this ); //you cannot move marker when col > KS_colMax or row > KS_rowMax if( col > KS_colMax || row > KS_rowMax){ kdDebug(36001) << "KSpreadCanvas::mousePressEvent: col or row is out of range: col: " << col << " row: " << row << endl; return; } // Unselect a selection ? if ( _ev->button() == LeftButton || !selection.contains( QPoint( col, row ) ) ) table->unselect(); // Extending an existing selection with the shift button ? if ( m_pView->koDocument()->isReadWrite() && selection.right() != KS_colMax && selection.bottom() != KS_rowMax && _ev->state() & ShiftButton ) { if( col != old_column || row != old_row ) { if(old_column>col) { int tmp=col; col=old_column; old_column=tmp; } if(old_row>row) { int tmp=row; row=old_row; old_row=tmp; } if( selection.left()!=0 && selection.right()!=0 && selection.top()!=0 && selection.bottom()!=0 ) { //if you have a selection and you go up in the table //so bottom is the bottom of the selection //not the markercolumn if(selection.bottom()>row) row = selection.bottom(); if(selection.right()>col) col = selection.right(); } selection.setLeft(old_column); selection.setRight( col ); selection.setTop(old_row); selection.setBottom( row ); table->setSelection( selection, QPoint( old_column, old_row ), this ); //always put Marker in top and left //otherwise all functions don't work // table->setMarker( QPoint( old_column, old_row ) ); return; } } // activeTable()->setMarker( QPoint( col, row ) ); KSpreadCell *cell = table->cellAt( col, row ); // Go to the upper left corner of the obscuring object if cells are merged if (cell->isObscuringForced()) { cell = cell->obscuringCells().getFirst(); col = cell->column(); row = cell->row(); } // Start a marking action ? if ( !m_strAnchor.isEmpty() && _ev->button() == LeftButton ) { bool isLink = (m_strAnchor.find("http://") == 0 || m_strAnchor.find("mailto:") == 0 || m_strAnchor.find("ftp://") == 0 || m_strAnchor.find("file:") == 0 ); bool isLocalLink = (m_strAnchor.find("file:") == 0); if( isLink ) { QString question = i18n("Do you want to open this link to '%1'?\n").arg(m_strAnchor); if( isLocalLink ) { question += i18n("Note that opening a link to a local file may " "compromise your system's security!"); } // this will also start local programs, so adding a "don't warn again" // checkbox will probably be too dangerous int choice = KMessageBox::warningYesNo(this, question, i18n("Open Link?")); if( choice == KMessageBox::Yes ) { (void) new KRun( m_strAnchor ); } } else { gotoLocation( KSpreadPoint( m_strAnchor, m_pDoc->map() ) ); } } else if ( _ev->button() == LeftButton ) { m_eMouseAction = Mark; selection.setCoords( col, row, col + cell->extraXCells(), row + cell->extraYCells() ); table->setSelection( selection, this ); m_iMouseStartColumn = col; m_iMouseStartRow = row; } else if ( _ev->button() == RightButton ) { // No selection or the mouse press was outside of an existing selection ? if ( selection.left() == 0 || !selection.contains( QPoint(col, row )) ) table->setMarker( QPoint( col, row ) ); } // Paste operation with the middle button ? if( _ev->button() == MidButton ) { table->setMarker( QPoint( col, row ) ); table->paste( QPoint( markerColumn(), markerRow() ) ); table->cellAt( markerColumn(), markerRow() )->update(); } // Update the edit box m_pView->updateEditWidgetOnPress(); updatePosWidget(); // Context menu ? if ( _ev->button() == RightButton ) { // TODO: Handle anchor QPoint p = mapToGlobal( _ev->pos() ); m_pView->openPopupMenu( p ); } } void KSpreadCanvas::chooseMouseMoveEvent( QMouseEvent * _ev ) { if ( !m_bMousePressed ) return; KSpreadTable *table = activeTable(); if ( !table ) return; int ypos, xpos; int row = table->topRow( _ev->pos().y(), ypos, this ); int col = table->leftColumn( _ev->pos().x(), xpos, this ); /*if ( col < m_iMouseStartColumn ) col = m_iMouseStartColumn; if ( row < m_iMouseStartRow ) row = m_iMouseStartRow;*/ if( col > KS_colMax || row > KS_rowMax ) { kdDebug(36001) << "KSpreadCanvas::chooseMouseMoveEvent: col or row is out of range: col: " << col << " row: " << row << endl; return; } // Noting changed ? QRect selection( table->chooseRect() ); /*if ( row == selection.bottom() && col == selection.right() ) return; */ // Set the new lower right corner of the selection /*selection.setRight( col ); selection.setBottom( row );*/ if ( col <= m_iMouseStartColumn ) { selection.setLeft( col ); selection.setRight( m_iMouseStartColumn ); } else selection.setRight( col ); if ( row <= m_iMouseStartRow ) { selection.setTop( row ); selection.setBottom( m_iMouseStartRow); } else selection.setBottom( row ); table->setChooseRect( selection ); // Scroll the table if neccessary if ( _ev->pos().x() < 0 ) horzScrollBar()->setValue( xOffset() + xpos ); else if ( _ev->pos().x() > width() ) { if ( col < KS_colMax ) { ColumnLayout *cl = table->columnLayout( col + 1 ); xpos = table->columnPos( col + 1, this ); horzScrollBar()->setValue( xOffset() + ( xpos + cl->width( this ) - width() ) ); } } if ( _ev->pos().y() < 0 ) vertScrollBar()->setValue( yOffset() + ypos ); else if ( _ev->pos().y() > height() ) { if ( row < KS_rowMax ) { RowLayout *rl = table->rowLayout( row + 1 ); ypos = table->rowPos( row + 1, this ); vertScrollBar()->setValue( yOffset() + ( ypos + rl->height( this ) - height() ) ); } } } void KSpreadCanvas::chooseMouseReleaseEvent( QMouseEvent* ) { // gets done in mouseReleaseEvent // m_bMousePressed = FALSE; } void KSpreadCanvas::chooseMousePressEvent( QMouseEvent * _ev ) { KSpreadTable *table = activeTable(); if ( !table ) return; QRect selection = table->chooseRect(); int ypos, xpos; int row = table->topRow( _ev->pos().y(), ypos, this ); int col = table->leftColumn( _ev->pos().x(), xpos, this ); if( col > KS_colMax || row > KS_rowMax ) { kdDebug(36001) << "KSpreadCanvas::chooseMousePressEvent: col or row is out of range: col: " << col << " row: " << row << endl; return; } if ( ( (!table->isColumnSelected()) && (!table->isRowSelected())) && ( _ev->state() & ShiftButton ) ) { if ( col != m_iMouseStartColumn || row != m_iMouseStartRow ) { if ( selection.left() !=0 && selection.right() !=0 && selection.top() !=0 && selection.bottom() !=0 ) { if ( col < m_iMouseStartColumn ) col = m_iMouseStartColumn; if ( row < m_iMouseStartRow ) row = m_iMouseStartRow; if ( row == selection.bottom() && col == selection.right() ) return; } selection.setLeft(m_iMouseStartColumn); selection.setRight( col ); selection.setTop(m_iMouseStartRow); selection.setBottom( row ); table->setChooseRect( selection ); return; } } setChooseMarkerColumn( col ); setChooseMarkerRow( row ); KSpreadCell *cell = table->cellAt( chooseMarkerColumn(), chooseMarkerRow() ); // Go to the upper left corner of the obscuring object if it is a merged cell if ( cell->isObscuringForced() ) { cell = cell->obscuringCells().getFirst(); setChooseMarkerRow( cell->row() ); setChooseMarkerColumn( cell->column() ); } if ( cell->isForceExtraCells() ) { selection.setCoords( chooseMarkerColumn(), chooseMarkerRow(), chooseMarkerColumn() + cell->extraXCells(), chooseMarkerRow() + cell->extraYCells() ); } else { selection.setCoords( chooseMarkerColumn(), chooseMarkerRow(), chooseMarkerColumn(), chooseMarkerRow() ); } table->setChooseRect( selection ); m_iMouseStartColumn = chooseMarkerColumn(); m_iMouseStartRow = chooseMarkerRow(); } void KSpreadCanvas::mouseDoubleClickEvent( QMouseEvent* ) { if ( m_pView->koDocument()->isReadWrite() ) createEditor(); } void KSpreadCanvas::wheelEvent( QWheelEvent* _ev ) { if ( vertScrollBar() ) QApplication::sendEvent( vertScrollBar(), _ev ); } void KSpreadCanvas::paintEvent( QPaintEvent* _ev ) { if ( m_pDoc->isLoading() ) return; if ( !activeTable() ) return; // printf("PAINT EVENT %i %i %i %i\n", _ev->rect().x(), _ev->rect().y(), _ev->rect().width(), _ev->rect().height() ); QRect rect( _ev->rect() ); if ( rect.left() < 0 ) rect.rLeft() = 0; if ( rect.right() > width() ) rect.rRight() = width(); if ( rect.top() < 0 ) rect.rTop() = 0; if ( rect.bottom() > height() ) rect.rBottom() = height(); // printf("PAINT EVENT %i %i %i %i\n", rect.x(), rect.y(), rect.width(), rect.height() ); QPainter painter; painter.begin( this ); QWMatrix m = m_pView->matrix(); painter.setWorldMatrix( m ); m = m.invert(); QPoint tl = m.map( rect.topLeft() ); QPoint br = m.map( rect.bottomRight() ); //kdDebug(36001) << "Mapped topleft to " << tl.x() << ":" << tl.y() << endl; painter.save(); // Clip away children QRegion rgn = painter.clipRegion(); if ( rgn.isEmpty() ) rgn = QRegion( rect ); QPtrListIterator it( m_pDoc->children() ); for( ; it.current(); ++it ) { if ( ((KSpreadChild*)it.current())->table() == activeTable() && !m_pView->hasDocumentInWindow( it.current()->document() ) ) { rgn -= it.current()->region( painter.worldMatrix() ); } } painter.setClipRegion( rgn ); // Draw content m_pDoc->paintContent( painter, QRect( tl, br ), FALSE, activeTable() ); painter.restore(); // Draw children // QPtrListIterator it( m_pDoc->children() ); it.toFirst(); for( ; it.current(); ++it ) { if ( ((KSpreadChild*)it.current())->table() == activeTable() && !m_pView->hasDocumentInWindow( it.current()->document() ) ) { // #### todo: paint only if child is visible inside rect painter.save(); m_pDoc->paintChild( it.current(), painter, m_pView ); painter.restore(); } } painter.end(); if( choose_visible ) drawChooseMarker( ); } void KSpreadCanvas::focusInEvent( QFocusEvent* ) { if ( !m_pEditor ) return; //kdDebug(36001) << "m_bChoose : " << ( m_bChoose ? "true" : "false" ) << endl; // If we are in editing mode, we redirect the // focus to the CellEditor or EditWidget // And we know which, using lastEditorWithFocus. // This screws up though (David) if ( lastEditorWithFocus() == EditWidget ) { m_pView->editWidget()->setFocus(); //kdDebug(36001) << "Focus to EditWidget" << endl; return; } //kdDebug(36001) << "Redirecting focus to editor" << endl; m_pEditor->setFocus(); } void KSpreadCanvas::focusOutEvent( QFocusEvent* ) { if (m_scrollTimer->isActive()) m_scrollTimer->stop(); m_bMousePressed = false; } void KSpreadCanvas::resizeEvent( QResizeEvent* _ev ) { // If we rise horizontally, then check if we are still within the valid area (KS_colMax) if ( _ev->size().width() > _ev->oldSize().width() ){ if ( (unsigned long)( xOffset() + _ev->size().width() ) > activeTable()->sizeMaxX() ) { horzScrollBar()->setRange( 0, activeTable()->sizeMaxX() - _ev->size().width() ); } } // If we lower vertically, then check if the range should represent the maximum range else if ( _ev->size().width() < _ev->oldSize().width() ){ if ( (unsigned long)(horzScrollBar()->maxValue()) == ( activeTable()->sizeMaxX() - _ev->oldSize().width() ) ) { horzScrollBar()->setRange( 0, activeTable()->sizeMaxX() - _ev->size().width() ); } } // If we rise vertically, then check if we are still within the valid area (KS_rowMax) if ( _ev->size().height() > _ev->oldSize().height() ){ if ( (unsigned long)( yOffset() + _ev->size().height() ) > activeTable()->sizeMaxY() ) { vertScrollBar()->setRange( 0, activeTable()->sizeMaxY() - _ev->size().height() ); } } // If we lower vertically, then check if the range should represent the maximum range else if ( _ev->size().height() < _ev->oldSize().height() ){ if ( (unsigned long)vertScrollBar()->maxValue() == ( activeTable()->sizeMaxY() - _ev->oldSize().height() ) ) { vertScrollBar()->setRange( 0, activeTable()->sizeMaxY() - _ev->size().height() ); } } } void KSpreadCanvas::keyPressEvent ( QKeyEvent * _ev ) -{ - KSpreadTable *table = activeTable(); +{ + KSpreadTable * table = activeTable(); QString tmp; if ( !table ) return; + if ( formatKeyPress( _ev ) ) + return; + // Dont handle the remaining special keys. if ( _ev->state() & ( Qt::AltButton | Qt::ControlButton ) && (_ev->key() != Key_Down) && (_ev->key() != Key_Up) && (_ev->key() != Key_Right) && (_ev->key() != Key_Left) && (_ev->key() != Key_Home) ) { QWidget::keyPressEvent( _ev ); return; } // Always accept so that events are not // passed to the parent. _ev->accept(); // Find out about the current selection/choose. QRect selection; if ( m_bChoose ) selection = activeTable()->chooseRect(); else selection = activeTable()->selectionRect(); // Is this a key that involves goint to another cell ? If yes, do the // "end of editing" stuff here, instead of for each case - this bool is // also used for make_select (extending selection), so it doesn't include Return bool bChangingCells = ( _ev->key() == Key_Down || _ev->key() == Key_Up || _ev->key() == Key_Left || _ev->key() == Key_Right || _ev->key() == Key_Prior || _ev->key() == Key_Next ); // End of editing a cell if ( ( bChangingCells || _ev->key() == Key_Return || _ev->key() == Key_Enter ) && m_pEditor && !m_bChoose ) { deleteEditor( true /*save changes*/ ); } // Are we making a selection right now ? Go thru this only if no selection is made // or if we neither selected complete rows nor columns. bool make_select = m_pView->koDocument()->isReadWrite() && ((( _ev->state() & ShiftButton ) == ShiftButton || (( _ev->state() & ShiftButton ) == ShiftButton ) && ( _ev->state() & ControlButton ) == ControlButton) && ( bChangingCells || _ev->key() == Key_Home || _ev->key() == Key_End )); ColumnLayout *cl; RowLayout *rl; int moveHide=0; + if( !((( _ev->state() & ShiftButton ) == ShiftButton)&&( _ev->state() & ControlButton ) == ControlButton) && (_ev->state() != Qt::ControlButton) ) { KSpread::MoveTo tmpMoveTo=m_pView->doc()->getMoveToValue(); //if shift Button clicked inverse move direction if(_ev->state()==Qt::ShiftButton) { switch( tmpMoveTo) { case KSpread::Bottom: tmpMoveTo=KSpread::Top; break; case KSpread::Top: tmpMoveTo=KSpread::Bottom; break; case KSpread::Left: tmpMoveTo=KSpread::Right; break; case KSpread::Right: tmpMoveTo=KSpread::Left; } - } + } + //if( _ev->state() != Qt::ControlButton ){ switch( _ev->key() ) { case Key_Return: case Key_Enter: switch( tmpMoveTo) { case KSpread::Bottom : { if ( !m_bChoose && markerRow() == KS_rowMax ) return; if ( m_bChoose && chooseMarkerRow() == KS_rowMax ) return; if ( m_bChoose ) chooseGotoLocation( chooseMarkerColumn(), QMIN( KS_rowMax, chooseMarkerRow() + 1 ), 0, make_select ); else { QRect selection = activeTable()->selectionRect(); if( selection.left() == 0 ) gotoLocation( markerColumn(), QMIN( KS_rowMax, markerRow() + 1 ), 0, make_select,false,true ); else { if( markerColumn()selectionRect(); if( selection.left() == 0 ) gotoLocation( markerColumn(), QMAX( 1, markerRow() - 1 ), 0, make_select,false,true ); else { if( markerRow()==selection.top() && markerColumn()==selection.left()) gotoLocation( selection.right(), QMAX( 1, selection.bottom() ), 0, make_select,true,true ); else if(markerColumn()==selection.right() && markerRow()>selection.top()) gotoLocation( markerColumn(), QMAX( 1, markerRow() - 1 ), 0, make_select,true,true ); else if(markerColumn()selection.top() ) gotoLocation( markerColumn(), QMAX( 1, markerRow() - 1 ), 0, make_select,true ,true); else if( markerRow()==selection.top() && markerColumn()<=selection.right()) gotoLocation( markerColumn()-1, QMAX( 1, selection.bottom() ), 0, make_select,true, true ); } } return; } case KSpread::Left : { /*if ( !m_bChoose && markerColumn() == 1 ) return;*/ if ( m_bChoose && chooseMarkerColumn() == 1 ) return; if ( m_bChoose ) chooseGotoLocation( QMAX(chooseMarkerColumn()-1,1), chooseMarkerRow() , 0, make_select ); else { QRect selection = activeTable()->selectionRect(); if( selection.left() == 0 ) gotoLocation( QMAX(markerColumn()-1,1), markerRow() , 0, make_select,false,true ); else { if( markerRow()==selection.top() && markerColumn()==selection.left()) gotoLocation( selection.right(),selection.bottom() , 0, make_select,true,true ); else if(markerColumn()>selection.left() && markerRow()<=selection.bottom()) gotoLocation( QMAX(markerColumn()-1,1), markerRow() , 0, make_select,true,true ); else if(markerColumn()==selection.right()&&markerRow()==selection.bottom() && markerColumn()!=selection.left()) gotoLocation( QMAX(markerColumn()-1,1), markerRow(), 0, make_select,true ,true); else if(markerColumn()==selection.right()&&markerRow()==selection.bottom() && markerColumn()==selection.left()) gotoLocation( markerColumn(),QMAX( markerRow()-1,1), 0, make_select,true ,true); else if( markerColumn()==selection.left() && markerRow()<=selection.bottom()) gotoLocation( selection.right(),QMAX( 1, markerRow()-1 ) , 0, make_select,true, true ); } } return; } case KSpread::Right : { /*if ( !m_bChoose && markerColumn() == KS_colMax) return;*/ if ( m_bChoose && chooseMarkerColumn() == KS_colMax ) return; if ( m_bChoose ) chooseGotoLocation( QMIN( KS_colMax, chooseMarkerColumn()+1 ),chooseMarkerRow() , 0, make_select ); else { QRect selection = activeTable()->selectionRect(); if( selection.left() == 0 ) gotoLocation( QMIN( KS_colMax, markerColumn()+1 ), markerRow() , 0, make_select,false,true ); else { if( markerRow()==selection.top() && markerColumn()==selection.left() && markerColumn()!=selection.right()) gotoLocation( QMIN(markerColumn()+1, KS_colMax), markerRow(), 0, make_select,true,true ); else if( markerRow()==selection.top() && markerColumn()==selection.left() && markerColumn()==selection.right()) gotoLocation( markerColumn(), QMIN(markerRow()+1, KS_rowMax), 0, make_select,true,true ); else if(markerColumn()nonDefaultRowLayout( moveHide ); } while( rl->isHide()); if ( m_bChoose ) chooseGotoLocation( chooseMarkerColumn(), QMIN( KS_rowMax, /*chooseMarkerRow() + 1*/moveHide ), 0, make_select); else gotoLocation( markerColumn(), QMIN( KS_rowMax, /*markerRow() + 1*/ moveHide), 0, make_select,false,true ); return; case Key_Up: if ( !m_bChoose && markerRow() == 1 ) return; if ( m_bChoose && chooseMarkerRow() == 1 ) return; if(m_bChoose) moveHide=chooseMarkerRow(); else moveHide=markerRow(); do { moveHide--; rl= activeTable()->nonDefaultRowLayout( moveHide ); } while( rl->isHide() && moveHide!=0); if(moveHide==0) return; if ( m_bChoose ) chooseGotoLocation( chooseMarkerColumn(), QMAX( 1, /*chooseMarkerRow() - 1*/moveHide ), 0, make_select ); else gotoLocation( markerColumn(), QMAX( 1, /*markerRow() - 1*/ moveHide ), 0, make_select,false,true ); return; case Key_Right: case Key_Tab: if ( !m_bChoose && markerColumn() >= KS_colMax ) return; if ( m_bChoose && chooseMarkerColumn() >= KS_colMax ) return; if(m_bChoose) moveHide=chooseMarkerColumn(); else moveHide=markerColumn() ; do { moveHide++; cl= activeTable()->nonDefaultColumnLayout( moveHide ); } while( cl->isHide() ); if ( m_bChoose ) chooseGotoLocation( QMIN( KS_colMax, /*chooseMarkerColumn() + 1*/moveHide ), chooseMarkerRow(), 0, make_select ); else gotoLocation( QMIN( KS_colMax, /*markerColumn() + 1*/moveHide ), markerRow(), 0, make_select,false,true ); return; case Key_Left: if ( !m_bChoose && markerColumn() == 1 ) return; if ( m_bChoose && chooseMarkerColumn() == 1 ) return; if(m_bChoose) moveHide=chooseMarkerColumn(); else moveHide=markerColumn(); do { moveHide--; cl= activeTable()->nonDefaultColumnLayout( moveHide ); } while( cl->isHide() && moveHide!=0); // if column==0 return; if(moveHide==0) return; if ( m_bChoose ) chooseGotoLocation( QMAX( 1, /*chooseMarkerColumn() - 1*/moveHide ), chooseMarkerRow(), 0, make_select ); else gotoLocation( QMAX( 1, /*markerColumn() - 1*/ moveHide), markerRow(), 0, make_select,false,true ); return; case Key_Escape: if ( m_pEditor ) deleteEditor( false ); _ev->accept(); // ? return; case Key_Home: // We are in edit mode -> go beginning of line if ( m_pEditor ) { // (David) Do this for text editor only, not formula editor... // Don't know how to avoid this hack (member var for editor type ?) if ( m_pEditor->inherits("KSpreadTextEditor") ) QApplication::sendEvent( m_pEditWidget, _ev ); // What to do for a formula editor ? } else { if ( !m_bChoose && markerColumn() == 1 ) return; if ( m_bChoose && chooseMarkerColumn() == 1 ) return; int col = table->getFirstCellRow(markerRow())->column(); if ( col == markerColumn() ) col = 1; if ( m_bChoose ) chooseGotoLocation( col, markerRow(), 0, make_select ); else gotoLocation( col, markerRow(), 0, make_select,false,true ); } return; case Key_End: // move to the last used cell in the row // We are in edit mode -> go beginning of line if ( m_pEditor ) { // (David) Do this for text editor only, not formula editor... // Don't know how to avoid this hack (member var for editor type ?) if ( m_pEditor->inherits("KSpreadTextEditor") ) QApplication::sendEvent( m_pEditWidget, _ev ); // TODO: What to do for a formula editor ? } else { int maxCol = table->maxColumn(); int row = markerRow(); int max = -1; int i; // we have to check every cell, cause there might // be unused cells in the middle for (i = 1; i < maxCol; ++i) { KSpreadCell * cell = table->cellAt( i, row ); if (cell != table->defaultCell()) { if (!cell->isObscured()) max = i; } } if (max == -1) return; if ( m_bChoose ) chooseGotoLocation( max, markerRow(), 0, make_select ); else gotoLocation( max, markerRow(), 0, make_select,false,true ); } return; case Key_Prior: if( !m_bChoose && markerRow() == 1 ) return; if( m_bChoose && chooseMarkerRow() == 1 ) return; if ( m_bChoose ) chooseGotoLocation( chooseMarkerColumn(), QMAX( 1, chooseMarkerRow() - 10 ), 0, make_select ); else gotoLocation( markerColumn(), QMAX( 1, markerRow() - 10 ), 0, make_select,false,true ); return; case Key_Next: if( !m_bChoose && markerRow() == KS_rowMax ) return; if( m_bChoose && chooseMarkerRow() == KS_rowMax ) return; if ( m_bChoose ) chooseGotoLocation( chooseMarkerColumn(), QMIN( KS_rowMax, chooseMarkerRow() + 10 ), 0, make_select ); else gotoLocation( markerColumn(), QMIN( KS_rowMax, markerRow() + 10 ), 0, make_select,false,true ); return; case Key_Delete: activeTable()->clearTextSelection( QPoint( markerColumn(), markerRow() ) ); m_pView->editWidget()->setText( "" ); return; case Key_F2: m_pView->editWidget()->setFocus(); if(m_pEditor) m_pView->editWidget()->setCursorPosition(m_pEditor->cursorPosition()-1); m_pView->editWidget()->cursorForward(false); return; default: if (m_pEditor && (_ev->key() == Key_F4)) { m_pEditor->handleKeyPressEvent( _ev ); _ev->accept(); return; } // No null character ... if ( _ev->text().isEmpty() || !m_pView->koDocument()->isReadWrite() ) { _ev->accept(); return; } if ( !m_pEditor && !m_bChoose ) { // Switch to editing mode createEditor( CellEditor ); m_pEditor->handleKeyPressEvent( _ev ); } else if ( m_pEditor ) m_pEditor->handleKeyPressEvent( _ev ); return; } // control button not pressed } else { //control button pressed if(!make_select) table->unselect(); int x, y; switch(_ev->key()){ //Ctrl+Key_Up case Key_Up: //If we are already at the end, we skip if ( !m_bChoose && markerRow() <= 1 ) return; //If we are already at the end, we skip if ( m_bChoose && chooseMarkerRow() <= 1 ) return; if ( m_bChoose ) //If we are in choose mode, we only go 1 up chooseGotoLocation( chooseMarkerColumn(), QMAX( 1, chooseMarkerRow() - 1 ), 0, make_select ); else{ x = markerColumn(); y = markerRow(); //If we are at the end of a filled or empty block, then move one up if ( activeTable()->cellAt( x, y )->isEmpty() != activeTable()->cellAt( x, y-1 )->isEmpty() ) y --; else { // if this is a filled cell if(!activeTable()->cellAt( x, y )->isEmpty()){ //Then we search as long as the previous pervios field is filled while ( (y-1 >= 1) && !(activeTable()->cellAt( x, y-1 ))->isEmpty() ) { y --; } } else{ //Otherwise we search as long as the previous pervios field is empty KSpreadCell * _c = activeTable()->getNextCellUp( x, y ); //Found an existing cell, but does it contain something? while ( _c && _c->isEmpty() ) { _c = activeTable()->getNextCellUp( x, _c->row() ); } //If there is a filled one, use the next if ( _c ) y = _c->row() + 1; //Otherwise go to the first row else y = 1; } } gotoLocation( x, QMAX( 1, y ), 0, make_select, true, true ); } return; //Ctrl+Key_Down case Key_Down: //If we are already at the end, we skip if ( !m_bChoose && markerRow() >= KS_rowMax ) return; //If we are already at the end, we skip if ( m_bChoose && chooseMarkerRow() >= KS_rowMax ) return; if ( m_bChoose ) //If we are in choose mode, we only go 1 down chooseGotoLocation( chooseMarkerColumn(), QMIN( KS_rowMax, chooseMarkerRow() + 1 ), 0, make_select ); else{ x = markerColumn(); y = markerRow(); //If we are at the end of a filled or empty block, then move one down if ( ( y < KS_rowMax ) && ( activeTable()->cellAt( x, y )->isEmpty() != activeTable()->cellAt( x, y+1 )->isEmpty() ) ) y ++; else { // if this is a filled cell if(!activeTable()->cellAt( x, y )->isEmpty()){ //Then we search as long as the next field is filled while ( (y+1 <= KS_rowMax) && !(activeTable()->cellAt( x, y+1 ))->isEmpty() ) { y ++; } } else{ // If this already the last used field then jump to the end if ( y >= activeTable()->maxRow() ) { y = KS_rowMax; } else { //Otherwise we search for the next filled field and use the last empty one KSpreadCell * _c = activeTable()->getNextCellDown( x, y ); //Found an existing cell, but does it contain something? while ( _c && _c->isEmpty() ) { _c = activeTable()->getNextCellDown( x, _c->row() ); } //If there is a filled one, use the previous if ( _c ) y = _c->row() - 1; //Otherwise go to the end else y = KS_rowMax; } } } gotoLocation( x, QMIN( KS_rowMax, y ), 0, make_select, true, true ); } return; //Ctrl+Key_Right case Key_Right: //If we are already at the end, we skip if ( !m_bChoose && markerColumn() >= KS_colMax ) return; //If we are already at the end, we skip if ( m_bChoose && chooseMarkerColumn() >= KS_colMax ) return; if ( m_bChoose ) //If we are in choose mode, we only go 1 right chooseGotoLocation( QMIN( KS_colMax, chooseMarkerColumn() + 1 ), chooseMarkerRow(), 0, make_select ); else{ x = markerColumn(); y = markerRow(); //If we are at the end of a filled or empty block, then move one right if ( activeTable()->cellAt( x, y )->isEmpty() != activeTable()->cellAt( x+1, y )->isEmpty() ) x ++; else { // if this is a filled cell if(!activeTable()->cellAt( x, y )->isEmpty()){ //Then we search as long as the next field is filled while ( (x < KS_colMax) && !(activeTable()->cellAt( x+1, y ))->isEmpty() ){ x ++; } } else{ // If this already the last used field then jump to the end if ( x >= activeTable()->maxColumn() ) { x = KS_colMax; } else { //Otherwise we search for the next filled field and use the last empty one KSpreadCell * _c = activeTable()->getNextCellRight( x, y ); //Found an existing cell, but does it contain something? while ( _c && _c->isEmpty() ) { _c = activeTable()->getNextCellRight( _c->column(), y ); } //If there is a filled one, use the previous if ( _c ) x = _c->column() - 1; //Otherwise go to the end else x = KS_colMax; } } } gotoLocation( QMIN( KS_colMax, x ), y, 0, make_select, true, true ); } return; //Ctrl+Key_Left case Key_Left: //If we are already at the end, we skip if ( !m_bChoose && markerColumn() <= 1 ) return; //If we are already at the end, we skip if ( m_bChoose && chooseMarkerColumn() <= 1 ) return; if ( m_bChoose ) //If we are in choose mode, we only go 1 left chooseGotoLocation( QMAX( 1, chooseMarkerColumn() - 1 ), chooseMarkerRow(), 0, make_select ); else{ x = markerColumn(); y = markerRow(); //If we are at the end of a filled or empty block, then move one left if ( activeTable()->cellAt( x, y )->isEmpty() != activeTable()->cellAt( x-1, y )->isEmpty() ) x --; else { // if this is a filled cell if(!activeTable()->cellAt( x, y )->isEmpty()){ //Then we search as long as the previous field is filled while ( (x-1 >= 1) && !(activeTable()->cellAt( x-1, y ))->isEmpty() ){ x --; } } else{ //Otherwise we search as long as the previous pervios field is empty KSpreadCell * _c = activeTable()->getNextCellLeft( x, y ); //Found an existing cell, but does it contain something? while ( _c && _c->isEmpty() ) { _c = activeTable()->getNextCellLeft( _c->column(), y ); } //If there is a filled one, use the next if ( _c ) x = _c->column() + 1; //Otherwise go to the first row else x = 1; } } gotoLocation( QMAX( 1, x ), y, 0, make_select, true, true ); } return; //Ctrl+Key_Home case Key_Home: gotoLocation( 1, 1, 0, make_select, true, true ); return; } } /** * Tell the KSpreadView event handler and enable * makro recording by the way. */ // _ev->accept(); // m_pView->eventKeyPressed( _ev, m_bChoose ); } +double KSpreadCanvas::getDouble( KSpreadCell * cell ) +{ + cell->setFactor( 1.0 ); + if ( cell->isDate() ) + { + QDate date = cell->valueDate(); + QDate dummy(1900, 1, 1); + return (dummy.daysTo( date ) + 1); + } + if ( cell->isTime() ) + { + QTime time = cell->valueTime(); + QTime dummy; + return dummy.secsTo( time ); + } + if ( cell->isNumeric() ) + return cell->valueDouble(); + + return 0.0; +} + +void KSpreadCanvas::convertToDouble( KSpreadCell * cell ) +{ + if ( cell->isTime() || cell->isDate() ) + cell->setValue( getDouble( cell ) ); + cell->setFactor( 1.0 ); +} + +void KSpreadCanvas::convertToPercent( KSpreadCell * cell ) +{ + if ( cell->isTime() || cell->isDate() ) + cell->setValue( getDouble( cell ) ); + + cell->setFactor( 100.0 ); + cell->setFormatType( KSpreadCell::Percentage ); +} + +void KSpreadCanvas::convertToMoney( KSpreadCell * cell ) +{ + if ( cell->isTime() || cell->isDate() ) + cell->setValue( getDouble( cell ) ); + + cell->setFormatType( KSpreadCell::Money ); + cell->setFactor( 1.0 ); + cell->setPrecision( m_pDoc->locale()->fracDigits() ); +} + +void KSpreadCanvas::convertToTime( KSpreadCell * cell ) +{ + if ( cell->isDate() ) + cell->setValue( getDouble( cell ) ); + + cell->setFormatType( KSpreadLayout::SecondeTime ); + + QTime time(0, 0, 0); + time = time.addSecs( (int) cell->valueDouble() ); + int msec = (int) ( (cell->valueDouble() - (int) cell->valueDouble())* 1000 ); + time = time.addMSecs( msec ); + cell->setCellText( time.toString() ); +} + +void KSpreadCanvas::convertToDate( KSpreadCell * cell ) +{ + if ( cell->isTime() ) + cell->setValue( getDouble( cell ) ); + + cell->setFormatType( KSpreadLayout::ShortDate ); + cell->setFactor( 1.0 ); + + QDate date(1900, 1, 1); + + date = date.addDays( (int) cell->valueDouble() - 1 ); + cell->setCellText( util_dateFormat(m_pDoc->locale(), date, KSpreadCell::ShortDate) ); +} + +bool KSpreadCanvas::formatKeyPress( QKeyEvent * _ev ) +{ + KSpreadCell * cell = 0L; + KSpreadTable * table = activeTable(); + QRect rect = table->selectionRect(); + bool selected = ( rect.left() != 0 ); + + if ( !selected ) + rect.setCoords( markerColumn(), markerRow(), markerColumn(), markerRow() ); + + int right = rect.right(); + int bottom = rect.bottom(); + + if ( !m_pDoc->undoBuffer()->isLocked() ) + { + QString dummy; + KSpreadUndoCellLayout * undo = new KSpreadUndoCellLayout( m_pDoc, table, rect, dummy ); + m_pDoc->undoBuffer()->appendUndo( undo ); + } + + if ( selected && table->isRowSelected() ) + { + for ( int r = rect.top(); r <= bottom; ++r ) + { + cell = table->getFirstCellRow( r ); + while ( cell ) + { + if ( cell->isObscuringForced() ) + { + cell = table->getNextCellRight( cell->column(), r ); + continue; + } + + QPen pen; + + switch ( _ev->key() ) + { + case Key_Exclam: + convertToDouble( cell ); + cell->setFormatType( KSpreadCell::Number ); + cell->setPrecision( 2 ); + break; + + case Key_Dollar: + convertToMoney( cell ); + break; + + case Key_Percent: + convertToPercent( cell ); + break; + + case Key_At: + convertToTime( cell ); + break; + + case Key_NumberSign: + convertToDate( cell ); + break; + + case Key_AsciiCircum: + cell->setFormatType( KSpreadCell::Scientific ); + convertToDouble( cell ); + cell->setFactor( 1.0 ); + break; + + case Key_Ampersand: + if ( r == rect.top() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cell->setTopBorderPen( pen ); + } + else if ( r == rect.bottom() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cell->setBottomBorderPen( pen ); + } + break; + + default: + return false; + } // switch + + cell = table->getNextCellRight( cell->column(), r ); + } // while (cell) + RowLayout * rw = table->nonDefaultRowLayout( r ); + QPen pen; + switch ( _ev->key() ) + { + case Key_Exclam: + rw->setFormatType( KSpreadCell::Number ); + rw->setPrecision( 2 ); + break; + + case Key_Dollar: + rw->setFormatType( KSpreadCell::Money ); + rw->setFactor( 1.0 ); + rw->setPrecision( m_pDoc->locale()->fracDigits() ); + break; + + case Key_Percent: + rw->setFactor( 100.0 ); + rw->setFormatType( KSpreadCell::Percentage ); + break; + + case Key_At: + rw->setFormatType( KSpreadLayout::SecondeTime ); + rw->setFactor( 1.0 ); + break; + + case Key_NumberSign: + rw->setFormatType( KSpreadLayout::ShortDate ); + rw->setFactor( 1.0 ); + break; + + case Key_AsciiCircum: + rw->setFormatType( KSpreadCell::Scientific ); + rw->setFactor( 1.0 ); + break; + + case Key_Ampersand: + if ( r == rect.top() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + rw->setTopBorderPen( pen ); + } + if ( r == rect.bottom() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + rw->setBottomBorderPen( pen ); + } + break; + + default: + return false; + } + table->emit_updateRow( rw, r ); + } + + return true; + } + + if ( selected && table->isColumnSelected() ) + { + for ( int c = rect.left(); c <= right; ++c ) + { + cell = table->getFirstCellColumn( c ); + while ( cell ) + { + if ( cell->isObscuringForced() ) + { + cell = table->getNextCellDown( c, cell->row() ); + continue; + } + + QPen pen; + switch ( _ev->key() ) + { + case Key_Exclam: + convertToDouble( cell ); + cell->setFormatType( KSpreadCell::Number ); + cell->setPrecision( 2 ); + break; + + case Key_Dollar: + convertToMoney( cell ); + break; + + case Key_Percent: + convertToPercent( cell ); + break; + + case Key_At: + convertToTime( cell ); + break; + + case Key_NumberSign: + convertToDate( cell ); + break; + + case Key_AsciiCircum: + cell->setFormatType( KSpreadCell::Scientific ); + convertToDouble( cell ); + cell->setFactor( 1.0 ); + break; + + case Key_Ampersand: + if ( c == rect.left() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cell->setLeftBorderPen( pen ); + } + else if ( c == rect.right() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cell->setRightBorderPen( pen ); + } + break; + + default: + return false; + } + cell = table->getNextCellDown( c, cell->row() ); + } + + ColumnLayout * cw = table->nonDefaultColumnLayout( c ); + QPen pen; + switch ( _ev->key() ) + { + case Key_Exclam: + cw->setFormatType( KSpreadCell::Number ); + cw->setPrecision( 2 ); + break; + + case Key_Dollar: + cw->setFormatType( KSpreadCell::Money ); + cw->setFactor( 1.0 ); + cw->setPrecision( m_pDoc->locale()->fracDigits() ); + break; + + case Key_Percent: + cw->setFactor( 100.0 ); + cw->setFormatType( KSpreadCell::Percentage ); + break; + + case Key_At: + cw->setFormatType( KSpreadLayout::SecondeTime ); + cw->setFactor( 1.0 ); + break; + + case Key_NumberSign: + cw->setFormatType( KSpreadLayout::ShortDate ); + cw->setFactor( 1.0 ); + break; + + case Key_AsciiCircum: + cw->setFactor( 1.0 ); + cw->setFormatType( KSpreadCell::Scientific ); + break; + + case Key_Ampersand: + if ( c == rect.left() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cw->setLeftBorderPen( pen ); + } + if ( c == rect.right() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cw->setRightBorderPen( pen ); + } + break; + + default: + return false; + } + table->emit_updateColumn( cw, c ); + } + return true; + } + + for ( int row = rect.top(); row <= bottom; ++row ) + { + for ( int col = rect.left(); col <= right; ++ col ) + { + cell = table->nonDefaultCell( col, row ); + + if ( cell->isObscuringForced() ) + continue; + + QPen pen; + switch ( _ev->key() ) + { + case Key_Exclam: + convertToDouble( cell ); + cell->setFormatType( KSpreadCell::Number ); + cell->setPrecision( 2 ); + break; + + case Key_Dollar: + convertToMoney( cell ); + break; + + case Key_Percent: + convertToPercent( cell ); + break; + + case Key_At: + convertToTime( cell ); + break; + + case Key_NumberSign: + convertToDate( cell ); + break; + + case Key_AsciiCircum: + cell->setFormatType( KSpreadCell::Scientific ); + convertToDouble( cell ); + cell->setFactor( 1.0 ); + break; + + case Key_Ampersand: + if ( row == rect.top() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cell->setTopBorderPen( pen ); + } + if ( row == rect.bottom() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cell->setBottomBorderPen( pen ); + } + if ( col == rect.left() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cell->setLeftBorderPen( pen ); + } + if ( col == rect.right() ) + { + pen = QPen( m_pView->borderColor(), 1, SolidLine); + cell->setRightBorderPen( pen ); + } + break; + + default: + return false; + } // switch + } // for left .. right + } // for top .. bottom + table->updateView(rect); + return true; +} + void KSpreadCanvas::doAutoScroll() { if ( !m_bMousePressed) { m_scrollTimer->stop(); return; } bool select = false; QPoint pos( mapFromGlobal( QCursor::pos() ) ); if ( pos.y() < 0 ) { vertScrollBar()->setValue(vertScrollBar()->value() - 20); select = true; } else if ( pos.y() > height() ) { vertScrollBar()->setValue(vertScrollBar()->value() + 20); select = true; } if ( pos.x() < 0 ) { horzScrollBar()->setValue(horzScrollBar()->value() - 20); select = true; } else if ( pos.x() > width() ) { horzScrollBar()->setValue(horzScrollBar()->value() + 20); select = true; } if (select) { QMouseEvent * event = new QMouseEvent(QEvent::MouseMove, pos, 0, 0); mouseMoveEvent(event); delete event; } } void KSpreadCanvas::deleteEditor( bool saveChanges ) { if( !m_pEditor ) return; // We need to set the line-edit out of edit mode, // but only if we are using it (text editor) // A bit of a hack - perhaps we should store the editor mode ? bool textEditor=true; int newHeight = -1; int row = -1; if ( m_pEditor->inherits("KSpreadTextEditor") ) { if ( m_pEditor->cell()->height() < m_pEditor->height() ) { if (((KSpreadTextEditor * ) m_pEditor)->sizeUpdate()) { newHeight = m_pEditor->height(); row = m_pEditor->cell()->row(); } } m_pEditWidget->setEditMode( false ); } else textEditor=false; QString t = m_pEditor->text(); // Delete the cell editor first and after that update the document. // That means we get a synchronous repaint after the cell editor // widget is gone. Otherwise we may get painting errors. delete m_pEditor; m_pEditor = 0; if (saveChanges && textEditor) m_pView->setText( t ); else m_pView->updateEditWidget(); if (newHeight != -1) m_pView->vBorderWidget()->resizeRow(newHeight, row, true); setFocus(); } void KSpreadCanvas::createEditor() { KSpreadCell* cell = activeTable()->cellAt( markerColumn(), markerRow() ); createEditor( CellEditor ); if ( cell ) m_pEditor->setText(cell->text()); } void KSpreadCanvas::createEditor( EditorType ed, bool addFocus) { KSpreadTable *table = activeTable(); if ( !m_pEditor ) { KSpreadCell* cell = activeTable()->cellAt( marker() ); if ( ed == CellEditor ) { m_pEditWidget->setEditMode( true ); m_pEditor = new KSpreadTextEditor( cell, this ); } int w, h; int min_w = cell->width( markerColumn(), this ); int min_h = cell->height( markerRow(), this ); if ( cell->isDefault() ) { w = min_w; h = min_h; //kdDebug(36001) << "DEFAULT" << endl; } else { w = cell->extraWidth() + 1; h = cell->extraHeight() + 1; //kdDebug(36001) << "HEIGHT=" << min_h << " EXTRA=" << h << endl; } int xpos = table->columnPos( markerColumn(), this ); int ypos = table->rowPos( markerRow(), this ); QPalette p = m_pEditor->palette(); QColorGroup g( p.active() ); QColor color=cell->textColor( markerColumn(), markerRow() ); if(!color.isValid()) color=QApplication::palette().active().text(); g.setColor( QColorGroup::Text, color); color=cell->bgColor( markerColumn(), markerRow() ); if(!color.isValid()) color=g.base(); g.setColor( QColorGroup::Background, color ); m_pEditor->setPalette( QPalette( g, p.disabled(), g ) ); m_pEditor->setFont( cell->textFont( markerColumn(), markerRow() ) ); m_pEditor->setGeometry( xpos, ypos, w, h ); m_pEditor->setMinimumSize( QSize( min_w, min_h ) ); m_pEditor->show(); //kdDebug(36001) << "FOCUS1" << endl; //Laurent 2001-12-05 //Don't add focus when we create a new editor and //we select text in edit widget otherwise we don't delete //selected text. if(addFocus) m_pEditor->setFocus(); //kdDebug(36001) << "FOCUS2" << endl; } } void KSpreadCanvas::closeEditor() { if(m_bChoose) return; if ( m_pEditor ) { deleteEditor( true ); // save changes } } //--------------------------------------------- // // Drawing Engine // //--------------------------------------------- void KSpreadCanvas::updateCellRect( const QRect &_rect ) { updateSelection( _rect, activeTable()->markerRect() ); } void KSpreadCanvas::updateSelection( const QRect &_old_sel, const QRect& old_marker ) { KSpreadTable *table = activeTable(); if ( !table ) return; /* two areas that indicate the areas needing repainting */ QRect oldSelectionArea; QRect newSelectionArea; // If old selection was empty -> Just use the marker oldSelectionArea = old_marker; if ( _old_sel.left() != 0 ) { oldSelectionArea = oldSelectionArea.unite(_old_sel); } // If new selection was empty -> Just use the marker newSelectionArea = table->markerRect(); if ( table->selectionRect().left() != 0 ) { newSelectionArea = newSelectionArea.unite(table->selectionRect()); } /* since the marker/selection border extends into neighboring cells, we want to calculate all the cells bordering these regions. */ ExtendRectBorder(oldSelectionArea); ExtendRectBorder(newSelectionArea); /* Prepare the painter */ QPainter painter; painter.begin( this ); // Do the view transformation. QWMatrix m = m_pView->matrix(); painter.setWorldMatrix( m ); // Which part of the document is visible ? To determine this // just transform the viewport rectangle with the inverse // matrix, since this matrix usually transforms from document // coordinates to view coordinates. m = m.invert(); QPoint tl = m.map( QPoint( 0, 0 ) ); QPoint br = m.map( QPoint( width(), height() ) ); QRect view( tl, br ); // // Clip away children // QRegion rgn = painter.clipRegion(); if ( rgn.isEmpty() ) rgn = QRegion( QRect( 0, 0, width(), height() ) ); QPtrListIterator it( m_pDoc->children() ); for( ; it.current(); ++it ) { if ( ((KSpreadChild*)it.current())->table() == activeTable() && !m_pView->hasDocumentInWindow( it.current()->document() ) ) rgn -= it.current()->region( painter.worldMatrix() ); } painter.setClipRegion( rgn ); QPen pen; pen.setWidth( 1 ); painter.setPen( pen ); PaintRegion(oldSelectionArea, view, painter); PaintRegion(newSelectionArea, view, painter); painter.end(); // XIM Position int xpos_xim, ypos_xim; xpos_xim = table->columnPos( markerColumn(), this ); ypos_xim = table->rowPos( markerRow(), this ); setMicroFocusHint(xpos_xim, ypos_xim, 0, 16); } void KSpreadCanvas::ExtendRectBorder(QRect& area) { ColumnLayout *cl; RowLayout *rl; //look at if column is hiding. //if it's hiding refreshing column+1 (or column -1 ) int left = area.left(); int right = area.right(); int top = area.top(); int bottom = area.bottom(); if ( right < KS_colMax ) { do { right++; cl = activeTable()->nonDefaultColumnLayout( right ); } while( cl->isHide() && right != KS_colMax ); } if ( left > 1 ) { do { left--; cl = activeTable()->nonDefaultColumnLayout( left ); } while( cl->isHide() && left != 1); } if ( bottom < KS_rowMax ) { do { bottom++; rl = activeTable()->nonDefaultRowLayout( bottom ); } while( rl->isHide() && bottom != KS_rowMax ); } if ( top > 1 ) { do { top--; rl = activeTable()->nonDefaultRowLayout( top ); } while( rl->isHide() && top != 1); } area.setLeft(left); area.setRight(right); area.setTop(top); area.setBottom(bottom); } void KSpreadCanvas::PaintRegion(QRect paintRegion, QRect viewRegion, QPainter &painter) { /* paint region has cell coordinates (col,row) while viewRegion has world coordinates. paintRegion is the cells to update and viewRegion is the area actually onscreen. */ KSpreadTable *table = activeTable(); /* get the world coordinates of the upper left corner of the paintRegion */ QPoint corner(table->columnPos(paintRegion.left()), table->rowPos(paintRegion.top())); QPoint currentCellPos = corner; for ( int y = paintRegion.top(); y <= paintRegion.bottom() && currentCellPos.y() <= viewRegion.bottom(); y++ ) { RowLayout *row_lay = table->rowLayout( y ); currentCellPos.setX(corner.x()); for ( int x = paintRegion.left(); x <= paintRegion.right() && currentCellPos.x() <= viewRegion.right(); x++ ) { ColumnLayout *col_lay = table->columnLayout( x ); KSpreadCell *cell = table->cellAt( x, y ); QPoint cellCoordinate( x, y ); cell->paintCell( viewRegion, painter, currentCellPos, cellCoordinate); currentCellPos.setX(currentCellPos.x() + col_lay->width()); } currentCellPos.setY(currentCellPos.y() + row_lay->height()); } } //--------------------------------------------- // // Choose Marker // //--------------------------------------------- void KSpreadCanvas::updateChooseMarker( const QRect& _old, const QRect& _new ) { if ( isChooseMarkerVisible() ) { drawChooseMarker( _old ); drawChooseMarker( _new ); } else { choose_visible = TRUE; drawChooseMarker( _new ); } if ( _new.left() == 0 || !m_bChoose || !m_pEditor ) { //kdDebug(36001) << "updateChooseMarker len=0" << endl; length_namecell = 0; return; } KSpreadTable* table = activeTable(); // ##### Torben: Clean up here! QString name_cell; //kdDebug(36001) << m_chooseStartTable->tableName() << ", " // << table->tableName() << endl; if( m_chooseStartTable != table ) { if ( _new.left() >= _new.right() && _new.top() >= _new.bottom() ) name_cell = util_cellName( table, _new.left(), _new.top() ); else name_cell = util_rangeName( table, _new ); } else { if ( _new.left() >= _new.right() && _new.top() >= _new.bottom() ) name_cell = util_cellName( _new.left(), _new.top() ); else name_cell = util_rangeName( _new ); } int old = length_namecell; length_namecell= name_cell.length(); length_text = m_pEditor->text().length(); //kdDebug(36001) << "updateChooseMarker2 len=" << length_namecell << endl; QString text = m_pEditor->text(); QString res = text.left( m_pEditor->cursorPosition() - old ) + name_cell + text.right( text.length() - m_pEditor->cursorPosition() ); int pos = m_pEditor->cursorPosition() - old; ((KSpreadTextEditor*)m_pEditor)->blockCheckChoose( TRUE ); m_pEditor->setText( res ); ((KSpreadTextEditor*)m_pEditor)->blockCheckChoose( FALSE ); m_pEditor->setCursorPosition( pos + length_namecell ); //kdDebug(36001) << "old=" << old << " len=" << length_namecell << " pos=" << pos << endl; } void KSpreadCanvas::updatePosWidget() { QRect selection = m_pView->activeTable()->selectionRect(); QString buffer; QString tmp; KSpreadCell *cell=activeTable()->cellAt( markerColumn(), markerRow() ); QRect extraCell; extraCell.setCoords(markerColumn(),markerRow(), markerColumn()+cell->extraXCells(),markerRow()+cell->extraYCells()); // No selection, or only one cell merged selected if ( selection.left() == 0 || extraCell==selection ) { if(activeTable()->getLcMode()) { buffer="L"+tmp.setNum( markerRow() ); buffer+="C"+tmp.setNum( markerColumn() ); } else { buffer=util_encodeColumnLabelText( markerColumn() ); buffer+=tmp.setNum( markerRow() ); } } /*else if((!activeTable->isRowSelected( selection.) && (!activeTable->isColumnSelected( selection.)) { if(activeTable()->getLcMode()) { buffer=tmp.setNum( (selection.bottom()-m_iMarkerRow+1) )+"Lx"; buffer+=tmp.setNum((selection.right()-m_iMarkerColumn+1))+"C"; } else { buffer=util_encodeColumnLabelText( m_iMarkerColumn ); buffer+=tmp.setNum(m_iMarkerRow); buffer+=":"; buffer+=util_encodeColumnLabelText( selection.right() ); buffer+=tmp.setNum(selection.bottom()); } }*/ else { if(activeTable()->getLcMode()) { buffer=tmp.setNum( (selection.bottom()-selection.top()+1) )+"Lx"; if( activeTable()->isRowSelected( selection ) ) buffer+=tmp.setNum((KS_colMax-selection.left()+1))+"C"; else buffer+=tmp.setNum((selection.right()-selection.left()+1))+"C"; } else { //encodeColumnLabelText return @@@@ when column >KS_colMax //=> it's not a good display //=> for the moment I display pos of marker buffer=util_encodeColumnLabelText( selection.left() ); buffer+=tmp.setNum(selection.top()); buffer+=":"; buffer+=util_encodeColumnLabelText( QMIN( KS_colMax, selection.right() ) ); buffer+=tmp.setNum(selection.bottom()); //buffer=activeTable()->columnLabel( m_iMarkerColumn ); //buffer+=tmp.setNum(m_iMarkerRow); } } m_pPosWidget->setText(buffer); } void KSpreadCanvas::drawChooseMarker() { drawChooseMarker( activeTable()->chooseRect() ); } void KSpreadCanvas::drawChooseMarker( const QRect& selection ) { // Draw nothing if the selection is empty if ( selection.left() == 0 ) return; QPainter painter; painter.begin( this ); int xpos; int ypos; int w, h; if ( selection.left() == 0 || activeTable()->isRowSelected( selection ) || activeTable()->isColumnSelected( selection ) ) { xpos = activeTable()->columnPos( chooseMarkerColumn(), this ); ypos = activeTable()->rowPos( chooseMarkerRow(), this ); KSpreadCell *cell = activeTable()->cellAt( chooseMarkerColumn(), chooseMarkerRow() ); w = cell->width( chooseMarkerColumn(), this ); h = cell->height( chooseMarkerRow(), this ); } else { xpos = activeTable()->columnPos( selection.left(), this ); ypos = activeTable()->rowPos( selection.top(), this ); int x = activeTable()->columnPos( selection.right(), this ); KSpreadCell *cell = activeTable()->cellAt( selection.right(), selection.top() ); int tw = cell->width( selection.right(), this ); w = ( x - xpos ) + tw; cell = activeTable()->cellAt( selection.left(), selection.bottom() ); int y = activeTable()->rowPos( selection.bottom(), this ); int th = cell->height( selection.bottom(), this ); h = ( y - ypos ) + th; } RasterOp rop = painter.rasterOp(); painter.setRasterOp( NotROP ); QPen pen; pen.setWidth( 2 ); pen.setStyle(DashLine); painter.setPen( pen ); painter.drawLine( xpos - 2, ypos - 1, xpos + w + 2, ypos - 1 ); painter.drawLine( xpos - 1, ypos + 1, xpos - 1, ypos + h + 3 ); painter.drawLine( xpos + 1, ypos + h + 1, xpos + w - 3, ypos + h + 1 ); painter.drawLine( xpos + w, ypos + 1, xpos + w, ypos + h - 2 ); // painter.fillRect( xpos + w - 2, ypos + h - 1, 5, 5, black ); painter.setRasterOp( rop ); painter.end(); } void KSpreadCanvas::setChooseMarker( const QPoint& p ) { if ( p.x() == m_i_chooseMarkerColumn && p.y() == m_i_chooseMarkerRow ) return; m_i_chooseMarkerRow = p.y(); m_i_chooseMarkerColumn = p.x(); // This will trigger a redraw activeTable()->setChooseRect( QRect( p.x(), p.y(), 1, 1 ) ); } void KSpreadCanvas::adjustArea(bool makeUndo) { QRect selection( activeTable()->selectionRect() ); QRect rect=selection; if(activeTable()->areaIsEmpty()) return; if(selection.left() == 0) rect.setCoords(markerColumn(),markerRow(),markerColumn(),markerRow() ); if(makeUndo) { if ( !doc()->undoBuffer()->isLocked() ) { KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( doc(),activeTable() , rect ); doc()->undoBuffer()->appendUndo( undo ); } } // Columns selected if( activeTable()->isColumnSelected() ) { for (int x=selection.left(); x <= selection.right(); x++ ) { hBorderWidget()->adjustColumn(x,false); } } // Rows selected else if( activeTable()->isRowSelected() ) { for(int y = selection.top(); y <= selection.bottom(); y++ ) { vBorderWidget()->adjustRow(y,false); } } // No selection else if( selection.left() == 0 || selection.top() == 0 || selection.bottom() == 0 || selection.right() == 0 ) { vBorderWidget()->adjustRow(markerRow(),false); hBorderWidget()->adjustColumn(markerColumn(),false); } // Selection of a rectangular area else { for (int x=selection.left(); x <= selection.right(); x++ ) { hBorderWidget()->adjustColumn(x,false); } for(int y = selection.top(); y <= selection.bottom(); y++ ) { vBorderWidget()->adjustRow(y,false); } } } void KSpreadCanvas::equalizeRow() { QRect selection( activeTable()->selectionRect() ); bool selected = ( selection.left() != 0 ); RowLayout *rl; int size; if(selected) { rl = m_pView->activeTable()->rowLayout(selection.top()); size=rl->height(this); for(int i=selection.top()+1;i<=selection.bottom();i++) size=QMAX(m_pView->activeTable()->rowLayout(i)->height(this),size); m_pView->vBorderWidget()->equalizeRow(size); } } void KSpreadCanvas::equalizeColumn() { ColumnLayout *cl; QRect selection( activeTable()->selectionRect() ); bool selected = ( selection.left() != 0 ); int size; if(selected) { cl = m_pView->activeTable()->columnLayout(selection.left()); size=cl->width(this); for(int i=selection.left()+1;i<=selection.right();i++) size=QMAX(m_pView->activeTable()->columnLayout(i)->width(this),size); m_pView->hBorderWidget()->equalizeColumn(size); } } /**************************************************************** * * KSpreadVBorder * ****************************************************************/ KSpreadVBorder::KSpreadVBorder( QWidget *_parent, KSpreadCanvas *_canvas, KSpreadView *_view) : QWidget( _parent, "", /*WNorthWestGravity*/WStaticContents | WResizeNoErase | WRepaintNoErase ) { m_pView = _view; m_pCanvas = _canvas; m_lSize = 0L; setBackgroundMode( PaletteButton ); setMouseTracking( TRUE ); m_bResize = FALSE; m_bSelection = FALSE; m_iSelectionAnchor=1; } void KSpreadVBorder::mousePressEvent( QMouseEvent * _ev ) { m_bResize = FALSE; m_bSelection = FALSE; if(!m_pView->koDocument()->isReadWrite()) return; KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); // We were editing a cell -> save value and get out of editing mode if ( m_pCanvas->editor() ) { m_pCanvas->deleteEditor( true ); // save changes } // Find the first visible row and the y position of this row. int y = 0; int row = table->topRow( 0, y, m_pCanvas ); // Did the user click between two rows ? while ( y < height() ) { int h = table->rowLayout( row )->height( m_pCanvas ); row++; if ( row > KS_rowMax ) row = KS_rowMax; if ( _ev->pos().y() >= y + h - 1 && _ev->pos().y() <= y + h + 1 && !(table->rowLayout( row )->isHide()&&row==1) ) m_bResize = TRUE; y += h; } int tmp2; int tmpRow=table->topRow( _ev->pos().y() - 1, tmp2, m_pCanvas ); if(table->rowLayout(tmpRow )->isHide()&&tmpRow==1) m_bResize = false; // So he clicked between two rows ? if ( m_bResize ) { // Determine row to resize int tmp; m_iResizedRow = table->topRow( _ev->pos().y() - 1, tmp, m_pCanvas ); paintSizeIndicator( _ev->pos().y(), true ); } else { m_bSelection = TRUE; int tmp; int hit_row = table->topRow( _ev->pos().y(), tmp, m_pCanvas ); if(hit_row > KS_rowMax) return; m_iSelectionAnchor = hit_row; QRect rect = m_pCanvas->activeTable()->selectionRect(); QRect selection; if(!rect.contains( QPoint(1,hit_row)) || !(_ev->button() == RightButton) || (!m_pCanvas->activeTable()->isRowSelected()) ) { selection.setCoords( 1, hit_row, KS_colMax, hit_row ); table->setSelection( selection, m_pCanvas ); } if ( _ev->button() == RightButton ) { QPoint p = mapToGlobal( _ev->pos() ); m_pView->popupRowMenu( p ); m_bSelection=FALSE; } m_pView->updateEditWidget(); } } void KSpreadVBorder::mouseReleaseEvent( QMouseEvent * _ev ) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); if( !m_pView->koDocument()->isReadWrite() ) return; if ( m_bResize ) { // Remove size indicator painted by paintSizeIndicator QPainter painter; painter.begin( m_pCanvas ); painter.setRasterOp( NotROP ); painter.drawLine( 0, m_iResizePos, m_pCanvas->width(), m_iResizePos ); painter.end(); int start = m_iResizedRow; int end = m_iResizedRow; QRect selection = m_pCanvas->activeTable()->selectionRect(); QRect rect; rect.setCoords( 1, m_iResizedRow, KS_colMax, m_iResizedRow ); if( m_pCanvas->activeTable()->isRowSelected() ) { if( selection.contains( QPoint( 1, m_iResizedRow ) ) ) { start=selection.top(); end=selection.bottom(); rect=selection; } } int height = 0; int y = table->rowPos( m_iResizedRow, m_pCanvas ); if (( m_pCanvas->zoom() * (float)( _ev->pos().y() - y ) ) <=0 /*(2.0* m_pCanvas->zoom())*/) height = 0 /*(int)(2.0* m_pCanvas->zoom())*/; else height = _ev->pos().y() - y; if ( !m_pCanvas->doc()->undoBuffer()->isLocked() ) { if(height!=0) { KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(),m_pCanvas->activeTable() , rect ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } else { //hide row KSpreadUndoHideRow *undo = new KSpreadUndoHideRow( m_pCanvas->doc(),m_pCanvas->activeTable() , rect.top(),(rect.bottom()-rect.top()) ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } } for(int i = start; i <= end; i++ ) { RowLayout *rl = table->nonDefaultRowLayout( i ); if(height!=0) { if(!rl->isHide()) rl->setHeight( height, m_pCanvas ); } else rl->setHide(true ); } if(height==0) table->emitHideColumn(); delete m_lSize; m_lSize = 0; } else if (m_bSelection) { QRect rect = table->selectionRect(); // TODO: please don't remove. Right now it's useless, but it's for a future feature // Norbert bool m_frozen = false; if ( m_frozen ) { kdDebug(36001) << "selected: T " << rect.top() << " B " << rect.bottom() << endl; int i; RowLayout * row; QValueListhiddenRows; for ( i = rect.top(); i <= rect.bottom(); ++i ) { row = m_pView->activeTable()->rowLayout( i ); if ( row->isHide() ) { hiddenRows.append(i); } } if (hiddenRows.count() > 0) m_pView->activeTable()->showRow(0, -1, hiddenRows); } } m_bSelection = FALSE; m_bResize = FALSE; } void KSpreadVBorder::adjustRow( int _row, bool makeUndo ) { int adjust; int select; if(_row==-1) { adjust=m_pCanvas->activeTable()->adjustRow(QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() )); select=m_iSelectionAnchor; } else { adjust=m_pCanvas->activeTable()->adjustRow(QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ),_row); select=_row; } if(adjust!=-1) { if(makeUndo && !m_pCanvas->doc()->undoBuffer()->isLocked() ) { QRect rect; rect.setCoords( 1, select, KS_colMax, select); KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(),m_pCanvas->activeTable() , rect ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); RowLayout *rl = table->nonDefaultRowLayout( select ); adjust=QMAX((int)(2.0* m_pCanvas->zoom()),adjust); rl->setHeight(adjust,m_pCanvas); } } void KSpreadVBorder::equalizeRow( int resize ) { KSpreadTable *table = m_pCanvas->activeTable(); Q_ASSERT( table ); QRect selection( table->selectionRect() ); if ( !m_pCanvas->doc()->undoBuffer()->isLocked() ) { KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(),m_pCanvas->activeTable() , selection ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } RowLayout *rl; for (int i=selection.top();i<=selection.bottom();i++) { rl= table->nonDefaultRowLayout( i ); resize=QMAX((int)(2.0* m_pCanvas->zoom()), resize); rl->setHeight( resize, m_pCanvas ); } } void KSpreadVBorder::resizeRow( int resize, int nb, bool makeUndo ) { KSpreadTable *table = m_pCanvas->activeTable(); Q_ASSERT( table ); if( nb == -1 ) // I don't know, where this is the case { if( makeUndo && !m_pCanvas->doc()->undoBuffer()->isLocked() ) { QRect rect; rect.setCoords( 1, m_iSelectionAnchor, KS_colMax, m_iSelectionAnchor ); KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(), m_pCanvas->activeTable(), rect ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } RowLayout *rl = table->nonDefaultRowLayout( m_iSelectionAnchor ); resize = QMAX( (int)(2.0* m_pCanvas->zoom()), resize ); rl->setHeight( resize, m_pCanvas ); } else { QRect selection( table->selectionRect() ); if( selection.bottom()==0 ||selection.top()==0 || selection.left()==0 || selection.right()==0 ) { if( makeUndo && !m_pCanvas->doc()->undoBuffer()->isLocked() ) { QRect rect; rect.setCoords( 1, m_pCanvas->markerRow(), KS_colMax, m_pCanvas->markerRow() ); KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(), m_pCanvas->activeTable(), rect ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } RowLayout *rl = table->nonDefaultRowLayout( m_pCanvas->markerRow() ); resize=QMAX((int)(2.0* m_pCanvas->zoom()), resize); rl->setHeight( resize, m_pCanvas ); } else { if(makeUndo && !m_pCanvas->doc()->undoBuffer()->isLocked() ) { KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(), m_pCanvas->activeTable(), selection ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } RowLayout *rl; for ( int i=selection.top(); i<=selection.bottom(); i++ ) { rl = table->nonDefaultRowLayout( i ); resize=QMAX((int)(2.0* m_pCanvas->zoom()), resize); rl->setHeight( resize, m_pCanvas ); } } } } void KSpreadVBorder::mouseMoveEvent( QMouseEvent * _ev ) { if(!m_pView->koDocument()->isReadWrite()) return; KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); // The button is pressed and we are resizing ? if ( m_bResize ) { paintSizeIndicator( _ev->pos().y(), false ); } // The button is pressed and we are selecting ? else if ( m_bSelection ) { int y = 0; int row = table->topRow( _ev->pos().y(), y, m_pCanvas ); if( row > KS_rowMax ) return; QRect selection = table->selectionRect(); if ( row < m_iSelectionAnchor ) { selection.setTop( row ); selection.setBottom( m_iSelectionAnchor ); } else { selection.setBottom( row ); selection.setTop( m_iSelectionAnchor ); } table->setSelection( selection, m_pCanvas ); if ( _ev->pos().y() < 0 ) m_pCanvas->vertScrollBar()->setValue( m_pCanvas->yOffset() + y ); else if ( _ev->pos().y() > m_pCanvas->height() ) { if (row < KS_rowMax) { RowLayout *rl = table->rowLayout( row + 1 ); y = table->rowPos( row + 1, m_pCanvas ); m_pCanvas->vertScrollBar()->setValue( m_pCanvas->yOffset() + y + rl->height( m_pCanvas ) - m_pCanvas->height() ); } } } // No button is pressed and the mouse is just moved else { int tmp; int tmpRow = table->topRow( _ev->pos().y() - 1, tmp, m_pCanvas ); int ypos = _ev->pos().y(); if ( ( (table->topRow( ( ypos - 1), tmp, m_pCanvas ) != tmpRow) || (table->topRow( ( ypos - 1) + 3, tmp, m_pCanvas ) != tmpRow) ) && !(table->rowLayout(tmpRow)->isHide() && tmpRow == 1) ) { setCursor(splitVCursor); return; } /* Doesn't work correctly, gets removed if it turns out that the new version really works, Norbert while ( y < height() ) { int h = table->rowLayout( row )->height( m_pCanvas ); if ( _ev->pos().y() >= y + h - 1 && _ev->pos().y() <= y + h + 1 &&!(table->rowLayout(tmpRow)->isHide()&&tmpRow==1)) { setCursor(splitVCursor); return; } y += h; } */ setCursor( arrowCursor ); } } void KSpreadVBorder::mouseDoubleClickEvent( QMouseEvent * /*_ev */) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); if(!m_pView->koDocument()->isReadWrite()) return; adjustRow(); } void KSpreadVBorder::wheelEvent( QWheelEvent* _ev ) { if ( m_pCanvas->vertScrollBar() ) QApplication::sendEvent( m_pCanvas->vertScrollBar(), _ev ); } void KSpreadVBorder::paintSizeIndicator( int mouseY, bool firstTime ) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); QPainter painter; painter.begin( m_pCanvas ); painter.setRasterOp( NotROP ); if (!firstTime) painter.drawLine( 0, m_iResizePos, m_pCanvas->width(), m_iResizePos ); m_iResizePos = mouseY; // Dont make the row have a height < 2 pixel. //int twenty = (int)( 2.0 * m_pCanvas->zoom() ); int y = table->rowPos( m_iResizedRow, m_pCanvas ); if ( m_iResizePos < y /*+ twenty*/ ) m_iResizePos = y /*+ twenty*/; painter.drawLine( 0, m_iResizePos, m_pCanvas->width(), m_iResizePos ); painter.end(); QString tmpSize; if(m_iResizePos!=y) tmpSize=i18n("Height: %1 %2").arg(KoUnit::ptToUnit(((m_iResizePos-y)/m_pCanvas->zoom()) ,m_pView->doc()->getUnit() )).arg(m_pView->doc()->getUnitName()); else tmpSize=i18n("Hide Row"); painter.begin(this); int len = painter.fontMetrics().width(tmpSize ); int hei = painter.fontMetrics().height( ); painter.end(); if(!m_lSize) { m_lSize=new QLabel(m_pCanvas); m_lSize->setGeometry(3,3+y,len+2, hei+2 ) ; m_lSize->setAlignment(Qt::AlignVCenter); m_lSize->setText(tmpSize); m_lSize->show(); } else { m_lSize->setGeometry(3,3+y,len+2, hei+2 ); m_lSize->setText(tmpSize); } } void KSpreadVBorder::paintEvent( QPaintEvent* _ev ) { KSpreadTable *table = m_pCanvas->activeTable(); if ( !table ) return; QPainter painter; painter.begin( this ); QPen pen; pen.setWidth( 1 ); painter.setPen( pen ); // painter.setBackgroundColor( colorGroup().base() ); // painter.eraseRect( _ev->rect() ); //QFontMetrics fm = painter.fontMetrics(); // Matthias Elter: This causes a SEGFAULT in ~QPainter! // Only god and the trolls know why ;-) // bah...took me quite some time to track this one down... painter.setClipRect( _ev->rect() ); int ypos; int top_row = table->topRow( _ev->rect().y(), ypos, m_pCanvas ); int bottom_row = table->bottomRow( _ev->rect().bottom(), m_pCanvas ); QRect selection( table->selectionRect() ); QFont normalFont = painter.font(); QFont boldFont = normalFont; boldFont.setBold( TRUE ); KSpreadCell *cell=table->cellAt( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); QRect extraCell; extraCell.setCoords(m_pCanvas->markerColumn(),m_pCanvas->markerRow(), m_pCanvas->markerColumn()+cell->extraXCells(),m_pCanvas->markerRow()+cell->extraYCells()); //several cells selected but not just a cell merged bool area= (selection.left() != 0 && extraCell!=selection); for ( int y = top_row; y <= bottom_row; y++ ) { bool highlighted = (area && y >= selection.top() && y <= selection.bottom() ); bool selected = ( highlighted && (table->isRowSelected()) ); RowLayout *row_lay = table->rowLayout( y ); if ( selected ) { QBrush fillSelected( colorGroup().brush( QColorGroup::Highlight ) ); qDrawShadePanel( &painter, 0, ypos, YBORDER_WIDTH, row_lay->height( m_pCanvas ), colorGroup(), FALSE, 1, &fillSelected ); } else if ( highlighted ) { QBrush fillHighlighted( colorGroup().brush( QColorGroup::Background ) ); qDrawShadePanel( &painter, 0, ypos, YBORDER_WIDTH, row_lay->height( m_pCanvas ), colorGroup(), true, 1, &fillHighlighted ); } else { QBrush fill( colorGroup().brush( QColorGroup::Background ) ); qDrawShadePanel( &painter, 0, ypos, YBORDER_WIDTH, row_lay->height( m_pCanvas ), colorGroup(), FALSE, 1, &fill ); } char buffer[ 20 ]; sprintf( buffer, "%i", y ); // Reset painter painter.setFont( normalFont ); painter.setPen( colorGroup().text() ); if ( selected ) painter.setPen( colorGroup().highlightedText() ); else if ( highlighted ) painter.setFont( boldFont ); int len = painter.fontMetrics().width(buffer ); if(!row_lay->isHide()) painter.drawText( (YBORDER_WIDTH-len)/2, ypos + ( row_lay->height( m_pCanvas ) + painter.fontMetrics().ascent() - painter.fontMetrics().descent() ) / 2, buffer ); ypos += row_lay->height( m_pCanvas ); } m_pCanvas->updatePosWidget(); painter.end(); } /**************************************************************** * * KSpreadHBorder * ****************************************************************/ KSpreadHBorder::KSpreadHBorder( QWidget *_parent, KSpreadCanvas *_canvas,KSpreadView *_view ) : QWidget( _parent, "", /*WNorthWestGravity*/ WStaticContents| WResizeNoErase | WRepaintNoErase ) { m_pView = _view; m_pCanvas = _canvas; m_lSize = 0L; setBackgroundMode( PaletteButton ); setMouseTracking( TRUE ); m_bResize = FALSE; m_bSelection = FALSE; m_iSelectionAnchor=1; } void KSpreadHBorder::mousePressEvent( QMouseEvent * _ev ) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); if(!m_pView->koDocument()->isReadWrite()) return; // We were editing a cell -> save value and get out of editing mode if ( m_pCanvas->editor() ) { m_pCanvas->deleteEditor( true ); // save changes } m_bResize = FALSE; m_bSelection = FALSE; int x = 0; int col = table->leftColumn( 0, x, m_pCanvas ); while ( x < width() && !m_bResize ) { int w = table->columnLayout( col )->width( m_pCanvas ); col++; if ( col > KS_colMax ) col = KS_colMax; if ( _ev->pos().x() >= x + w - 1 && _ev->pos().x() <= x + w + 1 && !(table->columnLayout( col )->isHide()&&col==1)) m_bResize = TRUE; x += w; } //if col is hide and it's the first column //you mustn't resize it. int tmp2; int tmpCol=table->leftColumn( _ev->pos().x() - 1, tmp2, m_pCanvas ); if ( table->columnLayout(tmpCol )->isHide() && tmpCol == 1) m_bResize = false; QRect rect = table->selectionRect(); if ( m_bResize ) { // Determine the column to resize int tmp; m_iResizedColumn = table->leftColumn( _ev->pos().x() - /*3*/1, tmp, m_pCanvas ); paintSizeIndicator( _ev->pos().x(), true ); } else if ( ( rect.left() != rect.right() ) && ( tmpCol >= rect.left() ) && ( tmpCol <= rect.right() ) && _ev->button() == RightButton ) { QPoint p = mapToGlobal( _ev->pos() ); m_pView->popupColumnMenu( p ); } else { m_bSelection = TRUE; int tmp; int hit_col = table->leftColumn( _ev->pos().x(), tmp, m_pCanvas ); if( hit_col > KS_colMax) return; m_iSelectionAnchor = hit_col; QRect r; if(!rect.contains( QPoint(hit_col,1)) || !(_ev->button() == RightButton) || !(table->isRowSelected()) ) { r.setCoords( hit_col, 1, hit_col, KS_rowMax ); table->setSelection( r, m_pCanvas ); } if ( _ev->button() == RightButton ) { QPoint p = mapToGlobal( _ev->pos() ); m_pView->popupColumnMenu( p ); m_bSelection=FALSE; } m_pView->updateEditWidget(); } } void KSpreadHBorder::mouseReleaseEvent( QMouseEvent * _ev ) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); if(!m_pView->koDocument()->isReadWrite()) return; if ( m_bResize ) { // Remove size indicator painted by paintSizeIndicator QPainter painter; painter.begin( m_pCanvas ); painter.setRasterOp( NotROP ); painter.drawLine( m_iResizePos, 0, m_iResizePos, m_pCanvas->height() ); painter.end(); int start=m_iResizedColumn; int end=m_iResizedColumn; QRect selection = m_pCanvas->activeTable()->selectionRect(); QRect rect; rect.setCoords( m_iResizedColumn, 1, m_iResizedColumn, KS_rowMax ); if( m_pCanvas->activeTable()->isColumnSelected() ) { if(selection.contains(QPoint(m_iResizedColumn,1))) { start=selection.left(); end=selection.right(); rect=selection; } } int width=0; int x = table->columnPos( m_iResizedColumn, m_pCanvas ); if ( ( m_pCanvas->zoom() * (float)( _ev->pos().x() - x ) ) <=0.0 ) width= 0 ; /*(int)(2.0* m_pCanvas->zoom());*/ else width=_ev->pos().x() - x; if ( !m_pCanvas->doc()->undoBuffer()->isLocked() ) { //juste resize if(width!=0) { KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(),m_pCanvas->activeTable() , rect ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } else {//hide column KSpreadUndoHideColumn *undo = new KSpreadUndoHideColumn( m_pCanvas->doc(), m_pCanvas->activeTable(),rect.left(),(rect.right()-rect.left())); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } } for(int i=start;i<=end;i++) { ColumnLayout *cl = table->nonDefaultColumnLayout( i ); if( width!=0) { if(!cl->isHide()) cl->setWidth( width, m_pCanvas ); } else cl->setHide(true); } if(width==0) table->emitHideRow(); delete m_lSize; m_lSize=0; } else if (m_bSelection) { QRect rect = table->selectionRect(); // TODO: please don't remove. Right now it's useless, but it's for a future feature // Norbert bool m_frozen = false; if ( m_frozen ) { kdDebug(36001) << "selected: L " << rect.left() << " R " << rect.right() << endl; int i; ColumnLayout * col; QValueListhiddenCols; for ( i = rect.left(); i <= rect.right(); ++i ) { col = m_pView->activeTable()->columnLayout( i ); if ( col->isHide() ) { hiddenCols.append(i); } } if (hiddenCols.count() > 0) m_pView->activeTable()->showColumn(0, -1, hiddenCols); } } m_bSelection = FALSE; m_bResize = FALSE; } void KSpreadHBorder::adjustColumn( int _col, bool makeUndo ) { int adjust; int select; if( _col==-1 ) { adjust = m_pCanvas->activeTable()->adjustColumn(QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() )); select=m_iSelectionAnchor; } else { adjust=m_pCanvas->activeTable()->adjustColumn(QPoint( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ),_col); select=_col; } if(adjust!=-1) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); if( makeUndo && !m_pCanvas->doc()->undoBuffer()->isLocked() ) { QRect rect; rect.setCoords( select, 1, select, KS_rowMax ); KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(),m_pCanvas->activeTable() , rect ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } ColumnLayout *cl = table->nonDefaultColumnLayout( select ); adjust = QMAX( (int)(2.0 * m_pCanvas->zoom()), adjust ); cl->setWidth( adjust, m_pCanvas ); } } void KSpreadHBorder::equalizeColumn( int resize ) { KSpreadTable *table = m_pCanvas->activeTable(); Q_ASSERT( table ); QRect selection( table->selectionRect() ); if ( !m_pCanvas->doc()->undoBuffer()->isLocked() ) { KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(),m_pCanvas->activeTable() , selection ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } ColumnLayout *cl; for (int i=selection.left();i<=selection.right();i++) { cl= table->nonDefaultColumnLayout( i ); resize = QMAX( (int)(2.0* m_pCanvas->zoom()), resize ); cl->setWidth( resize, m_pCanvas ); } } void KSpreadHBorder::resizeColumn( int resize, int nb, bool makeUndo ) { KSpreadTable *table = m_pCanvas->activeTable(); Q_ASSERT( table ); if( nb == -1 ) { if( makeUndo && !m_pCanvas->doc()->undoBuffer()->isLocked() ) { QRect rect; rect.setCoords( m_iSelectionAnchor, 1, m_iSelectionAnchor, KS_rowMax ); KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(), m_pCanvas->activeTable(), rect ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } ColumnLayout *cl = table->nonDefaultColumnLayout( m_iSelectionAnchor ); resize = QMAX( (int)(2.0* m_pCanvas->zoom()), resize ); cl->setWidth( resize, m_pCanvas ); } else { QRect selection( table->selectionRect() ); if( selection.bottom() == 0 || selection.top() == 0 || selection.left() == 0 || selection.right() == 0 ) { if( makeUndo && !m_pCanvas->doc()->undoBuffer()->isLocked() ) { QRect rect; rect.setCoords( m_iSelectionAnchor, 1, m_iSelectionAnchor, KS_rowMax ); KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(), m_pCanvas->activeTable(), rect ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } ColumnLayout *cl = table->nonDefaultColumnLayout( m_pCanvas->markerColumn() ); resize = QMAX( (int)(2.0* m_pCanvas->zoom()), resize ); cl->setWidth( resize, m_pCanvas ); } else { if( makeUndo && !m_pCanvas->doc()->undoBuffer()->isLocked() ) { KSpreadUndoResizeColRow *undo = new KSpreadUndoResizeColRow( m_pCanvas->doc(), m_pCanvas->activeTable(), selection ); m_pCanvas->doc()->undoBuffer()->appendUndo( undo ); } ColumnLayout *cl; for ( int i=selection.left(); i<=selection.right(); i++ ) { cl = table->nonDefaultColumnLayout( i ); resize = QMAX( (int)(2.0* m_pCanvas->zoom()), resize ); cl->setWidth( resize, m_pCanvas ); } } } } void KSpreadHBorder::mouseDoubleClickEvent( QMouseEvent * /*_ev */) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); if(!m_pView->koDocument()->isReadWrite()) return; adjustColumn(); } void KSpreadHBorder::mouseMoveEvent( QMouseEvent * _ev ) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); if(!m_pView->koDocument()->isReadWrite()) return; if ( m_bResize ) { paintSizeIndicator( _ev->pos().x(), false ); } else if ( m_bSelection ) { int x = 0; int col = table->leftColumn( _ev->pos().x(), x, m_pCanvas ); if( col > KS_colMax ) return; QRect r = table->selectionRect(); if ( col < m_iSelectionAnchor ) { r.setLeft( col ); r.setRight( m_iSelectionAnchor ); } else { r.setRight( col ); r.setLeft( m_iSelectionAnchor ); } table->setSelection( r, m_pCanvas ); if ( _ev->pos().x() < 0 ) m_pCanvas->horzScrollBar()->setValue( m_pCanvas->xOffset() + x ); else if ( _ev->pos().x() > m_pCanvas->width() ) { if ( col < KS_colMax ) { ColumnLayout *cl = table->columnLayout( col + 1 ); x = table->columnPos( col + 1, m_pCanvas ); m_pCanvas->horzScrollBar()->setValue( m_pCanvas->xOffset() + ( x + cl->width( m_pCanvas ) - m_pCanvas->width() ) ); } } } // Perhaps we have to modify the cursor else { //if col is hide and it's the first column //you mustn't resize it. int tmp2; int tmpCol=table->leftColumn( _ev->pos().x() - 1, tmp2, m_pCanvas ); /* Doesn't work correctly, gets removed if it turns out that the new version really works, Norbert while ( x < width() ) { int w = table->columnLayout( col )->width( m_pCanvas ); if ( _ev->pos().x() >= x + w - 1 && _ev->pos().x() <= x + w + 1 &&!(table->columnLayout(tmpCol)->isHide() && tmpCol == 1) ) { setCursor(splitHCursor); return; } x += w; } */ int xpos = _ev->pos().x(); if ( ( (table->leftColumn( ( xpos - 1), tmp2, m_pCanvas ) != tmpCol) || (table->leftColumn( ( xpos - 1) + 3, tmp2, m_pCanvas ) != tmpCol) ) && !(table->columnLayout(tmpCol)->isHide() && tmpCol == 1) ) { setCursor(splitHCursor); return; } setCursor( arrowCursor ); } } void KSpreadHBorder::wheelEvent( QWheelEvent* _ev ) { if ( m_pCanvas->horzScrollBar() ) QApplication::sendEvent( m_pCanvas->horzScrollBar(), _ev ); } void KSpreadHBorder::paintSizeIndicator( int mouseX, bool firstTime ) { KSpreadTable *table = m_pCanvas->activeTable(); assert( table ); QPainter painter; painter.begin( m_pCanvas ); painter.setRasterOp( NotROP ); if (!firstTime) painter.drawLine( m_iResizePos, 0, m_iResizePos, m_pCanvas->height() ); m_iResizePos = mouseX; //int twenty = (int)( 2.0 * m_pCanvas->zoom() ); // Dont make the column have a width < 2 pixels. int x = table->columnPos( m_iResizedColumn, m_pCanvas ); if ( m_iResizePos <= x /*+ twenty*/ ) m_iResizePos = x /*+ twenty*/; painter.drawLine( m_iResizePos, 0, m_iResizePos, m_pCanvas->height() ); painter.end(); QString tmpSize; if(m_iResizePos !=x) tmpSize=i18n("Width: %1 %2").arg(KoUnit::ptToUnit(((m_iResizePos-x)/m_pCanvas->zoom()), m_pView->doc()->getUnit())).arg(m_pView->doc()->getUnitName()); else tmpSize=i18n("Hide Column"); painter.begin(this); int len = painter.fontMetrics().width(tmpSize ); int hei = painter.fontMetrics().height( ); painter.end(); if(!m_lSize) { m_lSize=new QLabel(m_pCanvas); m_lSize->setGeometry(x+3,3,len+2, hei+2 ) ; m_lSize->setAlignment(Qt::AlignVCenter); m_lSize->setText(tmpSize); m_lSize->show(); } else { m_lSize->setGeometry(x+3,3,len+2, hei+2 ) ; m_lSize->setText(tmpSize); } } void KSpreadHBorder::paintEvent( QPaintEvent* _ev ) { KSpreadTable *table = m_pCanvas->activeTable(); if (!table ) return; QPainter painter; painter.begin( this ); QPen pen; pen.setWidth( 1 ); painter.setPen( pen ); painter.setBackgroundColor( white ); // painter.eraseRect( _ev->rect() ); //QFontMetrics fm = painter.fontMetrics(); // Matthias Elter: This causes a SEGFAULT in ~QPainter! // Only god and the trolls know why ;-) // bah...took me quite some time to track this one down... // Determine which columns need painting int xpos; int left_col = table->leftColumn( _ev->rect().x(), xpos, m_pCanvas ); int right_col = table->rightColumn( _ev->rect().right(), m_pCanvas ); QRect selection( table->selectionRect() ); QFont normalFont = painter.font(); QFont boldFont = normalFont; boldFont.setBold( TRUE ); KSpreadCell *cell=table->cellAt( m_pCanvas->markerColumn(), m_pCanvas->markerRow() ); QRect extraCell; extraCell.setCoords(m_pCanvas->markerColumn(),m_pCanvas->markerRow(), m_pCanvas->markerColumn()+cell->extraXCells(),m_pCanvas->markerRow()+cell->extraYCells()); //several cells selected but not just a cell merged bool area=( selection.left()!=0 && extraCell!=selection ); for ( int x = left_col; x <= right_col; x++ ) { bool highlighted = ( area && x >= selection.left() && x <= selection.right()); bool selected = ( highlighted && table->isColumnSelected() && (!table->isRowSelected()) ); ColumnLayout *col_lay = table->columnLayout( x ); if ( selected ) { QBrush fillSelected( colorGroup().brush( QColorGroup::Highlight ) ); qDrawShadePanel( &painter, xpos, 0, col_lay->width( m_pCanvas ), XBORDER_HEIGHT, colorGroup(), FALSE, 1, &fillSelected ); } else if ( highlighted ) { QBrush fillHighlighted( colorGroup().brush( QColorGroup::Background ) ); qDrawShadePanel( &painter, xpos, 0, col_lay->width( m_pCanvas ), XBORDER_HEIGHT, colorGroup(), true, 1, &fillHighlighted ); } else { QBrush fill( colorGroup().brush( QColorGroup::Background ) ); qDrawShadePanel( &painter, xpos, 0, col_lay->width( m_pCanvas ), XBORDER_HEIGHT, colorGroup(), FALSE, 1, &fill ); } // Reset painter painter.setFont( normalFont ); painter.setPen( colorGroup().text() ); if ( selected ) painter.setPen( colorGroup().highlightedText() ); else if ( highlighted ) painter.setFont( boldFont ); if(!m_pView->activeTable()->getShowColumnNumber()) { int len = painter.fontMetrics().width( util_encodeColumnLabelText( x ) ); if(!col_lay->isHide()) painter.drawText( xpos + ( col_lay->width( m_pCanvas ) - len ) / 2, ( XBORDER_HEIGHT + painter.fontMetrics().ascent() - painter.fontMetrics().descent() ) / 2, util_encodeColumnLabelText( x ) ); } else { QString tmp; int len = painter.fontMetrics().width( tmp.setNum(x) ); if(!col_lay->isHide()) painter.drawText( xpos + ( col_lay->width( m_pCanvas ) - len ) / 2, ( XBORDER_HEIGHT + painter.fontMetrics().ascent() - painter.fontMetrics().descent() ) / 2, tmp.setNum(x) ); } xpos += col_lay->width( m_pCanvas ); } m_pCanvas->updatePosWidget(); painter.end(); } /**************************************************************** * * KSpreadToolTip * ****************************************************************/ KSpreadToolTip::KSpreadToolTip( KSpreadCanvas* canvas ) : QToolTip( canvas ), m_canvas( canvas ) { } void KSpreadToolTip::maybeTip( const QPoint& p ) { KSpreadTable *table = m_canvas->activeTable(); if ( !table ) return; // Over which cell is the mouse ? int ypos, xpos; int row = table->topRow( p.y(), ypos, m_canvas ); int col = table->leftColumn( p.x(), xpos, m_canvas ); KSpreadCell* cell = table->visibleCellAt( col, row ); if ( !cell ) return; // Get the comment QString comment= cell->comment(col,row); // Determine position and width of the current cell. cell = table->cellAt( col, row ); int u = cell->width( col, m_canvas ); // Special treatment for obscured cells. if ( cell->isObscured() && cell->isObscuringForced() ) { cell = cell->obscuringCells().getFirst(); int moveX = cell->column(); int moveY = cell->row(); // Use the obscuring cells dimensions u = cell->width( moveX, m_canvas ); xpos = table->columnPos( moveX, m_canvas ); ypos = table->rowPos( moveY, m_canvas ); } // Is the cursor over the comment marker (if there is any) then // show the comment. QRect marker( xpos + u - 10, ypos, 10, 10 ); if ( marker.contains( p ) ) { tip( marker, comment ); } } #include "kspread_canvas.moc"