kspread

kspread_view.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005-2006 Raphael Langerhorst <raphael.langerhorst@kdemail.net>
00003              (C) 2006      Stefan Nikolaus <stefan.nikolaus@kdemail.net>
00004              (C) 2002-2005 Ariya Hidayat <ariya@kde.org>
00005              (C) 1999-2003 Laurent Montel <montel@kde.org>
00006              (C) 2002-2003 Norbert Andres <nandres@web.de>
00007              (C) 2002-2003 Philipp Mueller <philipp.mueller@gmx.de>
00008              (C) 2002-2003 John Dailey <dailey@vt.edu>
00009              (C) 1999-2003 David Faure <faure@kde.org>
00010              (C) 1999-2001 Simon Hausmann <hausmann@kde.org>
00011              (C) 1998-2000 Torben Weis <weis@kde.org>
00012 
00013    This library is free software; you can redistribute it and/or
00014    modify it under the terms of the GNU Library General Public
00015    License as published by the Free Software Foundation; either
00016    version 2 of the License, or (at your option) any later version.
00017 
00018    This library is distributed in the hope that it will be useful,
00019    but WITHOUT ANY WARRANTY; without even the implied warranty of
00020    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021    Library General Public License for more details.
00022 
00023    You should have received a copy of the GNU Library General Public License
00024    along with this library; see the file COPYING.LIB.  If not, write to
00025    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00026  * Boston, MA 02110-1301, USA.
00027 */
00028 
00029 #include <kprinter.h> // has to be first
00030 
00031 // standard C/C++ includes
00032 #include <assert.h>
00033 #include <stdlib.h>
00034 #include <time.h>
00035 
00036 // Qt includes
00037 #include <qbuffer.h>
00038 #include <qclipboard.h>
00039 #include <qcursor.h>
00040 #include <qlayout.h>
00041 #include <qpaintdevicemetrics.h>
00042 #include <qregexp.h>
00043 #include <qtimer.h>
00044 #include <qtoolbutton.h>
00045 #include <qsqldatabase.h>
00046 #include <qlistview.h>
00047 #include <qsizepolicy.h>
00048 
00049 // KDE includes
00050 #include <dcopclient.h>
00051 #include <dcopref.h>
00052 #include <kapplication.h>
00053 #include <kconfig.h>
00054 #include <kdebug.h>
00055 #include <kfind.h>
00056 #include <kfinddialog.h>
00057 #include <kfontdialog.h>
00058 #include <kinputdialog.h>
00059 #include <kmessagebox.h>
00060 #include <knotifyclient.h>
00061 #include <kpassdlg.h>
00062 #include <kprocio.h>
00063 #include <kreplace.h>
00064 #include <kreplacedialog.h>
00065 #include <kspell.h>
00066 #include <kspelldlg.h>
00067 #include <kstatusbar.h>
00068 #include <kstdaction.h>
00069 #include <kstandarddirs.h>
00070 #include <ktempfile.h>
00071 #include <kparts/partmanager.h>
00072 #include <klistview.h>
00073 #include <kpushbutton.h>
00074 
00075 // KOffice includes
00076 #include <tkcoloractions.h>
00077 #include <kdatatool.h>
00078 #include <KoCharSelectDia.h>
00079 #include <KoCommandHistory.h>
00080 #include <KoMainWindow.h>
00081 #include <KoOasisLoadingContext.h>
00082 #include <KoOasisStore.h>
00083 #include <KoOasisStyles.h>
00084 #include <KoPartSelectAction.h>
00085 #include <KoStoreDrag.h>
00086 #include <KoTabBar.h>
00087 #include <kspread_toolbox.h>
00088 #include <KoTemplateCreateDia.h>
00089 #include <KoZoomAction.h>
00090 
00091 // KSpread includes
00092 #include "commands.h"
00093 #include "damages.h"
00094 #include "digest.h"
00095 #include "inspector.h"
00096 #include "kspread_canvas.h"
00097 #include "kspread_editors.h"
00098 #include "kspread_events.h"
00099 #include "kspread_global.h"
00100 #include "kspread_handler.h"
00101 #include "kspread_locale.h"
00102 #include "kspread_map.h"
00103 #include "selection.h"
00104 #include "kspread_sheetprint.h"
00105 #include "kspread_style.h"
00106 #include "kspread_style_manager.h"
00107 #include "kspread_undo.h"
00108 #include "testrunner.h"
00109 #include "valuecalc.h"
00110 #include "valueconverter.h"
00111 
00112 // dialogs
00113 #include "dialogs/kspread_dlg_angle.h"
00114 #include "dialogs/kspread_dlg_area.h"
00115 #include "dialogs/kspread_dlg_comment.h"
00116 #include "dialogs/kspread_dlg_conditional.h"
00117 #include "dialogs/kspread_dlg_cons.h"
00118 #include "dialogs/kspread_dlg_csv.h"
00119 #include "dialogs/kspread_dlg_database.h"
00120 #include "dialogs/kspread_dlg_format.h"
00121 #include "dialogs/kspread_dlg_formula.h"
00122 #include "dialogs/kspread_dlg_goalseek.h"
00123 #include "dialogs/kspread_dlg_goto.h"
00124 #include "dialogs/kspread_dlg_insert.h"
00125 #include "dialogs/kspread_dlg_layout.h"
00126 #include "dialogs/kspread_dlg_list.h"
00127 //#include "dialogs/kspread_dlg_multipleop.h"
00128 #include "dialogs/kspread_dlg_paperlayout.h"
00129 #include "dialogs/kspread_dlg_pasteinsert.h"
00130 #include "dialogs/kspread_dlg_preference.h"
00131 #include "dialogs/kspread_dlg_reference.h"
00132 #include "dialogs/kspread_dlg_resize2.h"
00133 #include "dialogs/kspread_dlg_series.h"
00134 #include "dialogs/kspread_dlg_show.h"
00135 #include "dialogs/kspread_dlg_showColRow.h"
00136 #include "dialogs/kspread_dlg_sort.h"
00137 #include "dialogs/kspread_dlg_special.h"
00138 #include "dialogs/kspread_dlg_styles.h"
00139 #include "dialogs/kspread_dlg_subtotal.h"
00140 #include "dialogs/kspread_dlg_validity.h"
00141 #include "dialogs/link.h"
00142 #include "dialogs/sheet_properties.h"
00143 #include "dialogs/kspread_dlg_find.h"
00144 #include "dialogs/SheetSelectWidget.h"
00145 #include "kspread_propertyEditor.h"
00146 #include "kspread_generalProperty.h"
00147 
00148 // KSpread DCOP
00149 #include "KSpreadViewIface.h"
00150 
00151 #include "kspread_view.h"
00152 
00153 namespace KSpread
00154 {
00155 class ViewActions;
00156 
00157 class View::Private
00158 {
00159 public:
00160     View* view;
00161     Doc* doc;
00162     DCOPObject* dcop;
00163 
00164     // the active sheet, may be 0
00165     // this is the sheet which has the input focus
00166     Sheet* activeSheet;
00167 
00168     // GUI elements
00169     QWidget *frame;
00170     QFrame *toolWidget;
00171     Canvas *canvas;
00172     VBorder *vBorderWidget;
00173     HBorder *hBorderWidget;
00174     QScrollBar *horzScrollBar;
00175     QScrollBar *vertScrollBar;
00176     KoTabBar *tabBar;
00177     KStatusBarLabel* calcLabel;
00178 
00179     // formulabar, consists of:
00180     QHBoxLayout* formulaBarLayout;
00181     ComboboxLocationEditWidget *posWidget;
00182     QButton* formulaButton;
00183     QButton *okButton;
00184     QButton *cancelButton;
00185     KSpread::EditWidget *editWidget;
00186     QGridLayout* viewLayout;
00187     QHBoxLayout* tabScrollBarLayout;
00188 
00189     // all UI actions
00190     ViewActions* actions;
00191 
00192     // If updateEditWidget is called it changes some KToggleActions.
00193     // That causes them to emit a signal. If this lock is true, then these
00194     // signals are ignored.
00195     bool toolbarLock;
00196 
00197     // if true, kspread is still loading the document
00198     // don't try to refresh the view
00199     bool loading;
00200 
00201     // selection/marker
00202     Selection* selection;
00203     Selection* choice;
00204     QMap<Sheet*, QPoint> savedAnchors;
00205     QMap<Sheet*, QPoint> savedMarkers;
00206 
00207     // Find and Replace context. We remember the options and
00208     // the strings used previously.
00209     long findOptions;
00210     QStringList findStrings;
00211     QStringList replaceStrings;
00212     FindOption::searchTypeValue typeValue;
00213     FindOption::searchDirectionValue directionValue;
00214     // Current "find" operation
00215     KFind* find;
00216     KReplace* replace;
00217     int findLeftColumn;
00218     int findRightColumn;
00219     QPoint findPos;
00220     QPoint findEnd;
00221 
00222     InsertHandler* insertHandler;
00223 
00224     // Insert special character dialog
00225     KoCharSelectDia* specialCharDlg;
00226 
00227     // Holds a guarded pointer to the transformation toolbox.
00228     QGuardedPtr<KoTransformToolBox> transformToolBox;
00229 
00230     // the last popup menu (may be 0).
00231     // Since only one popup menu can be opened at once, its pointer is stored here.
00232     // Delete the old one before you store a pointer to anotheron here.
00233     QPopupMenu *popupMenu;
00234     int popupMenuFirstToolId;
00235 
00236     QPopupMenu *popupRow;
00237     QPopupMenu *popupColumn;
00238     QPopupMenu* popupChild;       // for embedded children
00239     QPopupMenu* popupListChoose;  // for list of choose
00240 
00241     // the child for which the popup menu has been opened.
00242     Child* popupChildObject;
00243 
00244     // spell-check context
00245     struct
00246     {
00247       KSpell *   kspell;
00248       Sheet *  firstSpellSheet;
00249       Sheet *  currentSpellSheet;
00250       Cell  *  currentCell;
00251       MacroUndoAction *macroCmdSpellCheck;
00252       unsigned int    spellCurrCellX;
00253       unsigned int    spellCurrCellY;
00254       unsigned int    spellStartCellX;
00255       unsigned int    spellStartCellY;
00256       unsigned int    spellEndCellX;
00257       unsigned int    spellEndCellY;
00258       bool            spellCheckSelection;
00259       QStringList replaceAll;
00260     } spell;
00261 
00262     struct
00263     {
00264         Sheet * currentSheet;
00265         Sheet * firstSheet;
00266     } searchInSheets;
00267 
00268     // the tools
00269     struct ToolEntry
00270     {
00271       QString command;
00272       KDataToolInfo info;
00273     };
00274     QPtrList<ToolEntry> toolList;
00275 
00276     void initActions();
00277     void adjustActions( bool mode );
00278     void adjustActions( Sheet* sheet, Cell* cell );
00279     void adjustWorkbookActions( bool mode );
00280     void updateButton( Cell *cell, int column, int row);
00281     QButton* newIconButton( const char *_file, bool _kbutton = false, QWidget *_parent = 0L );
00282 
00283     PropertyEditor *m_propertyEditor;
00284 
00285     QTimer statusBarOpTimer;
00286 };
00287 
00288 class ViewActions
00289 {
00290 public:
00291 
00292     // cell formatting
00293     KAction* cellLayout;
00294     KAction *actionExtraProperties;
00295     KAction* defaultFormat;
00296     KToggleAction* bold;
00297     KToggleAction* italic;
00298     KToggleAction* underline;
00299     KToggleAction* strikeOut;
00300     KFontAction* selectFont;
00301     KFontSizeAction* selectFontSize;
00302     KAction* fontSizeUp;
00303     KAction* fontSizeDown;
00304     TKSelectColorAction* textColor;
00305     KToggleAction* alignLeft;
00306     KToggleAction* alignCenter;
00307     KToggleAction* alignRight;
00308     KToggleAction* alignTop;
00309     KToggleAction* alignMiddle;
00310     KToggleAction* alignBottom;
00311     KToggleAction* wrapText;
00312     KToggleAction* verticalText;
00313     KAction* increaseIndent;
00314     KAction* decreaseIndent;
00315     KAction* changeAngle;
00316     KToggleAction* percent;
00317     KAction* precplus;
00318     KAction* precminus;
00319     KToggleAction* money;
00320     KAction* upper;
00321     KAction* lower;
00322     KAction* firstLetterUpper;
00323     TKSelectColorAction* bgColor;
00324     KAction* borderLeft;
00325     KAction* borderRight;
00326     KAction* borderTop;
00327     KAction* borderBottom;
00328     KAction* borderAll;
00329     KAction* borderOutline;
00330     KAction* borderRemove;
00331     TKSelectColorAction* borderColor;
00332     KSelectAction* selectStyle;
00333     KAction* createStyle;
00334 
00335     // cell operations
00336     KAction* editCell;
00337     KAction* insertCell;
00338     KAction* removeCell;
00339     KAction* deleteCell;
00340     KToolBarPopupAction* mergeCell;
00341     KAction* mergeCellHorizontal;
00342     KAction* mergeCellVertical;
00343     KAction* dissociateCell;
00344     KAction* clearText;
00345     KAction* conditional;
00346     KAction* clearConditional;
00347     KAction* validity;
00348     KAction* clearValidity;
00349     KAction* addModifyComment;
00350     KAction* removeComment;
00351     KAction* clearComment;
00352 
00353     // column & row operations
00354     KAction* resizeColumn;
00355     KAction* insertColumn;
00356     KAction* deleteColumn;
00357     KAction* hideColumn;
00358     KAction* showColumn;
00359     KAction* equalizeColumn;
00360     KAction* showSelColumns;
00361     KAction* resizeRow;
00362     KAction* insertRow;
00363     KAction* deleteRow;
00364     KAction* hideRow;
00365     KAction* showRow;
00366     KAction* equalizeRow;
00367     KAction* showSelRows;
00368     KAction* adjust;
00369 
00370     // sheet/workbook operations
00371     KAction* sheetProperties;
00372     KAction* insertSheet;
00373     KAction* menuInsertSheet;
00374     KAction* removeSheet;
00375     KAction* renameSheet;
00376     KAction* hideSheet;
00377     KAction* showSheet;
00378     KAction* autoFormat;
00379     KAction* areaName;
00380     KAction* showArea;
00381     KAction* insertSeries;
00382     KAction* insertFunction;
00383     KAction* insertSpecialChar;
00384     KAction* insertFromDatabase;
00385     KAction* insertFromTextfile;
00386     KAction* insertFromClipboard;
00387     KAction* transform;
00388     KAction* sort;
00389     KAction* sortDec;
00390     KAction* sortInc;
00391     KAction* fillRight;
00392     KAction* fillLeft;
00393     KAction* fillUp;
00394     KAction* fillDown;
00395     KAction* paperLayout;
00396     KAction* definePrintRange;
00397     KAction* resetPrintRange;
00398     KToggleAction* showPageBorders;
00399     KAction* recalcWorksheet;
00400     KAction* recalcWorkbook;
00401     KToggleAction* protectSheet;
00402     KToggleAction* protectDoc;
00403 
00404     // general editing
00405     KAction* cut;
00406     KAction* copy;
00407     KAction* paste;
00408     KAction* specialPaste;
00409     KAction* insertCellCopy;
00410     KAction* find;
00411     KAction* replace;
00412 
00413     // navigation
00414     KAction* gotoCell;
00415     KAction* nextSheet;
00416     KAction* prevSheet;
00417     KAction* firstSheet;
00418     KAction* lastSheet;
00419 
00420     // misc
00421     KAction* styleDialog;
00422     KAction* autoSum;
00423     KSelectAction* formulaSelection;
00424     KAction* insertLink;
00425     KAction* removeLink;
00426     KAction* consolidate;
00427     KAction* goalSeek;
00428     KAction* subTotals;
00429     KAction* textToColumns;
00430     KAction* multipleOperations;
00431     KAction* createTemplate;
00432     KoPartSelectAction *insertPart;
00433     KToggleAction* insertChartFrame;
00434     KAction* insertPicture;
00435     KAction* customList;
00436     KAction* spellChecking;
00437     KAction* internalTests;
00438     KAction* inspector;
00439 
00440     // settings
00441     KoZoomAction* viewZoom;
00442     KToggleAction* showStatusBar;
00443     KToggleAction* showTabBar;
00444     KToggleAction* showFormulaBar;
00445     KAction* preference;
00446 
00447     // running calculation
00448     KToggleAction* calcNone;
00449     KToggleAction* calcMin;
00450     KToggleAction* calcMax;
00451     KToggleAction* calcAverage;
00452     KToggleAction* calcCount;
00453     KToggleAction* calcSum;
00454     KToggleAction* calcCountA;
00455 };
00456 
00457 
00458 void View::Private::initActions()
00459 {
00460   actions = new ViewActions;
00461 
00462   KActionCollection* ac = view->actionCollection();
00463 
00464   // -- cell formatting actions --
00465 
00466   actions->cellLayout = new KAction( i18n("Cell Format..."), "cell_layout",
00467       Qt::CTRL+ Qt::ALT+ Qt::Key_F, view, SLOT( layoutDlg() ), ac, "cellLayout" );
00468   actions->cellLayout->setToolTip( i18n("Set the cell formatting.") );
00469 
00470   actions->actionExtraProperties = new KAction( i18n( "&Properties" ), "penbrush", 0,
00471       view, SLOT( extraProperties() ), ac, "extra_properties" );
00472 
00473   actions->defaultFormat = new KAction( i18n("Default"),
00474       0, view, SLOT( defaultSelection() ), ac, "default" );
00475   actions->defaultFormat->setToolTip( i18n("Resets to the default format.") );
00476 
00477   actions->bold = new KToggleAction( i18n("Bold"), "text_bold",
00478       Qt::CTRL+Qt::Key_B, ac, "bold");
00479   QObject::connect( actions->bold, SIGNAL( toggled( bool) ),
00480       view, SLOT( bold( bool ) ) );
00481 
00482   actions->italic = new KToggleAction( i18n("Italic"), "text_italic",
00483       Qt::CTRL+Qt::Key_I, ac, "italic");
00484   QObject::connect( actions->italic, SIGNAL( toggled( bool) ),
00485       view, SLOT( italic( bool ) ) );
00486 
00487   actions->underline = new KToggleAction( i18n("Underline"), "text_under",
00488       Qt::CTRL+Qt::Key_U, ac, "underline");
00489   QObject::connect( actions->underline, SIGNAL( toggled( bool) ),
00490       view, SLOT( underline( bool ) ) );
00491 
00492   actions->strikeOut = new KToggleAction( i18n("Strike Out"), "text_strike",
00493       0, ac, "strikeout");
00494   QObject::connect( actions->strikeOut, SIGNAL( toggled( bool) ),
00495       view, SLOT( strikeOut( bool ) ) );
00496 
00497   actions->selectFont = new KFontAction( i18n("Select Font..."),
00498       0, ac, "selectFont" );
00499   QObject::connect( actions->selectFont, SIGNAL( activated( const QString& ) ),
00500       view, SLOT( fontSelected( const QString& ) ) );
00501 
00502   actions->selectFontSize = new KFontSizeAction( i18n("Select Font Size"),
00503       0, ac, "selectFontSize" );
00504   QObject::connect( actions->selectFontSize, SIGNAL( fontSizeChanged( int ) ),
00505       view, SLOT( fontSizeSelected( int ) ) );
00506 
00507   actions->fontSizeUp = new KAction( i18n("Increase Font Size"), "fontsizeup",
00508       0, view, SLOT( increaseFontSize() ), ac,  "increaseFontSize" );
00509 
00510   actions->fontSizeDown = new KAction( i18n("Decrease Font Size"), "fontsizedown",
00511       0, view, SLOT( decreaseFontSize() ), ac, "decreaseFontSize" );
00512 
00513   actions->textColor = new TKSelectColorAction( i18n("Text Color"),
00514       TKSelectColorAction::TextColor, view, SLOT( changeTextColor() ),
00515       ac, "textColor",true );
00516   actions->textColor->setDefaultColor(QColor());
00517 
00518   actions->alignLeft = new KToggleAction( i18n("Align Left"), "text_left",
00519       0, ac, "left");
00520   QObject::connect( actions->alignLeft, SIGNAL( toggled( bool ) ),
00521       view, SLOT( alignLeft( bool ) ) );
00522   actions->alignLeft->setExclusiveGroup( "Align" );
00523   actions->alignLeft->setToolTip(i18n("Left justify the cell contents."));
00524 
00525   actions->alignCenter = new KToggleAction( i18n("Align Center"), "text_center",
00526       0, ac, "center");
00527   QObject::connect( actions->alignCenter, SIGNAL( toggled( bool ) ),
00528       view, SLOT( alignCenter( bool ) ) );
00529   actions->alignCenter->setExclusiveGroup( "Align" );
00530   actions->alignCenter->setToolTip(i18n("Center the cell contents."));
00531 
00532   actions->alignRight = new KToggleAction( i18n("Align Right"), "text_right",
00533       0, ac, "right");
00534   QObject::connect( actions->alignRight, SIGNAL( toggled( bool ) ),
00535       view, SLOT( alignRight( bool ) ) );
00536   actions->alignRight->setExclusiveGroup( "Align" );
00537   actions->alignRight->setToolTip(i18n("Right justify the cell contents."));
00538 
00539   actions->alignTop = new KToggleAction( i18n("Align Top"), "text_top",
00540       0, ac, "top");
00541   QObject::connect( actions->alignTop, SIGNAL( toggled( bool ) ),
00542       view, SLOT( alignTop( bool ) ) );
00543   actions->alignTop->setExclusiveGroup( "Pos" );
00544   actions->alignTop->setToolTip(i18n("Align cell contents along the top of the cell."));
00545 
00546   actions->alignMiddle = new KToggleAction( i18n("Align Middle"), "middle",
00547       0, ac, "middle");
00548   QObject::connect( actions->alignMiddle, SIGNAL( toggled( bool ) ),
00549       view, SLOT( alignMiddle( bool ) ) );
00550   actions->alignMiddle->setExclusiveGroup( "Pos" );
00551   actions->alignMiddle->setToolTip(i18n("Align cell contents centered in the cell."));
00552 
00553   actions->alignBottom = new KToggleAction( i18n("Align Bottom"), "text_bottom",
00554       0, ac, "bottom");
00555   QObject::connect( actions->alignBottom, SIGNAL( toggled( bool ) ),
00556       view, SLOT( alignBottom( bool ) ) );
00557   actions->alignBottom->setExclusiveGroup( "Pos" );
00558   actions->alignBottom->setToolTip(i18n("Align cell contents along the bottom of the cell."));
00559 
00560   actions->wrapText = new KToggleAction( i18n("Wrap Text"), "multirow",
00561       0, ac, "multiRow" );
00562   QObject::connect( actions->wrapText, SIGNAL( toggled( bool ) ),
00563       view, SLOT( wrapText( bool ) ) );
00564   actions->wrapText->setToolTip(i18n("Make the cell text wrap onto multiple lines."));
00565 
00566   actions->verticalText = new KToggleAction( i18n("Vertical Text"),"vertical_text" ,
00567       0 ,ac, "verticaltext" );
00568   QObject::connect( actions->verticalText, SIGNAL( toggled( bool ) ),
00569       view, SLOT( verticalText( bool ) ) );
00570   actions->verticalText->setToolTip(i18n("Print cell contents vertically."));
00571 
00572   actions->increaseIndent = new KAction( i18n("Increase Indent"),
00573       QApplication::reverseLayout() ? "format_decreaseindent":"format_increaseindent",
00574       0, view, SLOT( increaseIndent() ), ac, "increaseindent" );
00575   actions->increaseIndent->setToolTip(i18n("Increase the indentation."));
00576 
00577   actions->decreaseIndent = new KAction( i18n("Decrease Indent"),
00578       QApplication::reverseLayout() ? "format_increaseindent" : "format_decreaseindent",
00579       0, view, SLOT( decreaseIndent() ), ac, "decreaseindent");
00580   actions->decreaseIndent->setToolTip(i18n("Decrease the indentation."));
00581 
00582   actions->changeAngle = new KAction( i18n("Change Angle..."),
00583       0, view, SLOT( changeAngle() ), ac, "changeangle" );
00584   actions->changeAngle->setToolTip(i18n("Change the angle that cell contents are printed."));
00585 
00586   actions->percent = new KToggleAction( i18n("Percent Format"), "percent",
00587       0, ac, "percent");
00588   QObject::connect( actions->percent, SIGNAL( toggled( bool ) ),
00589       view, SLOT( percent( bool ) ) );
00590   actions->percent->setToolTip(i18n("Set the cell formatting to look like a percentage."));
00591 
00592   actions->precplus = new KAction( i18n("Increase Precision"), "prec_plus",
00593       0, view, SLOT( precisionPlus() ), ac, "precplus");
00594   actions->precplus->setToolTip(i18n("Increase the decimal precision shown onscreen."));
00595 
00596   actions->precminus = new KAction( i18n("Decrease Precision"), "prec_minus",
00597       0, view, SLOT( precisionMinus() ), ac, "precminus");
00598   actions->precminus->setToolTip(i18n("Decrease the decimal precision shown onscreen."));
00599 
00600   actions->money = new KToggleAction( i18n("Money Format"), "money",
00601       0, ac, "money");
00602   QObject::connect( actions->money, SIGNAL( toggled( bool ) ),
00603       view, SLOT( moneyFormat( bool ) ) );
00604   actions->money->setToolTip(i18n("Set the cell formatting to look like your local currency."));
00605 
00606   actions->upper = new KAction( i18n("Upper Case"), "fontsizeup",
00607       0, view, SLOT( upper() ), ac, "upper" );
00608   actions->upper->setToolTip(i18n("Convert all letters to upper case."));
00609 
00610   actions->lower = new KAction( i18n("Lower Case"), "fontsizedown",
00611       0, view, SLOT( lower() ), ac, "lower" );
00612   actions->lower->setToolTip(i18n("Convert all letters to lower case."));
00613 
00614   actions->firstLetterUpper = new KAction( i18n("Convert First Letter to Upper Case"), "first_letter_upper",
00615       0, view, SLOT( firstLetterUpper() ),ac, "firstletterupper" );
00616   actions->firstLetterUpper->setToolTip(i18n("Capitalize the first letter."));
00617 
00618   actions->bgColor = new TKSelectColorAction( i18n("Background Color"),
00619       TKSelectColorAction::FillColor, ac, "backgroundColor", true );
00620   QObject::connect(actions->bgColor, SIGNAL( activated() ),
00621       view, SLOT( changeBackgroundColor() ) );
00622   actions->bgColor->setDefaultColor(QColor());
00623   actions->bgColor->setToolTip(i18n("Set the background color."));
00624 
00625   actions->borderLeft = new KAction( i18n("Border Left"), "border_left",
00626       0, view, SLOT( borderLeft() ), ac, "borderLeft" );
00627   actions->borderLeft->setToolTip(i18n("Set a left border to the selected area."));
00628 
00629   actions->borderRight = new KAction( i18n("Border Right"), "border_right",
00630       0, view, SLOT( borderRight() ), ac, "borderRight" );
00631   actions->borderRight->setToolTip(i18n("Set a right border to the selected area."));
00632 
00633   actions->borderTop = new KAction( i18n("Border Top"), "border_top",
00634       0, view, SLOT( borderTop() ), ac, "borderTop" );
00635   actions->borderTop->setToolTip(i18n("Set a top border to the selected area."));
00636 
00637   actions->borderBottom = new KAction( i18n("Border Bottom"), "border_bottom",
00638       0, view, SLOT( borderBottom() ), ac, "borderBottom" );
00639   actions->borderBottom->setToolTip(i18n("Set a bottom border to the selected area."));
00640 
00641   actions->borderAll = new KAction( i18n("All Borders"), "border_all",
00642       0, view, SLOT( borderAll() ), ac, "borderAll" );
00643   actions->borderAll->setToolTip(i18n("Set a border around all cells in the selected area."));
00644 
00645   actions->borderRemove = new KAction( i18n("Remove Borders"), "border_remove",
00646       0, view, SLOT( borderRemove() ), ac, "borderRemove" );
00647   actions->borderRemove->setToolTip(i18n("Remove all borders in the selected area."));
00648 
00649   actions->borderOutline = new KAction( i18n("Border Outline"), ("border_outline"),
00650       0, view, SLOT( borderOutline() ), ac, "borderOutline" );
00651   actions->borderOutline->setToolTip(i18n("Set a border to the outline of the selected area."));
00652 
00653   actions->borderColor = new TKSelectColorAction( i18n("Border Color"),
00654       TKSelectColorAction::LineColor, ac, "borderColor" );
00655   QObject::connect( actions->borderColor, SIGNAL( activated() ),
00656       view, SLOT( changeBorderColor() ) );
00657   actions->borderColor->setToolTip( i18n( "Select a new border color." ) );
00658 
00659   actions->selectStyle = new KSelectAction( i18n( "St&yle" ),
00660       0, ac, "stylemenu" );
00661   actions->selectStyle->setToolTip( i18n( "Apply a predefined style to the selected cells." ) );
00662   QObject::connect( actions->selectStyle, SIGNAL( activated( const QString & ) ),
00663       view, SLOT( styleSelected( const QString & ) ) );
00664 
00665   actions->createStyle = new KAction( i18n( "Create Style From Cell..." ),
00666       0, view, SLOT( createStyleFromCell()), ac, "createStyle" );
00667   actions->createStyle->setToolTip( i18n( "Create a new style based on the currently selected cell." ) );
00668 
00669   // -- cell operation actions --
00670 
00671   actions->editCell = new KAction( i18n("Modify Cell"),"cell_edit",
00672       Qt::CTRL+Qt::Key_M, view, SLOT( editCell() ), ac, "editCell" );
00673   actions->editCell->setToolTip(i18n("Edit the highlighted cell."));
00674 
00675   actions->insertCell = new KAction( i18n("Insert Cells..."), "insertcell",
00676       0, view, SLOT( slotInsert() ), ac, "insertCell" );
00677   actions->insertCell->setToolTip(i18n("Insert a blank cell into the spreadsheet."));
00678 
00679   actions->removeCell = new KAction( i18n("Remove Cells..."), "removecell",
00680       0, view, SLOT( slotRemove() ), ac, "removeCell" );
00681   actions->removeCell->setToolTip(i18n("Removes the current cell from the spreadsheet."));
00682 
00683   actions->deleteCell = new KAction( i18n("Delete"), "deletecell",
00684       0, view, SLOT( deleteSelection() ), ac, "delete" );
00685   actions->deleteCell->setToolTip(i18n("Delete all contents and formatting of the current cell."));
00686 
00687   actions->mergeCell = new KToolBarPopupAction( i18n("Merge Cells"),"mergecell",
00688       0, view, SLOT( mergeCell() ), ac, "mergecell" );
00689   actions->mergeCell->setToolTip(i18n("Merge the selected region."));
00690   actions->mergeCell->plug( actions->mergeCell->popupMenu() );
00691 
00692   actions->mergeCellHorizontal = new KAction( i18n("Merge Cells Horizontally"),"mergecell-horizontal",
00693       0, view, SLOT( mergeCellHorizontal() ), ac, "mergecellHorizontal" );
00694   actions->mergeCellHorizontal->setToolTip(i18n("Merge the selected region horizontally."));
00695   actions->mergeCellHorizontal->plug( actions->mergeCell->popupMenu() );
00696 
00697   actions->mergeCellVertical = new KAction( i18n("Merge Cells Vertically"),"mergecell-vertical",
00698       0, view, SLOT( mergeCellVertical() ), ac, "mergecellVertical" );
00699   actions->mergeCellVertical->setToolTip(i18n("Merge the selected region vertically."));
00700   actions->mergeCellVertical->plug( actions->mergeCell->popupMenu() );
00701 
00702   actions->dissociateCell = new KAction( i18n("Dissociate Cells"),"dissociatecell",
00703       0, view, SLOT( dissociateCell() ), ac, "dissociatecell" );
00704   actions->dissociateCell->setToolTip(i18n("Unmerge the selected region."));
00705 
00706   actions->clearText = new KAction( i18n("Text"),
00707       0, view, SLOT( clearTextSelection() ), ac, "cleartext" );
00708   actions->clearText->setToolTip(i18n("Remove the contents of the current cell."));
00709 
00710   actions->conditional = new KAction( i18n("Conditional Cell Attributes..."),
00711       0, view, SLOT( conditional() ), ac, "conditional" );
00712   actions->conditional->setToolTip(i18n("Set cell format based on certain conditions."));
00713 
00714 
00715   actions->clearConditional = new KAction( i18n("Conditional Cell Attributes"),
00716       0, view, SLOT( clearConditionalSelection() ), ac, "clearconditional" );
00717   actions->clearConditional->setToolTip(i18n("Remove the conditional cell formatting."));
00718 
00719   actions->validity = new KAction( i18n("Validity..."),
00720       0, view, SLOT( validity() ), ac, "validity" );
00721   actions->validity->setToolTip(i18n("Set tests to confirm cell data is valid."));
00722 
00723   actions->clearValidity = new KAction( i18n("Validity"),
00724       0, view, SLOT( clearValiditySelection() ), ac, "clearvalidity" );
00725   actions->clearValidity->setToolTip(i18n("Remove the validity tests on this cell."));
00726 
00727   actions->addModifyComment = new KAction( i18n("&Add/Modify Comment..."),"comment",
00728       0, view, SLOT( addModifyComment() ), ac, "addmodifycomment" );
00729   actions->addModifyComment->setToolTip(i18n("Edit a comment for this cell."));
00730 
00731   actions->removeComment = new KAction( i18n("&Remove Comment"),"removecomment",
00732       0,  view, SLOT( removeComment() ), ac, "removecomment" );
00733   actions->removeComment->setToolTip(i18n("Remove this cell's comment."));
00734 
00735   actions->clearComment = new KAction( i18n("Comment"),
00736       0, view, SLOT( clearCommentSelection() ), ac, "clearcomment" );
00737   actions->clearComment->setToolTip(i18n("Remove this cell's comment."));
00738 
00739   // -- column & row actions --
00740 
00741   actions->resizeColumn = new KAction( i18n("Resize Column..."), "resizecol",
00742       0, view, SLOT( resizeColumn() ), ac, "resizeCol" );
00743   actions->resizeColumn->setToolTip(i18n("Change the width of a column."));
00744 
00745   actions->insertColumn = new KAction( i18n("Insert Columns"), "insert_table_col",
00746       0, view, SLOT( insertColumn() ), ac, "insertColumn" );
00747   actions->insertColumn->setToolTip(i18n("Inserts a new column into the spreadsheet."));
00748 
00749   actions->deleteColumn = new KAction( i18n("Delete Columns"), "delete_table_col",
00750       0, view, SLOT( deleteColumn() ), ac, "deleteColumn" );
00751   actions->deleteColumn->setToolTip(i18n("Removes a column from the spreadsheet."));
00752 
00753   actions->hideColumn = new KAction( i18n("Hide Columns"), "hide_table_column",
00754       0, view, SLOT( hideColumn() ), ac, "hideColumn" );
00755   actions->hideColumn->setToolTip(i18n("Hide the column from view."));
00756 
00757   actions->showColumn = new KAction( i18n("Show Columns..."), "show_table_column",
00758       0, view, SLOT( showColumn() ), ac, "showColumn" );
00759   actions->showColumn->setToolTip(i18n("Show hidden columns."));
00760 
00761   actions->equalizeColumn = new KAction( i18n("Equalize Column"), "adjustcol",
00762       0, view, SLOT( equalizeColumn() ), ac, "equalizeCol" );
00763   actions->equalizeColumn->setToolTip(i18n("Resizes selected columns to be the same size."));
00764 
00765   actions->showSelColumns = new KAction( i18n("Show Columns"), "show_sheet_column",
00766       0, view, SLOT( showSelColumns() ), ac, "showSelColumns" );
00767   actions->showSelColumns->setToolTip(i18n("Show hidden columns in the selection."));
00768   actions->showSelColumns->setEnabled(false);
00769 
00770   actions->resizeRow = new KAction( i18n("Resize Row..."), "resizerow",
00771       0, view, SLOT( resizeRow() ), ac, "resizeRow" );
00772   actions->resizeRow->setToolTip(i18n("Change the height of a row."));
00773 
00774   actions->insertRow = new KAction( i18n("Insert Rows"), "insert_table_row",
00775       0, view, SLOT( insertRow() ), ac, "insertRow" );
00776   actions->insertRow->setToolTip(i18n("Inserts a new row into the spreadsheet."));
00777 
00778   actions->deleteRow = new KAction( i18n("Delete Rows"), "delete_table_row",
00779       0, view, SLOT( deleteRow() ), ac, "deleteRow" );
00780   actions->deleteRow->setToolTip(i18n("Removes a row from the spreadsheet."));
00781 
00782   actions->hideRow = new KAction( i18n("Hide Rows"), "hide_table_row",
00783       0, view, SLOT( hideRow() ), ac, "hideRow" );
00784   actions->hideRow->setToolTip(i18n("Hide a row from view."));
00785 
00786   actions->showRow = new KAction( i18n("Show Rows..."), "show_table_row",
00787       0, view, SLOT( showRow() ), ac, "showRow" );
00788   actions->showRow->setToolTip(i18n("Show hidden rows."));
00789 
00790   actions->equalizeRow = new KAction( i18n("Equalize Row"), "adjustrow",
00791       0, view, SLOT( equalizeRow() ), ac, "equalizeRow" );
00792   actions->equalizeRow->setToolTip(i18n("Resizes selected rows to be the same size."));
00793 
00794   actions->showSelRows = new KAction( i18n("Show Rows"), "show_table_row",
00795       0, view, SLOT( showSelRows() ), ac, "showSelRows" );
00796   actions->showSelRows->setEnabled(false);
00797   actions->showSelRows->setToolTip(i18n("Show hidden rows in the selection."));
00798 
00799   actions->adjust = new KAction( i18n("Adjust Row && Column"),
00800       0, view, SLOT( adjust() ), ac, "adjust" );
00801   actions->adjust->setToolTip(i18n("Adjusts row/column size so that the contents will fit."));
00802 
00803   // -- sheet/workbook actions --
00804   actions->sheetProperties = new KAction( i18n("Sheet Properties"),
00805       0, view, SLOT( sheetProperties() ), ac, "sheetProperties" );
00806   actions->sheetProperties->setToolTip(i18n("Modify current sheet's properties."));
00807 
00808   actions->insertSheet = new KAction( i18n("Insert Sheet"),"inserttable",
00809       0, view, SLOT( insertSheet() ), ac, "insertSheet" );
00810   actions->insertSheet->setToolTip(i18n("Insert a new sheet."));
00811 
00812   // same action as insertSheet, but without 'insert' in the caption
00813   actions->menuInsertSheet = new KAction( i18n("&Sheet"),"inserttable",
00814       0, view, SLOT( insertSheet() ), ac, "menuInsertSheet" );
00815   actions->menuInsertSheet->setToolTip(i18n("Insert a new sheet."));
00816 
00817   actions->removeSheet = new KAction( i18n("Remove Sheet"), "delete_table",
00818       0, view, SLOT( removeSheet() ), ac, "removeSheet" );
00819   actions->removeSheet->setToolTip(i18n("Remove the active sheet."));
00820 
00821   actions->renameSheet=new KAction( i18n("Rename Sheet..."),
00822       0, view, SLOT( slotRename() ), ac, "renameSheet" );
00823   actions->renameSheet->setToolTip(i18n("Rename the active sheet."));
00824 
00825   actions->showSheet = new KAction(i18n("Show Sheet..."),
00826       0, view, SLOT( showSheet()), ac, "showSheet" );
00827   actions->showSheet->setToolTip(i18n("Show a hidden sheet."));
00828 
00829   actions->hideSheet = new KAction(i18n("Hide Sheet"),
00830       0, view, SLOT( hideSheet() ), ac, "hideSheet" );
00831   actions->hideSheet->setToolTip(i18n("Hide the active sheet."));
00832 
00833   actions->autoFormat = new KAction( i18n("AutoFormat..."),
00834       0, view, SLOT( sheetFormat() ), ac, "sheetFormat" );
00835   actions->autoFormat->setToolTip(i18n("Set the worksheet formatting."));
00836 
00837   actions->areaName = new KAction( i18n("Area Name..."),
00838       0, view, SLOT( setAreaName() ), ac, "areaname" );
00839   actions->areaName->setToolTip(i18n("Set a name for a region of the spreadsheet."));
00840 
00841   actions->showArea = new KAction( i18n("Show Area..."),
00842       0, view, SLOT( showAreaName() ), ac, "showArea" );
00843   actions->showArea->setToolTip(i18n("Display a named area."));
00844 
00845   actions->insertFunction = new KAction( i18n("&Function..."), "funct",
00846       0, view, SLOT( insertMathExpr() ), ac, "insertMathExpr" );
00847   actions->insertFunction->setToolTip(i18n("Insert math expression."));
00848 
00849   actions->insertSeries = new KAction( i18n("&Series..."),"series",
00850       0, view, SLOT( insertSeries() ), ac, "series");
00851   actions->insertSeries ->setToolTip(i18n("Insert a series."));
00852 
00853   actions->insertLink = new KAction( i18n("&Link..."), "insert_link",
00854       0, view, SLOT( insertHyperlink() ), ac, "insertHyperlink" );
00855   actions->insertLink->setToolTip(i18n("Insert an Internet hyperlink."));
00856 
00857   actions->removeLink = new KAction( i18n("&Remove Link"),
00858       0, view, SLOT( removeHyperlink() ), ac, "removeHyperlink" );
00859   actions->removeLink->setToolTip(i18n("Remove a link."));
00860 
00861   actions->insertSpecialChar = new KAction( i18n( "S&pecial Character..." ), "char",
00862       view, SLOT( insertSpecialChar() ), ac, "insertSpecialChar" );
00863   actions->insertSpecialChar->setToolTip( i18n( "Insert one or more symbols or letters not found on the keyboard." ) );
00864 
00865   actions->insertPart = new KoPartSelectAction( i18n("&Object"), "frame_query",
00866       view, SLOT( insertObject() ), ac, "insertPart");
00867   actions->insertPart->setToolTip(i18n("Insert an object from another program."));
00868 
00869   actions->insertChartFrame = new KToggleAction( i18n("&Chart"), "insert_chart",
00870       0, view, SLOT( insertChart() ), ac, "insertChart" );
00871   actions->insertChartFrame->setToolTip(i18n("Insert a chart."));
00872 
00873   actions->insertPicture = new KAction( i18n("&Picture"),
00874       0, view, SLOT( insertPicture() ), ac, "insertPicture" );
00875   actions->insertPicture->setToolTip(i18n("Insert a picture."));
00876 
00877 #ifndef QT_NO_SQL
00878   actions->insertFromDatabase = new KAction( i18n("From &Database..."),
00879       0, view, SLOT( insertFromDatabase() ),  ac, "insertFromDatabase");
00880   actions->insertFromDatabase->setToolTip(i18n("Insert data from a SQL database."));
00881 #endif
00882 
00883   actions->insertFromTextfile = new KAction( i18n("From &Text File..."),
00884       0, view,  SLOT( insertFromTextfile() ), ac, "insertFromTextfile");
00885   actions->insertFromTextfile->setToolTip(i18n("Insert data from a text file to the current cursor position/selection."));
00886 
00887   actions->insertFromClipboard = new KAction( i18n("From &Clipboard..."),
00888       0, view, SLOT( insertFromClipboard() ), ac, "insertFromClipboard");
00889   actions->insertFromClipboard->setToolTip(i18n("Insert CSV data from the clipboard to the current cursor position/selection."));
00890 
00891 //   actions->transform = new KAction( i18n("Transform Object..."), "rotate",
00892 //       0, view, SLOT( transformPart() ), ac, "transform" );
00893 //   actions->transform->setToolTip(i18n("Rotate the contents of the cell."));
00894 //   actions->transform->setEnabled( false );
00895 
00896   actions->sort = new KAction( i18n("&Sort..."),
00897       0, view, SLOT( sort() ), ac, "sort" );
00898   actions->sort->setToolTip(i18n("Sort a group of cells."));
00899 
00900   actions->sortDec = new KAction( i18n("Sort &Decreasing"), "sort_decrease",
00901       0, view, SLOT( sortDec() ), ac, "sortDec" );
00902   actions->sortDec->setToolTip(i18n("Sort a group of cells in decreasing (last to first) order."));
00903 
00904   actions->sortInc = new KAction( i18n("Sort &Increasing"), "sort_incr",
00905       0, view, SLOT( sortInc() ), ac, "sortInc" );
00906   actions->sortInc->setToolTip(i18n("Sort a group of cells in ascending (first to last) order."));
00907 
00908   actions->paperLayout = new KAction( i18n("Page Layout..."),
00909       0, view, SLOT( paperLayoutDlg() ), ac, "paperLayout" );
00910   actions->paperLayout->setToolTip(i18n("Specify the layout of the spreadsheet for a printout."));
00911 
00912   actions->definePrintRange = new KAction( i18n("Define Print Range"),
00913       0, view, SLOT( definePrintRange() ), ac, "definePrintRange" );
00914   actions->definePrintRange->setToolTip(i18n("Define the print range in the current sheet."));
00915 
00916   actions->resetPrintRange = new KAction( i18n("Reset Print Range"),
00917       0, view, SLOT( resetPrintRange() ), ac, "resetPrintRange" );
00918   actions->definePrintRange->setToolTip(i18n("Define the print range in the current sheet."));
00919 
00920   actions->showPageBorders = new KToggleAction( i18n("Show Page Borders"),
00921       0, ac, "showPageBorders");
00922   actions->showPageBorders->setCheckedState(i18n("Hide Page Borders"));
00923   QObject::connect( actions->showPageBorders, SIGNAL( toggled( bool ) ),
00924       view, SLOT( togglePageBorders( bool ) ) );
00925   actions->showPageBorders->setToolTip( i18n( "Show on the spreadsheet where the page borders will be." ) );
00926 
00927   actions->recalcWorksheet = new KAction( i18n("Recalculate Sheet"),
00928       Qt::SHIFT + Qt::Key_F9, view, SLOT( recalcWorkSheet() ), ac, "RecalcWorkSheet" );
00929   actions->recalcWorksheet->setToolTip(i18n("Recalculate the value of every cell in the current worksheet."));
00930 
00931   actions->recalcWorkbook = new KAction( i18n("Recalculate Document"),
00932       Qt::Key_F9, view, SLOT( recalcWorkBook() ), ac, "RecalcWorkBook" );
00933   actions->recalcWorkbook->setToolTip(i18n("Recalculate the value of every cell in all worksheets."));
00934 
00935   actions->protectSheet = new KToggleAction( i18n( "Protect &Sheet..." ),
00936       0, ac, "protectSheet" );
00937   actions->protectSheet->setToolTip( i18n( "Protect the sheet from being modified." ) );
00938   QObject::connect( actions->protectSheet, SIGNAL( toggled( bool ) ),
00939       view, SLOT( toggleProtectSheet( bool ) ) );
00940 
00941   actions->protectDoc = new KToggleAction( i18n( "Protect &Document..." ),
00942       0, ac, "protectDoc" );
00943   actions->protectDoc->setToolTip( i18n( "Protect the document from being modified." ) );
00944   QObject::connect( actions->protectDoc, SIGNAL( toggled( bool ) ),
00945       view, SLOT( toggleProtectDoc( bool ) ) );
00946 
00947   // -- editing actions --
00948 
00949   actions->copy = KStdAction::copy( view, SLOT( copySelection() ), ac, "copy" );
00950   actions->copy->setToolTip(i18n("Copy the cell object to the clipboard."));
00951 
00952   actions->paste = KStdAction::paste( view, SLOT( paste() ), ac, "paste" );
00953   actions->paste->setToolTip(i18n("Paste the contents of the clipboard at the cursor."));
00954 
00955   actions->cut = KStdAction::cut( view, SLOT( cutSelection() ), ac, "cut" );
00956   actions->cut->setToolTip(i18n("Move the cell object to the clipboard."));
00957 
00958   actions->specialPaste = new KAction( i18n("Special Paste..."), "special_paste",
00959       0, view, SLOT( specialPaste() ), ac, "specialPaste" );
00960   actions->specialPaste->setToolTip(i18n("Paste the contents of the clipboard with special options."));
00961 
00962   actions->insertCellCopy = new KAction( i18n("Paste with Insertion"), "insertcellcopy",
00963       0, view, SLOT( slotInsertCellCopy() ), ac, "insertCellCopy" );
00964   actions->insertCellCopy->setToolTip(i18n("Inserts a cell from the clipboard into the spreadsheet."));
00965 
00966   actions->find = KStdAction::find( view, SLOT(find()), ac );
00967   /*actions->findNext =*/ KStdAction::findNext( view, SLOT( findNext() ), ac );
00968   /*actions->findPrevious =*/ KStdAction::findPrev( view, SLOT( findPrevious() ), ac );
00969 
00970   actions->replace = KStdAction::replace( view, SLOT(replace()), ac );
00971 
00972   actions->fillRight = new KAction( i18n( "&Right" ), 0,
00973       0, view, SLOT( fillRight() ), ac, "fillRight" );
00974 
00975   actions->fillLeft = new KAction( i18n( "&Left" ), 0,
00976       0, view, SLOT( fillLeft() ), ac, "fillLeft" );
00977 
00978   actions->fillDown = new KAction( i18n( "&Down" ), 0,
00979       0, view, SLOT( fillDown() ), ac, "fillDown" );
00980 
00981   actions->fillUp = new KAction( i18n( "&Up" ), 0,
00982       0, view, SLOT( fillUp() ), ac, "fillUp" );
00983 
00984   // -- misc actions --
00985 
00986   actions->styleDialog = new KAction( i18n( "Style Manager" ),
00987       0, view, SLOT( styleDialog() ), ac, "styles" );
00988   actions->styleDialog->setToolTip( i18n( "Edit and organize cell styles." ) );
00989 
00990   actions->autoSum = new KAction( i18n("Autosum"), "black_sum",
00991       0, view, SLOT( autoSum() ), ac, "autoSum" );
00992   actions->autoSum->setToolTip(i18n("Insert the 'sum' function"));
00993 
00994   actions->spellChecking = KStdAction::spelling( view, SLOT( extraSpelling() ),
00995       ac, "spelling" );
00996   actions->spellChecking->setToolTip(i18n("Check the spelling."));
00997 
00998   actions->formulaSelection = new KSelectAction(i18n("Formula Selection"),
00999       0, ac, "formulaSelection");
01000   actions->formulaSelection->setToolTip(i18n("Insert a function."));
01001   QStringList lst;
01002   lst.append( "SUM");
01003   lst.append( "AVERAGE");
01004   lst.append( "IF");
01005   lst.append( "COUNT");
01006   lst.append( "MIN");
01007   lst.append( "MAX");
01008   lst.append( i18n("Others...") );
01009   ((KSelectAction*) actions->formulaSelection)->setItems( lst );
01010   actions->formulaSelection->setComboWidth( 80 );
01011   actions->formulaSelection->setCurrentItem(0);
01012   QObject::connect( actions->formulaSelection, SIGNAL( activated( const QString& ) ),
01013       view, SLOT( formulaSelection( const QString& ) ) );
01014 
01015   actions->viewZoom = new KoZoomAction( i18n( "Zoom" ), "viewmag", 0, ac, "view_zoom" );
01016   QObject::connect( actions->viewZoom, SIGNAL( zoomChanged( const QString & ) ),
01017       view, SLOT( viewZoom( const QString & ) ) );
01018 
01019   actions->consolidate = new KAction( i18n("&Consolidate..."),
01020       0, view, SLOT( consolidate() ), ac, "consolidate" );
01021   actions->consolidate->setToolTip(i18n("Create a region of summary data from a group of similar regions."));
01022 
01023   actions->goalSeek = new KAction( i18n("&Goal Seek..."),
01024       0, view, SLOT( goalSeek() ), ac, "goalSeek" );
01025   actions->goalSeek->setToolTip( i18n("Repeating calculation to find a specific value.") );
01026 
01027   actions->subTotals = new KAction( i18n("&Subtotals..."),
01028       0, view, SLOT( subtotals() ), ac, "subtotals" );
01029   actions->subTotals->setToolTip( i18n("Create different kind of subtotals to a list or database.") );
01030 
01031   actions->textToColumns = new KAction( i18n("&Text to Columns..."),
01032       0, view, SLOT( textToColumns() ), ac, "textToColumns" );
01033   actions->textToColumns->setToolTip( i18n("Expand the content of cells to multiple columns.") );
01034 
01035   actions->multipleOperations = new KAction( i18n("&Multiple Operations..."),
01036       0, view, SLOT( multipleOperations() ), ac, "multipleOperations" );
01037   actions->multipleOperations->setToolTip( i18n("Apply the same formula to various cells using different values for the parameter.") );
01038 
01039   actions->createTemplate = new KAction( i18n( "&Create Template From Document..." ),
01040       0, view, SLOT( createTemplate() ), ac, "createTemplate" );
01041 
01042   actions->customList = new KAction( i18n("Custom Lists..."),
01043       0, view, SLOT( sortList() ), ac, "sortlist" );
01044   actions->customList->setToolTip(i18n("Create custom lists for sorting or autofill."));
01045 
01046   // -- navigation actions --
01047 
01048   actions->gotoCell = new KAction( i18n("Goto Cell..."),"goto",
01049       0, view, SLOT( gotoCell() ), ac, "gotoCell" );
01050   actions->gotoCell->setToolTip(i18n("Move to a particular cell."));
01051 
01052   actions->nextSheet = new KAction( i18n("Next Sheet"), "forward",
01053       Qt::CTRL+Qt::Key_PageDown, view, SLOT( nextSheet() ), ac, "nextSheet");
01054   actions->nextSheet->setToolTip(i18n("Move to the next sheet."));
01055 
01056   actions->prevSheet = new KAction( i18n("Previous Sheet"), "back",
01057       Qt::CTRL+Qt::Key_PageUp, view, SLOT( previousSheet() ), ac, "previousSheet");
01058   actions->prevSheet->setToolTip(i18n("Move to the previous sheet."));
01059 
01060   actions->firstSheet = new KAction( i18n("First Sheet"), "start",
01061       0, view, SLOT( firstSheet() ), ac, "firstSheet");
01062   actions->firstSheet->setToolTip(i18n("Move to the first sheet."));
01063 
01064   actions->lastSheet = new KAction( i18n("Last Sheet"), "finish",
01065       0, view, SLOT( lastSheet() ), ac, "lastSheet");
01066   actions->lastSheet->setToolTip(i18n("Move to the last sheet."));
01067 
01068   // -- settings actions --
01069 
01070   actions->showStatusBar = new KToggleAction( i18n("Show Status Bar"),
01071       0, ac, "showStatusBar" );
01072   actions->showStatusBar->setCheckedState(i18n("Hide Status Bar"));
01073   QObject::connect( actions->showStatusBar, SIGNAL( toggled( bool ) ),
01074       view, SLOT( showStatusBar( bool ) ) );
01075   actions->showStatusBar->setToolTip(i18n("Show the status bar."));
01076 
01077   actions->showTabBar = new KToggleAction( i18n("Show Tab Bar"),
01078       0, ac, "showTabBar" );
01079   actions->showTabBar->setCheckedState(i18n("Hide Tab Bar"));
01080   QObject::connect( actions->showTabBar, SIGNAL( toggled( bool ) ),
01081       view, SLOT( showTabBar( bool ) ) );
01082   actions->showTabBar->setToolTip(i18n("Show the tab bar."));
01083 
01084   actions->showFormulaBar = new KToggleAction( i18n("Show Formula Bar"),
01085       0, ac, "showFormulaBar" );
01086   actions->showFormulaBar->setCheckedState(i18n("Hide Formula Bar"));
01087   QObject::connect( actions->showFormulaBar, SIGNAL( toggled( bool ) ),
01088       view, SLOT( showFormulaBar( bool ) ) );
01089   actions->showFormulaBar->setToolTip(i18n("Show the formula bar."));
01090 
01091   actions->preference = new KAction( i18n("Configure KSpread..."),"configure",
01092       0, view, SLOT( preference() ), ac, "preference" );
01093   actions->preference->setToolTip(i18n("Set various KSpread options."));
01094 
01095   // -- running calculation actions --
01096 
01097   actions->calcNone = new KToggleAction( i18n("None"), 0, ac, "menu_none");
01098   QObject::connect( actions->calcNone, SIGNAL( toggled( bool ) ),
01099       view, SLOT( menuCalc( bool ) ) );
01100   actions->calcNone->setExclusiveGroup( "Calc" );
01101   actions->calcNone->setToolTip(i18n("No calculation"));
01102 
01103   actions->calcSum = new KToggleAction( i18n("Sum"), 0, ac, "menu_sum");
01104   QObject::connect( actions->calcSum, SIGNAL( toggled( bool ) ),
01105       view, SLOT( menuCalc( bool ) ) );
01106   actions->calcSum->setExclusiveGroup( "Calc" );
01107   actions->calcSum->setToolTip(i18n("Calculate using sum."));
01108 
01109   actions->calcMin = new KToggleAction( i18n("Min"), 0, ac, "menu_min");
01110   QObject::connect( actions->calcMin, SIGNAL( toggled( bool ) ),
01111       view, SLOT( menuCalc( bool ) ) );
01112   actions->calcMin->setExclusiveGroup( "Calc" );
01113   actions->calcMin->setToolTip(i18n("Calculate using minimum."));
01114 
01115   actions->calcMax = new KToggleAction( i18n("Max"), 0, ac, "menu_max");
01116   QObject::connect( actions->calcMax, SIGNAL( toggled( bool ) ),
01117       view, SLOT( menuCalc( bool ) ) );
01118   actions->calcMax->setExclusiveGroup( "Calc" );
01119   actions->calcMax->setToolTip(i18n("Calculate using maximum."));
01120 
01121   actions->calcAverage = new KToggleAction( i18n("Average"), 0, ac, "menu_average");
01122   QObject::connect( actions->calcAverage, SIGNAL( toggled( bool ) ),
01123       view, SLOT( menuCalc( bool ) ) );
01124   actions->calcAverage->setExclusiveGroup( "Calc" );
01125   actions->calcAverage->setToolTip(i18n("Calculate using average."));
01126 
01127   actions->calcCount = new KToggleAction( i18n("Count"), 0, ac, "menu_count");
01128   QObject::connect( actions->calcCount, SIGNAL( toggled( bool ) ),
01129       view, SLOT( menuCalc( bool ) ) );
01130   actions->calcCount->setExclusiveGroup( "Calc" );
01131   actions->calcCount->setToolTip(i18n("Calculate using the count."));
01132 
01133   actions->calcCountA = new KToggleAction( i18n("CountA"), 0, ac, "menu_counta");
01134   QObject::connect( actions->calcCountA, SIGNAL( toggled( bool ) ),
01135       view, SLOT( menuCalc( bool ) ) );
01136   actions->calcCountA->setExclusiveGroup( "Calc" );
01137   actions->calcCountA->setToolTip(i18n("Calculate using the countA."));
01138 
01139   // -- special action, only for developers --
01140 
01141   actions->internalTests = new KAction( i18n("Run Internal Tests..."), "internalTests",
01142       Qt::CTRL+ Qt::SHIFT + Qt::Key_T, view, SLOT( runInternalTests() ), ac, "internalTests" );
01143   actions->inspector = new KAction( i18n("Run Inspector..."), "inspector",
01144       Qt::CTRL+ Qt::SHIFT + Qt::Key_I, view, SLOT( runInspector() ), ac, "inspector" );
01145 
01146   m_propertyEditor = 0;
01147 }
01148 
01149 void View::Private::adjustActions( bool mode )
01150 {
01151   actions->replace->setEnabled( mode );
01152   actions->insertSeries->setEnabled( mode );
01153   actions->insertLink->setEnabled( mode );
01154   actions->insertSpecialChar->setEnabled( mode );
01155   actions->insertFunction->setEnabled( mode );
01156   actions->removeComment->setEnabled( mode );
01157   actions->decreaseIndent->setEnabled( mode );
01158   actions->bold->setEnabled( mode );
01159   actions->italic->setEnabled( mode );
01160   actions->underline->setEnabled( mode );
01161   actions->strikeOut->setEnabled( mode );
01162   actions->percent->setEnabled( mode );
01163   actions->precplus->setEnabled( mode );
01164   actions->precminus->setEnabled( mode );
01165   actions->money->setEnabled( mode );
01166   actions->alignLeft->setEnabled( mode );
01167   actions->alignCenter->setEnabled( mode );
01168   actions->alignRight->setEnabled( mode );
01169   actions->alignTop->setEnabled( mode );
01170   actions->alignMiddle->setEnabled( mode );
01171   actions->alignBottom->setEnabled( mode );
01172   actions->paste->setEnabled( mode );
01173   actions->cut->setEnabled( mode );
01174   actions->specialPaste->setEnabled( mode );
01175   actions->deleteCell->setEnabled( mode );
01176   actions->clearText->setEnabled( mode );
01177   actions->clearComment->setEnabled( mode );
01178   actions->clearValidity->setEnabled( mode );
01179   actions->clearConditional->setEnabled( mode );
01180   actions->recalcWorkbook->setEnabled( mode );
01181   actions->recalcWorksheet->setEnabled( mode );
01182   actions->adjust->setEnabled( mode );
01183   actions->editCell->setEnabled( mode );
01184   actions->paperLayout->setEnabled( mode );
01185   actions->styleDialog->setEnabled( mode );
01186   actions->definePrintRange->setEnabled( mode );
01187   actions->resetPrintRange->setEnabled( mode );
01188   actions->insertFromDatabase->setEnabled( mode );
01189   actions->insertFromTextfile->setEnabled( mode );
01190   actions->insertFromClipboard->setEnabled( mode );
01191   actions->conditional->setEnabled( mode );
01192   actions->validity->setEnabled( mode );
01193   actions->goalSeek->setEnabled( mode );
01194   actions->subTotals->setEnabled( mode );
01195   actions->multipleOperations->setEnabled( mode );
01196   actions->textToColumns->setEnabled( mode );
01197   actions->consolidate->setEnabled( mode );
01198   actions->insertCellCopy->setEnabled( mode );
01199   actions->wrapText->setEnabled( mode );
01200   actions->selectFont->setEnabled( mode );
01201   actions->selectFontSize->setEnabled( mode );
01202   actions->deleteColumn->setEnabled( mode );
01203   actions->hideColumn->setEnabled( mode );
01204   actions->showColumn->setEnabled( mode );
01205   actions->showSelColumns->setEnabled( mode );
01206   actions->insertColumn->setEnabled( mode );
01207   actions->deleteRow->setEnabled( mode );
01208   actions->insertRow->setEnabled( mode );
01209   actions->hideRow->setEnabled( mode );
01210   actions->showRow->setEnabled( mode );
01211   actions->showSelRows->setEnabled( mode );
01212   actions->formulaSelection->setEnabled( mode );
01213   actions->textColor->setEnabled( mode );
01214   actions->bgColor->setEnabled( mode );
01215   actions->cellLayout->setEnabled( mode );
01216   actions->borderLeft->setEnabled( mode );
01217   actions->borderRight->setEnabled( mode );
01218   actions->borderTop->setEnabled( mode );
01219   actions->borderBottom->setEnabled( mode );
01220   actions->borderAll->setEnabled( mode );
01221   actions->borderOutline->setEnabled( mode );
01222   actions->borderRemove->setEnabled( mode );
01223   actions->borderColor->setEnabled( mode );
01224   actions->removeSheet->setEnabled( mode );
01225   actions->autoSum->setEnabled( mode );
01226   actions->defaultFormat->setEnabled( mode );
01227   actions->areaName->setEnabled( mode );
01228   actions->resizeRow->setEnabled( mode );
01229   actions->resizeColumn->setEnabled( mode );
01230   actions->fontSizeUp->setEnabled( mode );
01231   actions->fontSizeDown->setEnabled( mode );
01232   actions->upper->setEnabled( mode );
01233   actions->lower->setEnabled( mode );
01234   actions->equalizeRow->setEnabled( mode );
01235   actions->equalizeColumn->setEnabled( mode );
01236   actions->verticalText->setEnabled( mode );
01237   actions->addModifyComment->setEnabled( mode );
01238   actions->removeComment->setEnabled( mode );
01239   actions->insertCell->setEnabled( mode );
01240   actions->removeCell->setEnabled( mode );
01241   actions->changeAngle->setEnabled( mode );
01242   actions->dissociateCell->setEnabled( mode );
01243   actions->increaseIndent->setEnabled( mode );
01244   actions->decreaseIndent->setEnabled( mode );
01245   actions->spellChecking->setEnabled( mode );
01246   actions->calcMin->setEnabled( mode );
01247   actions->calcMax->setEnabled( mode );
01248   actions->calcAverage->setEnabled( mode );
01249   actions->calcCount->setEnabled( mode );
01250   actions->calcCountA->setEnabled( mode );
01251   actions->calcSum->setEnabled( mode );
01252   actions->calcNone->setEnabled( mode );
01253   actions->insertPart->setEnabled( mode );
01254   actions->createStyle->setEnabled( mode );
01255   actions->selectStyle->setEnabled( mode );
01256 
01257   actions->autoFormat->setEnabled( false );
01258   actions->sort->setEnabled( false );
01259   actions->mergeCell->setEnabled( false );
01260   actions->mergeCellHorizontal->setEnabled( false );
01261   actions->mergeCellVertical->setEnabled( false );
01262   actions->insertChartFrame->setEnabled( false );
01263   actions->sortDec->setEnabled( false );
01264   actions->sortInc->setEnabled( false );
01265 //   actions->transform->setEnabled( false );
01266 
01267   actions->fillRight->setEnabled( false );
01268   actions->fillLeft->setEnabled( false );
01269   actions->fillUp->setEnabled( false );
01270   actions->fillDown->setEnabled( false );
01271 
01272   if ( mode && !view->doc()->map()->isProtected() )
01273     actions->renameSheet->setEnabled( true );
01274   else
01275     actions->renameSheet->setEnabled( false );
01276 
01277   actions->showStatusBar->setChecked( view->doc()->showStatusBar() );
01278   actions->showTabBar->setChecked( view->doc()->showTabBar() );
01279   actions->showFormulaBar->setChecked( view->doc()->showFormulaBar() );
01280 
01281   formulaButton->setEnabled( mode );
01282 
01283   if ( activeSheet )
01284   {
01285     selection->update();
01286     view->objectSelectedChanged();
01287   }
01288 }
01289 
01290 void View::Private::adjustActions( Sheet* sheet, Cell* cell )
01291 {
01292   if ( sheet->isProtected() && !cell->isDefault() && cell->format()->notProtected( cell->column(), cell->row() ) )
01293   {
01294     if ( selection->isSingular() )
01295     {
01296       if ( !actions->bold->isEnabled() )
01297         adjustActions( true );
01298     }
01299     else
01300     {
01301       if ( actions->bold->isEnabled() )
01302         adjustActions( false );
01303     }
01304   }
01305   else if ( sheet->isProtected() )
01306   {
01307     if ( actions->bold->isEnabled() )
01308       adjustActions( false );
01309   }
01310 }
01311 
01312 void View::Private::adjustWorkbookActions( bool mode )
01313 {
01314   tabBar->setReadOnly( !view->doc()->isReadWrite() || view->doc()->map()->isProtected() );
01315 
01316   actions->hideSheet->setEnabled( mode );
01317   actions->showSheet->setEnabled( mode );
01318   actions->insertSheet->setEnabled( mode );
01319   actions->menuInsertSheet->setEnabled( mode );
01320   actions->removeSheet->setEnabled( mode );
01321 
01322   if ( mode )
01323   {
01324     if ( activeSheet && !activeSheet->isProtected() )
01325     {
01326       bool state = ( view->doc()->map()->visibleSheets().count() > 1 );
01327       actions->removeSheet->setEnabled( state );
01328       actions->hideSheet->setEnabled( state );
01329     }
01330     actions->showSheet->setEnabled( view->doc()->map()->hiddenSheets().count() > 0 );
01331     actions->renameSheet->setEnabled( activeSheet && !activeSheet->isProtected() );
01332   }
01333 }
01334 
01335 // TODO this should be merged with adjustActions
01336 void View::Private::updateButton( Cell *cell, int column, int row)
01337 {
01338     toolbarLock = true;
01339 
01340     // workaround for bug #59291 (crash upon starting from template)
01341     // certain Qt and Fontconfig combination fail miserably if can not
01342     // find the font name (e.g. not installed in the system)
01343     QStringList fontList;
01344     KFontChooser::getFontList( fontList, 0 );
01345     QString fontFamily = cell->format()->textFontFamily( column,row );
01346     for ( QStringList::Iterator it = fontList.begin(); it != fontList.end(); ++it )
01347       if ((*it).lower() == fontFamily.lower())
01348       {
01349         actions->selectFont->setFont( fontFamily );
01350         break;
01351       }
01352 
01353       actions->selectFontSize->setFontSize( cell->format()->textFontSize( column, row ) );
01354       actions->bold->setChecked( cell->format()->textFontBold( column, row ) );
01355       actions->italic->setChecked( cell->format()->textFontItalic(  column, row) );
01356       actions->underline->setChecked( cell->format()->textFontUnderline( column, row ) );
01357       actions->strikeOut->setChecked( cell->format()->textFontStrike( column, row ) );
01358 
01359       actions->alignLeft->setChecked( cell->format()->align( column, row ) == Format::Left );
01360       actions->alignCenter->setChecked( cell->format()->align( column, row ) == Format::Center );
01361       actions->alignRight->setChecked( cell->format()->align( column, row ) == Format::Right );
01362 
01363       actions->alignTop->setChecked( cell->format()->alignY( column, row ) == Format::Top );
01364       actions->alignMiddle->setChecked( cell->format()->alignY( column, row ) == Format::Middle );
01365       actions->alignBottom->setChecked( cell->format()->alignY( column, row ) == Format::Bottom );
01366 
01367       actions->verticalText->setChecked( cell->format()->verticalText( column,row ) );
01368 
01369       actions->wrapText->setChecked( cell->format()->multiRow( column,row ) );
01370 
01371     FormatType ft = cell->formatType();
01372     actions->percent->setChecked( ft == Percentage_format );
01373     actions->money->setChecked( ft == Money_format );
01374 
01375     if ( activeSheet && !activeSheet->isProtected() )
01376       actions->removeComment->setEnabled( !cell->format()->comment(column,row).isEmpty() );
01377 
01378     if ( activeSheet && !activeSheet->isProtected() )
01379       actions->decreaseIndent->setEnabled( cell->format()->getIndent( column, row ) > 0.0 );
01380 
01381     toolbarLock = false;
01382     if ( activeSheet )
01383       adjustActions( activeSheet, cell );
01384 }
01385 
01386 QButton* View::Private::newIconButton( const char *_file, bool _kbutton, QWidget *_parent )
01387 {
01388   if ( _parent == 0L )
01389     _parent = view;
01390 
01391   if ( !_kbutton ) {
01392     QPushButton* pb = new QPushButton( _parent );
01393     pb->setIconSet( SmallIconSet(_file) );
01394     return pb;
01395   } else {
01396     QToolButton* pb = new QToolButton( _parent );
01397     pb->setIconSet( SmallIconSet(_file) );
01398     return pb;
01399   }
01400 }
01401 
01402 KPSheetSelectPage::KPSheetSelectPage( QWidget *parent )
01403 : KPrintDialogPage(parent),
01404   gui(new SheetSelectWidget(this))
01405 {
01406   setTitle(gui->caption());
01407 
01408   //disabling automated sorting
01409   gui->ListViewAvailable->setSorting(-1);
01410   gui->ListViewSelected->setSorting(-1);
01411 
01412   //connect buttons
01413   connect(gui->ButtonSelectAll,SIGNAL(clicked()),this,SLOT(selectAll()));
01414   connect(gui->ButtonSelect,SIGNAL(clicked()),this,SLOT(select()));
01415   connect(gui->ButtonRemove,SIGNAL(clicked()),this,SLOT(remove()));
01416   connect(gui->ButtonRemoveAll,SIGNAL(clicked()),this,SLOT(removeAll()));
01417 
01418   connect(gui->ButtonMoveTop,SIGNAL(clicked()),this,SLOT(moveTop()));
01419   connect(gui->ButtonMoveUp,SIGNAL(clicked()),this,SLOT(moveUp()));
01420   connect(gui->ButtonMoveDown,SIGNAL(clicked()),this,SLOT(moveDown()));
01421   connect(gui->ButtonMoveBottom,SIGNAL(clicked()),this,SLOT(moveBottom()));
01422 }
01423 
01424 // KPSheetSelectPage::~KPSheetSelectPage()
01425 // {
01426 // }
01427 
01428 void KPSheetSelectPage::getOptions( QMap<QString,QString>& opts, bool /*incldef*/ )
01429 {
01430   QStringList sheetlist = this->selectedSheets();
01431   QStringList::iterator it;
01432   unsigned int i = 0;
01433   for (it = sheetlist.begin(); it != sheetlist.end(); ++it, i++)
01434   {
01435     opts.insert(printOptionForIndex(i),*it);
01436   }
01437 }
01438 
01439 void KPSheetSelectPage::setOptions( const QMap<QString,QString>& opts )
01440 {
01441   unsigned int i = 0;
01442   QStringList sheetlist;
01443   while (opts.contains(printOptionForIndex(i)))
01444   {
01445     sheetlist.prepend(opts[printOptionForIndex(i++)]);
01446   }
01447 
01448   QStringList::iterator it;
01449   for (it = sheetlist.begin(); it != sheetlist.end(); ++it)
01450   {
01451     kdDebug() << " adding sheet to list of printed sheets: " << *it << endl;
01452     this->prependSelectedSheet(*it);
01453   }
01454 }
01455 
01456 bool KPSheetSelectPage::isValid(QString& /*msg*/)
01457 {
01458   // we print the activeSheet() by default if no sheet is selected,
01459   // so we return true in any case
01460 
01461 //   Q_ASSERT(gui);
01462 //   if (gui->ListViewSelected->childCount() < 1)
01463 //   {
01464 //     msg = i18n("No sheets selected for printing!");
01465 //     return false;
01466 //   }
01467   return true;
01468 }
01469 
01470 QString KPSheetSelectPage::printOptionForIndex(unsigned int index)
01471 {
01472   return QString("sheetprintorder%1").arg(index);
01473 }
01474 
01475 void KPSheetSelectPage::prependAvailableSheet(const QString& sheetname)
01476 {
01477   Q_ASSERT(gui);
01478   new QListViewItem(gui->ListViewAvailable,sheetname);
01479 }
01480 
01481 void KPSheetSelectPage::prependSelectedSheet(const QString& sheetname)
01482 {
01483   Q_ASSERT(gui);
01484   new QListViewItem(gui->ListViewSelected,sheetname);
01485 }
01486 
01487 QStringList KPSheetSelectPage::selectedSheets()
01488 {
01489   Q_ASSERT(gui);
01490   QStringList list;
01491   QListViewItem* item = gui->ListViewSelected->firstChild();
01492   while (item)
01493   {
01494     list.append(item->text(0));
01495     item = item->nextSibling();
01496   }
01497   return list;
01498 }
01499 
01500 QStringList KPSheetSelectPage::selectedSheets(KPrinter &prt)
01501 {
01502   QStringList list;
01503   unsigned int index;
01504   const QMap<QString,QString>& options = prt.options();
01505   for (index = 0; options.contains(KPSheetSelectPage::printOptionForIndex(index)); index++)
01506   {
01507     list.append(options[KPSheetSelectPage::printOptionForIndex(index)]);
01508   }
01509   return list;
01510 }
01511 
01512 void KPSheetSelectPage::clearSelection()
01513 {
01514   gui->ListViewSelected->clear();
01515 }
01516 
01517 void KPSheetSelectPage::selectAll()
01518 {
01519   //we have to add all the stuff in reverse order
01520   // because inserted items (prependSelectedSheet) are prepended
01521   QStringList list;
01522   QListViewItem* item = gui->ListViewAvailable->firstChild();
01523   while (item)
01524   {
01525     list.prepend(item->text(0));
01526     item = item->nextSibling();
01527   }
01528   QStringList::iterator it;
01529   for (it = list.begin(); it != list.end(); ++it)
01530   {
01531     this->prependSelectedSheet(*it);
01532   }
01533 }
01534 
01535 void KPSheetSelectPage::select()
01536 {
01537   //we have to add all the stuff in reverse order
01538   // because inserted items (prependSelectedSheet) are prepended
01539   QStringList list;
01540   QListViewItem* item = gui->ListViewAvailable->firstChild();
01541   while (item)
01542   {
01543     if (item->isSelected())
01544       list.prepend(item->text(0));
01545     item = item->nextSibling();
01546   }
01547   QStringList::iterator it;
01548   for (it = list.begin(); it != list.end(); ++it)
01549   {
01550     this->prependSelectedSheet(*it);
01551   }
01552 }
01553 
01554 void KPSheetSelectPage::remove()
01555 {
01556   QListViewItem* item = gui->ListViewSelected->firstChild();
01557   QListViewItem* nextitem = NULL;
01558   while (item)
01559   {
01560     nextitem = item->nextSibling();
01561     if (item->isSelected())
01562       delete item;
01563     item = nextitem;
01564   }
01565 }
01566 
01567 void KPSheetSelectPage::removeAll()
01568 {
01569   gui->ListViewSelected->clear();
01570 }
01571 
01572 
01573 void KPSheetSelectPage::moveTop()
01574 {
01575   //this creates a temporary new list (selected first, then rest)
01576   // which replaces the existing one, to avoid the need of an additional sort column
01577 
01578   QValueList<QListViewItem*> newlist;
01579   QListViewItem* item = gui->ListViewSelected->firstChild();
01580   QListViewItem* nextitem = NULL;
01581 //   kdDebug() << "Filling new list with selected items first" << endl;
01582   while (item)
01583   {
01584     nextitem = item->nextSibling();
01585     if (item->isSelected())
01586     {
01587       newlist.prepend(item);
01588       gui->ListViewSelected->takeItem(item);
01589     }
01590     item = nextitem;
01591   }
01592 //   kdDebug() << "Appending the rest" << endl;
01593   item = gui->ListViewSelected->firstChild();
01594   while (item)
01595   {
01596 //     kdDebug() << " processing item " << item->text(0) << endl;
01597     nextitem = item->nextSibling();
01598     if (!item->isSelected())
01599     {
01600       newlist.prepend(item);
01601       gui->ListViewSelected->takeItem(item);
01602     }
01603     item = nextitem;
01604   }
01605 
01606 //   kdDebug() << "Refill the view with the correctly ordered list" << endl;
01607   //the view is empty now, refill in correct order (reversed!!)
01608   QValueList<QListViewItem*>::iterator it;
01609   for (it = newlist.begin(); it != newlist.end(); ++it)
01610   {
01611 //     kdDebug() << " adding " << (*it)->text(0) << endl;
01612     gui->ListViewSelected->insertItem(*it);
01613   }
01614 }
01615 
01616 void KPSheetSelectPage::moveUp()
01617 {
01618   //this creates a temporary new list
01619   // which replaces the existing one, to avoid the need of an additional sort column
01620 
01621   QValueList<QListViewItem*> newlist;
01622   QListViewItem* item = gui->ListViewSelected->firstChild();
01623   QListViewItem* nextitem = NULL;
01624   while (item)
01625   {
01626     nextitem = item->nextSibling();
01627     if (!item->isSelected())
01628     {
01629       while (nextitem && nextitem->isSelected())
01630       {
01631         QListViewItem* nextnextitem = nextitem->nextSibling();
01632         newlist.prepend(nextitem);
01633         gui->ListViewSelected->takeItem(nextitem);
01634         nextitem = nextnextitem;
01635       }
01636     }
01637 
01638     newlist.prepend(item);
01639     gui->ListViewSelected->takeItem(item);
01640     item = nextitem;
01641   }
01642 
01643 //   kdDebug() << "Refill the view with the correctly ordered list" << endl;
01644   //the view is empty now, refill in correct order (reversed!!)
01645   QValueList<QListViewItem*>::iterator it;
01646   for (it = newlist.begin(); it != newlist.end(); ++it)
01647   {
01648 //     kdDebug() << " adding " << (*it)->text(0) << endl;
01649     gui->ListViewSelected->insertItem(*it);
01650   }
01651 }
01652 
01653 void KPSheetSelectPage::moveDown()
01654 {
01655   QListViewItem* item = gui->ListViewSelected->lastItem();
01656 //   while (item)
01657 //   {
01658 //     nextitem = item->nextSibling();
01659 //     if (previousitem && previousitem->isSelected())
01660 //     {
01661 //       previousitem->moveItem(item);
01662 //     }
01663 //     previousitem = item;
01664 //     item = nextitem;
01665 //   }
01666   while (item)
01667   {
01668     while (item && !item->isSelected() && item->itemAbove() && item->itemAbove()->isSelected())
01669     {
01670       QListViewItem* tempitem = item->itemAbove();
01671       tempitem->moveItem(item);
01672     }
01673     if (item)
01674       item = item->itemAbove();
01675   }
01676 }
01677 
01678 void KPSheetSelectPage::moveBottom()
01679 {
01680   //this creates a temporary new list (unselected first, then rest)
01681   // which replaces the existing one, to avoid the need of an additional sort column
01682 
01683   QValueList<QListViewItem*> newlist;
01684   QListViewItem* item = gui->ListViewSelected->firstChild();
01685   QListViewItem* nextitem = NULL;
01686 //   kdDebug() << "Filling new list with unselected items first" << endl;
01687   while (item)
01688   {
01689 //     kdDebug() << " processing item " << item->text(0) << endl;
01690     nextitem = item->nextSibling();
01691     if (!item->isSelected())
01692     {
01693       newlist.prepend(item);
01694       gui->ListViewSelected->takeItem(item);
01695     }
01696     item = nextitem;
01697   }
01698 //   kdDebug() << "Appending the rest" << endl;
01699   item = gui->ListViewSelected->firstChild();
01700   while (item)
01701   {
01702     nextitem = item->nextSibling();
01703     if (item->isSelected())
01704     {
01705       newlist.prepend(item);
01706       gui->ListViewSelected->takeItem(item);
01707     }
01708     item = nextitem;
01709   }
01710 
01711 //   kdDebug() << "Refill the view with the correctly ordered list" << endl;
01712   //the view is empty now, refill in correct order (reversed!!)
01713   QValueList<QListViewItem*>::iterator it;
01714   for (it = newlist.begin(); it != newlist.end(); ++it)
01715   {
01716 //     kdDebug() << " adding " << (*it)->text(0) << endl;
01717     gui->ListViewSelected->insertItem(*it);
01718   }
01719 }
01720 
01721 
01722 /*****************************************************************************
01723  *
01724  * View
01725  *
01726  *****************************************************************************/
01727 
01728 View::View( QWidget *_parent, const char *_name,
01729     Doc *_doc )
01730   : KoView( _doc, _parent, _name )
01731 {
01732     ElapsedTime et( "View constructor" );
01733     kdDebug(36001) << "sizeof(Cell)=" << sizeof(Cell) <<endl;
01734 
01735     d = new Private;
01736     d->view = this;
01737     d->doc = _doc;
01738 
01739     d->dcop = 0;
01740 
01741     d->activeSheet = 0;
01742 
01743     d->toolbarLock = false;
01744     d->loading = false;
01745 
01746     d->selection = new Selection( this );
01747     d->choice = new Selection( this );
01748     d->choice->setMultipleSelection(true);
01749     connect(d->selection, SIGNAL(changed(const Region&)), this, SLOT(slotChangeSelection(const Region&)));
01750     connect(d->choice, SIGNAL(changed(const Region&)), this, SLOT(slotChangeChoice(const Region&)));
01751 
01752     d->findOptions = 0;
01753     d->findLeftColumn = 0;
01754     d->findRightColumn = 0;
01755     d->typeValue = FindOption::Value;
01756     d->directionValue = FindOption::Row;
01757     d->find = 0;
01758     d->replace = 0;
01759 
01760     d->popupMenuFirstToolId = 0;
01761     d->popupMenu   = 0;
01762     d->popupColumn = 0;
01763     d->popupRow    = 0;
01764     d->popupChild   = 0;
01765     d->popupListChoose = 0;
01766     d->popupChildObject = 0;
01767 
01768     d->searchInSheets.currentSheet = 0;
01769     d->searchInSheets.firstSheet = 0;
01770 
01771     // spell-check context
01772     d->spell.kspell = 0;
01773     d->spell.macroCmdSpellCheck = 0;
01774     d->spell.firstSpellSheet = 0;
01775     d->spell.currentSpellSheet = 0;
01776     d->spell.currentCell = 0;
01777     d->spell.spellStartCellX = 0;
01778     d->spell.spellStartCellY = 0;
01779     d->spell.spellEndCellX   = 0;
01780     d->spell.spellEndCellY   = 0;
01781     d->spell.spellCheckSelection = false;
01782 
01783     d->insertHandler = 0L;
01784     d->specialCharDlg = 0;
01785 
01786     setInstance( Factory::global() );
01787     if ( doc()->isReadWrite() )
01788       setXMLFile( "kspread.rc" );
01789     else
01790       setXMLFile( "kspread_readonly.rc" );
01791 
01792     // build the DCOP object
01793     dcopObject();
01794 
01795     connect( doc()->commandHistory(), SIGNAL( commandExecuted() ),
01796         this, SLOT( commandExecuted() ) );
01797 
01798     // GUI Initializations
01799     initView();
01800 
01801     d->initActions();
01802 
01803 
01804     // Handler for moving and resizing embedded parts
01805     KoContainerHandler* h = new KoContainerHandler( this, d->canvas );
01806     connect( h, SIGNAL( popupMenu( KoChild*, const QPoint& ) ), this, SLOT( popupChildMenu( KoChild*, const QPoint& ) ) );
01807 
01808 
01809     connect( this, SIGNAL( childSelected( KoDocumentChild* ) ),
01810              this, SLOT( slotChildSelected( KoDocumentChild* ) ) );
01811     connect( this, SIGNAL( childUnselected( KoDocumentChild* ) ),
01812              this, SLOT( slotChildUnselected( KoDocumentChild* ) ) );
01813     // If a selected part becomes active this is like it is deselected
01814     // just before.
01815     connect( this, SIGNAL( childActivated( KoDocumentChild* ) ),
01816              this, SLOT( slotChildUnselected( KoDocumentChild* ) ) );
01817 
01818     connect( d->canvas, SIGNAL( objectSelectedChanged() ),
01819              this, SLOT( objectSelectedChanged() ) );
01820 
01821     QObject::connect( doc()->map(), SIGNAL( sig_addSheet( Sheet* ) ), SLOT( slotAddSheet( Sheet* ) ) );
01822 
01823     QObject::connect( doc(), SIGNAL( sig_refreshView(  ) ), this, SLOT( slotRefreshView() ) );
01824 
01825     QObject::connect( doc(), SIGNAL( sig_refreshLocale() ), this, SLOT( refreshLocale()));
01826 
01827     QObject::connect( doc(), SIGNAL( sig_addAreaName( const QString & ) ), d->posWidget, SLOT( slotAddAreaName( const QString & ) ) );
01828 
01829     QObject::connect( doc(), SIGNAL( sig_removeAreaName( const QString & ) ), d->posWidget, SLOT( slotRemoveAreaName( const QString & ) ) );
01830 
01831     QObject::connect( doc(), SIGNAL( damagesFlushed( const QValueList<Damage*>& ) ),
01832         this, SLOT( handleDamages( const QValueList<Damage*>& ) ) );
01833 
01834     //KoView::setZoom( doc()->zoomedResolutionY() /* KoView only supports one zoom */ ); // initial value
01835     //when kspread is embedded into konqueror apply a zoom=100
01836     //in konqueror we can't change zoom -- ### TODO ?
01837     if (!doc()->isReadWrite())
01838     {
01839         setZoom( 100, true );
01840     }
01841 
01842     viewZoom( QString::number( doc()->zoom() ) );
01843 
01844     // ## Might be wrong, if doc isn't loaded yet
01845     d->actions->selectStyle->setItems( d->doc->styleManager()->styleNames() );
01846 
01847     // If doc was already loaded, initialize things
01848     // Otherwise the doc will do it in completeLoading.
01849     if ( !doc()->map()->sheetList().isEmpty() )
01850         initialPosition();
01851 
01852     connect (&d->statusBarOpTimer, SIGNAL(timeout()), this, SLOT(calcStatusBarOp()));
01853 }
01854 
01855 View::~View()
01856 {
01857     //  ElapsedTime el( "~View" );
01858     if ( doc()->isReadWrite() ) // make sure we're not embedded in Konq
01859         deleteEditor( true );
01860     if ( !d->transformToolBox.isNull() )
01861         delete (&*d->transformToolBox);
01862     /*if (d->calcLabel)
01863     {
01864         disconnect(d->calcLabel,SIGNAL(pressed( int )),this,SLOT(statusBarClicked(int)));
01865 
01866         }*/
01867 
01868     delete d->spell.kspell;
01869 
01870     d->canvas->endChoose();
01871     d->activeSheet = 0; // set the active sheet to 0L so that when during destruction
01872     // of embedded child documents possible repaints in Sheet are not
01873     // performed. The repains can happen if you delete an embedded document,
01874     // which leads to an regionInvalidated() signal emission in KoView, which calls
01875     // repaint, etc.etc. :-) (Simon)
01876 
01877     delete d->selection;
01878     delete d->choice;
01879 
01880     delete d->popupColumn;
01881     delete d->popupRow;
01882     delete d->popupMenu;
01883     delete d->popupChild;
01884     delete d->popupListChoose;
01885     delete d->calcLabel;
01886     delete d->dcop;
01887 
01888     delete d->insertHandler;
01889     d->insertHandler = 0L;
01890 
01891     delete d->actions;
01892     delete d;
01893 }
01894 
01895 Doc* View::doc() const
01896 {
01897   return d->doc;
01898 }
01899 
01900 // should be called only once, from the constructor
01901     /*
01902      * Top part is the formula bar.
01903      * Central part is the canvas, row header and vertical scrollbar.
01904      * Bottom part is the tab bar and horizontal scrollbar.
01905      *
01906      * Note that canvas must the one to be created, since other
01907      * widgets might depend on it.
01908      */
01909 
01910 void View::initView()
01911 {
01912     d->viewLayout = new QGridLayout( this, 3, 4 );
01913 
01914     // Vert. Scroll Bar
01915     d->calcLabel  = 0;
01916     d->vertScrollBar = new QScrollBar( this, "ScrollBar_2" );
01917     d->vertScrollBar->setRange( 0, 4096 );
01918     d->vertScrollBar->setOrientation( QScrollBar::Vertical );
01919     d->vertScrollBar->setLineStep(60);  //just random guess based on what feels okay
01920     d->vertScrollBar->setPageStep(60);  //This should be controlled dynamically, depending on how many rows are shown
01921 
01922     // Edit Bar
01923     d->toolWidget = new QFrame( this );
01924 
01925     d->formulaBarLayout = new QHBoxLayout( d->toolWidget );
01926     d->formulaBarLayout->setMargin( 4 );
01927     d->formulaBarLayout->addSpacing( 2 );
01928 
01929     d->posWidget = new ComboboxLocationEditWidget( d->toolWidget, this );
01930     d->posWidget->setMinimumWidth( 100 );
01931     d->formulaBarLayout->addWidget( d->posWidget );
01932     d->formulaBarLayout->addSpacing( 6 );
01933 
01934     d->formulaButton = d->newIconButton( "funct", true, d->toolWidget );
01935     d->formulaBarLayout->addWidget( d->formulaButton );
01936     d->formulaBarLayout->addSpacing( 2 );
01937     connect( d->formulaButton, SIGNAL( clicked() ), SLOT( insertMathExpr() ) );
01938 
01939     d->cancelButton = d->newIconButton( "cancel", true, d->toolWidget );
01940     d->formulaBarLayout->addWidget( d->cancelButton );
01941     d->okButton = d->newIconButton( "ok", true, d->toolWidget );
01942     d->formulaBarLayout->addWidget( d->okButton );
01943     d->formulaBarLayout->addSpacing( 6 );
01944 
01945     // The widget on which we display the sheet
01946     d->canvas = new Canvas( this );
01947 
01948     // The line-editor that appears above the sheet and allows to
01949     // edit the cells content. It knows about the two buttons.
01950     d->editWidget = new EditWidget( d->toolWidget, d->canvas, d->cancelButton, d->okButton );
01951     d->editWidget->setFocusPolicy( QWidget::StrongFocus );
01952     d->formulaBarLayout->addWidget( d->editWidget, 2 );
01953     d->formulaBarLayout->addSpacing( 2 );
01954 
01955     d->canvas->setEditWidget( d->editWidget );
01956 
01957     d->hBorderWidget = new HBorder( this, d->canvas,this );
01958     d->vBorderWidget = new VBorder( this, d->canvas ,this );
01959 
01960     d->canvas->setFocusPolicy( QWidget::StrongFocus );
01961     QWidget::setFocusPolicy( QWidget::StrongFocus );
01962     setFocusProxy( d->canvas );
01963 
01964     connect( this, SIGNAL( invalidated() ), d->canvas, SLOT( update() ) );
01965 
01966     QWidget* bottomPart = new QWidget( this );
01967     d->tabScrollBarLayout = new QHBoxLayout( bottomPart );
01968     d->tabScrollBarLayout->setAutoAdd( true );
01969     d->tabBar = new KoTabBar( bottomPart );
01970     d->horzScrollBar = new QScrollBar( bottomPart, "ScrollBar_1" );
01971 
01972     d->horzScrollBar->setRange( 0, 4096 );
01973     d->horzScrollBar->setOrientation( QScrollBar::Horizontal );
01974 
01975     d->horzScrollBar->setLineStep(60); //just random guess based on what feels okay
01976     d->horzScrollBar->setPageStep(60);
01977 
01978     QObject::connect( d->tabBar, SIGNAL( tabChanged( const QString& ) ), this, SLOT( changeSheet( const QString& ) ) );
01979     QObject::connect( d->tabBar, SIGNAL( tabMoved( unsigned, unsigned ) ),
01980       this, SLOT( moveSheet( unsigned, unsigned ) ) );
01981     QObject::connect( d->tabBar, SIGNAL( contextMenu( const QPoint& ) ),
01982       this, SLOT( popupTabBarMenu( const QPoint& ) ) );
01983     QObject::connect( d->tabBar, SIGNAL( doubleClicked() ),
01984       this, SLOT( slotRename() ) );
01985 
01986     d->viewLayout->setColStretch( 1, 10 );
01987     d->viewLayout->setRowStretch( 2, 10 );
01988     d->viewLayout->addMultiCellWidget( d->toolWidget, 0, 0, 0, 2 );
01989     d->viewLayout->addMultiCellWidget( d->hBorderWidget, 1, 1, 1, 2 );
01990     d->viewLayout->addWidget( d->vBorderWidget, 2, 0 );
01991     d->viewLayout->addWidget( d->canvas, 2, 1 );
01992     d->viewLayout->addWidget( d->vertScrollBar, 2, 2 );
01993     d->viewLayout->addMultiCellWidget( bottomPart, 3, 3, 0, 2 );
01994 
01995     KStatusBar * sb = statusBar();
01996     Q_ASSERT(sb);
01997     d->calcLabel = sb ? new KStatusBarLabel( QString::null, 0, sb ) : 0;
01998     addStatusBarItem( d->calcLabel, 0 );
01999     if (d->calcLabel)
02000         connect(d->calcLabel ,SIGNAL(itemPressed( int )),this,SLOT(statusBarClicked(int)));
02001 
02002     // signal slot
02003     QObject::connect( d->vertScrollBar, SIGNAL( valueChanged(int) ), d->canvas, SLOT( slotScrollVert(int) ) );
02004     QObject::connect( d->horzScrollBar, SIGNAL( valueChanged(int) ), d->canvas, SLOT( slotScrollHorz(int) ) );
02005 
02006 }
02007 
02008 Canvas* View::canvasWidget() const
02009 {
02010     return d->canvas;
02011 }
02012 
02013 HBorder* View::hBorderWidget()const
02014 {
02015     return d->hBorderWidget;
02016 }
02017 
02018 VBorder* View::vBorderWidget()const
02019 {
02020     return d->vBorderWidget;
02021 }
02022 
02023 QScrollBar* View::horzScrollBar()const
02024 {
02025     return d->horzScrollBar;
02026 }
02027 
02028 QScrollBar* View::vertScrollBar()const
02029 {
02030     return d->vertScrollBar;
02031 }
02032 
02033 EditWidget* View::editWidget()const
02034 {
02035     return d->editWidget;
02036 }
02037 
02038 ComboboxLocationEditWidget* View::posWidget()const
02039 {
02040     return d->posWidget;
02041 }
02042 
02043 KoTabBar* View::tabBar() const
02044 {
02045     return d->tabBar;
02046 }
02047 
02048 bool View::isLoading() const
02049 {
02050     return d->loading;
02051 }
02052 
02053 Selection* View::selectionInfo() const
02054 {
02055     return d->selection;
02056 }
02057 
02058 Selection* View::choice() const
02059 {
02060   return d->choice;
02061 }
02062 
02063 void View::resetInsertHandle()
02064 {
02065   d->actions->insertChartFrame->setChecked( false );
02066  // d->actions->insertPicture->setChecked( false );
02067 
02068   d->insertHandler = 0;
02069 }
02070 
02071 bool View::isInsertingObject()
02072 {
02073     return d->insertHandler;
02074 }
02075 
02076 const Sheet* View::activeSheet() const
02077 {
02078     return d->activeSheet;
02079 }
02080 
02081 Sheet* View::activeSheet()
02082 {
02083     return d->activeSheet;
02084 }
02085 
02086 void View::initConfig()
02087 {
02088     KConfig *config = Factory::global()->config();
02089     if ( config->hasGroup("Parameters" ))
02090     {
02091         config->setGroup( "Parameters" );
02092         if ( !doc()->configLoadFromFile() )
02093             doc()->setShowHorizontalScrollBar(config->readBoolEntry("Horiz ScrollBar",true));
02094         if ( !doc()->configLoadFromFile() )
02095             doc()->setShowVerticalScrollBar(config->readBoolEntry("Vert ScrollBar",true));
02096         doc()->setShowColHeader(config->readBoolEntry("Column Header",true));
02097         doc()->setShowRowHeader(config->readBoolEntry("Row Header",true));
02098         if ( !doc()->configLoadFromFile() )
02099             doc()->setCompletionMode((KGlobalSettings::Completion)config->readNumEntry("Completion Mode",(int)(KGlobalSettings::CompletionAuto)));
02100         doc()->setMoveToValue((KSpread::MoveTo)config->readNumEntry("Move",(int)(Bottom)));
02101         doc()->setIndentValue( config->readDoubleNumEntry( "Indent", 10.0 ) );
02102         doc()->setTypeOfCalc((MethodOfCalc)config->readNumEntry("Method of Calc",(int)(SumOfNumber)));
02103         if ( !doc()->configLoadFromFile() )
02104             doc()->setShowTabBar(config->readBoolEntry("Tabbar",true));
02105 
02106   doc()->setShowMessageError(config->readBoolEntry( "Msg error" ,false) );
02107 
02108   doc()->setShowFormulaBar(config->readBoolEntry("Formula bar",true));
02109         doc()->setShowStatusBar(config->readBoolEntry("Status bar",true));
02110 
02111         changeNbOfRecentFiles(config->readNumEntry("NbRecentFile",10));
02112         //autosave value is stored as a minute.
02113         //but default value is stored as seconde.
02114         doc()->setAutoSave(config->readNumEntry("AutoSave",KoDocument::defaultAutoSave()/60)*60);
02115         doc()->setBackupFile( config->readBoolEntry("BackupFile",true));
02116     }
02117 
02118    if (  config->hasGroup("KSpread Color" ) )
02119    {
02120      config->setGroup( "KSpread Color" );
02121      QColor _col(Qt::lightGray);
02122      _col = config->readColorEntry("GridColor", &_col);
02123      doc()->setGridColor(_col);
02124 
02125      QColor _pbCol(Qt::red);
02126      _pbCol = config->readColorEntry("PageBorderColor", &_pbCol);
02127      doc()->changePageBorderColor(_pbCol);
02128    }
02129 
02130 // Do we need a Page Layout in the congiguration file? Isn't this already in the template? Philipp
02131 /*
02132 if ( config->hasGroup("KSpread Page Layout" ) )
02133  {
02134    config->setGroup( "KSpread Page Layout" );
02135    if ( d->activeSheet->isEmpty())
02136      {
02137   d->activeSheet->setPaperFormat((KoFormat)config->readNumEntry("Default size page",1));
02138 
02139   d->activeSheet->setPaperOrientation((KoOrientation)config->readNumEntry("Default orientation page",0));
02140   d->activeSheet->setPaperUnit((KoUnit::Unit)config->readNumEntry("Default unit page",0));
02141      }
02142  }
02143 */
02144 
02145  initCalcMenu();
02146  calcStatusBarOp();
02147 }
02148 
02149 void View::changeNbOfRecentFiles(int _nb)
02150 {
02151     if (shell())
02152         shell()->setMaxRecentItems( _nb );
02153 }
02154 
02155 void View::initCalcMenu()
02156 {
02157     switch( doc()->getTypeOfCalc())
02158     {
02159         case  SumOfNumber:
02160             d->actions->calcSum->setChecked(true);
02161             break;
02162         case  Min:
02163             d->actions->calcMin->setChecked(true);
02164             break;
02165         case  Max:
02166             d->actions->calcMax->setChecked(true);
02167             break;
02168         case  Average:
02169             d->actions->calcAverage->setChecked(true);
02170             break;
02171         case  Count:
02172             d->actions->calcCount->setChecked(true);
02173             break;
02174         case  CountA:
02175             d->actions->calcCountA->setChecked(true);
02176             break;
02177         case  NoneCalc:
02178             d->actions->calcNone->setChecked(true);
02179             break;
02180         default :
02181             d->actions->calcSum->setChecked(true);
02182             break;
02183     }
02184 
02185 }
02186 
02187 
02188 void View::recalcWorkBook()
02189 {
02190   if (!activeSheet())
02191       return;
02192 
02193   Sheet * tbl;
02194   doc()->emitBeginOperation( true );
02195   for ( tbl = doc()->map()->firstSheet();
02196         tbl != 0L;
02197         tbl = doc()->map()->nextSheet() )
02198   {
02199    // bool b = tbl->getAutoCalc();
02200    // tbl->setAutoCalc( true );
02201     tbl->recalc( /*force recalculation = */ true);
02202    // tbl->setAutoCalc( b );
02203   }
02204 
02205   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
02206 }
02207 
02208 void View::refreshLocale()
02209 {
02210   doc()->emitBeginOperation(true);
02211   Sheet *tbl;
02212   for ( tbl = doc()->map()->firstSheet();
02213         tbl != 0L;
02214         tbl = doc()->map()->nextSheet() )
02215   {
02216     tbl->updateLocale();
02217   }
02218   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
02219 }
02220 
02221 void View::recalcWorkSheet()
02222 {
02223   if ( d->activeSheet != 0 )
02224   {
02225     doc()->emitBeginOperation( true );
02226 //    bool b = d->activeSheet->getAutoCalc();
02227 //    d->activeSheet->setAutoCalc( true );
02228     d->activeSheet->recalc( /*force recalculation = */ true);
02229  //   d->activeSheet->setAutoCalc( b );
02230     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
02231   }
02232 }
02233 
02234 
02235 void View::extraSpelling()
02236 {
02237   if ( d->spell.kspell )
02238     return; // Already in progress
02239 
02240   if (d->activeSheet == 0L)
02241     return;
02242 
02243   d->spell.macroCmdSpellCheck = 0L;
02244   d->spell.firstSpellSheet    = d->activeSheet;
02245   d->spell.currentSpellSheet  = d->spell.firstSpellSheet;
02246 
02247   QRect selection = d->selection->selection();
02248 
02249   // if nothing is selected, check every cell
02250   if (d->selection->isSingular())
02251   {
02252     d->spell.spellStartCellX = 0;
02253     d->spell.spellStartCellY = 0;
02254     d->spell.spellEndCellX   = 0;
02255     d->spell.spellEndCellY   = 0;
02256     d->spell.spellCheckSelection = false;
02257     d->spell.currentCell     = d->activeSheet->firstCell();
02258   }
02259   else
02260   {
02261     d->spell.spellStartCellX = selection.left();
02262     d->spell.spellStartCellY = selection.top();
02263     d->spell.spellEndCellX   = selection.right();
02264     d->spell.spellEndCellY   = selection.bottom();
02265     d->spell.spellCheckSelection = true;
02266     d->spell.currentCell     = 0L;
02267 
02268     // "-1" because X gets increased every time we go into spellCheckReady()
02269     d->spell.spellCurrCellX = d->spell.spellStartCellX - 1;
02270     d->spell.spellCurrCellY = d->spell.spellStartCellY;
02271   }
02272 
02273   startKSpell();
02274 }
02275 
02276 
02277 void View::startKSpell()
02278 {
02279     if ( doc()->getKSpellConfig() )
02280     {
02281         doc()->getKSpellConfig()->setIgnoreList( doc()->spellListIgnoreAll() );
02282         doc()->getKSpellConfig()->setReplaceAllList( d->spell.replaceAll );
02283 
02284     }
02285     d->spell.kspell = new KSpell( this, i18n( "Spell Checking" ), this,
02286                                        SLOT( spellCheckerReady() ),
02287                                        doc()->getKSpellConfig() );
02288 
02289   d->spell.kspell->setIgnoreUpperWords( doc()->dontCheckUpperWord() );
02290   d->spell.kspell->setIgnoreTitleCase( doc()->dontCheckTitleCase() );
02291 
02292   QObject::connect( d->spell.kspell, SIGNAL( death() ),
02293                     this, SLOT( spellCheckerFinished() ) );
02294   QObject::connect( d->spell.kspell, SIGNAL( misspelling( const QString &,
02295                                                          const QStringList &,
02296                                                          unsigned int) ),
02297                     this, SLOT( spellCheckerMisspelling( const QString &,
02298                                                          const QStringList &,
02299                                                          unsigned int) ) );
02300   QObject::connect( d->spell.kspell, SIGNAL( corrected( const QString &,
02301                                                        const QString &,
02302                                                        unsigned int) ),
02303                     this, SLOT( spellCheckerCorrected( const QString &,
02304                                                        const QString &,
02305                                                        unsigned int ) ) );
02306   QObject::connect( d->spell.kspell, SIGNAL( done( const QString & ) ),
02307                     this, SLOT( spellCheckerDone( const QString & ) ) );
02308   QObject::connect( d->spell.kspell, SIGNAL( ignoreall (const QString & ) ),
02309                     this, SLOT( spellCheckerIgnoreAll( const QString & ) ) );
02310 
02311   QObject::connect( d->spell.kspell, SIGNAL( replaceall( const QString &  ,  const QString & )), this, SLOT( spellCheckerReplaceAll( const QString &  ,  const QString & )));
02312 
02313 }
02314 
02315 void View::spellCheckerReplaceAll( const QString &orig, const QString & replacement)
02316 {
02317     d->spell.replaceAll.append( orig);
02318     d->spell.replaceAll.append( replacement);
02319 }
02320 
02321 
02322 void View::spellCheckerIgnoreAll( const QString & word)
02323 {
02324     doc()->addIgnoreWordAll( word );
02325 }
02326 
02327 
02328 void View::spellCheckerReady()
02329 {
02330   if (d->canvas)
02331     d->canvas->setCursor( WaitCursor );
02332 
02333   // go on to the next cell
02334   if (!d->spell.spellCheckSelection)
02335   {
02336     // if nothing is selected we have to check every cell
02337     // we use a different way to make it faster
02338     while ( d->spell.currentCell )
02339     {
02340       // check text only
02341       if ( d->spell.currentCell->value().isString() )
02342       {
02343         d->spell.kspell->check( d->spell.currentCell->text(), true );
02344 
02345         return;
02346       }
02347 
02348       d->spell.currentCell = d->spell.currentCell->nextCell();
02349       if ( d->spell.currentCell && d->spell.currentCell->isDefault() )
02350         kdDebug() << "checking default cell!!" << endl << endl;
02351     }
02352 
02353     if (spellSwitchToOtherSheet())
02354       spellCheckerReady();
02355     else
02356       spellCleanup();
02357 
02358     return;
02359   }
02360 
02361   // if something is selected:
02362 
02363   ++d->spell.spellCurrCellX;
02364   if (d->spell.spellCurrCellX > d->spell.spellEndCellX)
02365   {
02366     d->spell.spellCurrCellX = d->spell.spellStartCellX;
02367     ++d->spell.spellCurrCellY;
02368   }
02369 
02370   unsigned int y;
02371   unsigned int x;
02372 
02373   for ( y = d->spell.spellCurrCellY; y <= d->spell.spellEndCellY; ++y )
02374   {
02375     for ( x = d->spell.spellCurrCellX; x <= d->spell.spellEndCellX; ++x )
02376     {
02377       Cell * cell = d->spell.currentSpellSheet->cellAt( x, y );
02378 
02379       // check text only
02380       if (cell->isDefault() || !cell->value().isString())
02381         continue;
02382 
02383       d->spell.spellCurrCellX = x;
02384       d->spell.spellCurrCellY = y;
02385 
02386       d->spell.kspell->check( cell->text(), true );
02387 
02388       return;
02389     }
02390     d->spell.spellCurrCellX = d->spell.spellStartCellX;
02391   }
02392 
02393   // if the user selected something to be checked we are done
02394   // otherwise ask for checking the next sheet if any
02395   if (d->spell.spellCheckSelection)
02396   {
02397     // Done
02398     spellCleanup();
02399   }
02400   else
02401   {
02402     if (spellSwitchToOtherSheet())
02403       spellCheckerReady();
02404     else
02405       spellCleanup();
02406   }
02407 }
02408 
02409 
02410 void View::spellCleanup()
02411 {
02412   if ( d->canvas )
02413     d->canvas->setCursor( ArrowCursor );
02414 
02415   d->spell.kspell->cleanUp();
02416   delete d->spell.kspell;
02417   d->spell.kspell            = 0L;
02418   d->spell.firstSpellSheet   = 0L;
02419   d->spell.currentSpellSheet = 0L;
02420   d->spell.currentCell       = 0L;
02421   d->spell.replaceAll.clear();
02422 
02423 
02424   KMessageBox::information( this, i18n( "Spell checking is complete." ) );
02425 
02426   if ( d->spell.macroCmdSpellCheck )
02427     doc()->addCommand( d->spell.macroCmdSpellCheck );
02428   d->spell.macroCmdSpellCheck=0L;
02429 }
02430 
02431 
02432 bool View::spellSwitchToOtherSheet()
02433 {
02434   // there is no other sheet
02435   if ( doc()->map()->count() == 1 )
02436     return false;
02437 
02438   // for optimization
02439   QPtrList<Sheet> sheetList = doc()->map()->sheetList();
02440 
02441   unsigned int curIndex = sheetList.findRef(d->spell.currentSpellSheet);
02442   ++curIndex;
02443 
02444   // last sheet? then start at the beginning
02445   if ( curIndex >= sheetList.count() )
02446     d->spell.currentSpellSheet = sheetList.first();
02447   else
02448     d->spell.currentSpellSheet = sheetList.at(curIndex);
02449 
02450   // if the current sheet is the first one again, we are done.
02451   if ( d->spell.currentSpellSheet == d->spell.firstSpellSheet )
02452   {
02453     setActiveSheet( d->spell.firstSpellSheet );
02454     return false;
02455   }
02456 
02457   if (d->spell.spellCheckSelection)
02458   {
02459     d->spell.spellEndCellX = d->spell.currentSpellSheet->maxColumn();
02460     d->spell.spellEndCellY = d->spell.currentSpellSheet->maxRow();
02461 
02462     d->spell.spellCurrCellX = d->spell.spellStartCellX - 1;
02463     d->spell.spellCurrCellY = d->spell.spellStartCellY;
02464   }
02465   else
02466   {
02467     d->spell.currentCell = d->spell.currentSpellSheet->firstCell();
02468   }
02469 
02470   if ( KMessageBox::questionYesNo( this,
02471                                    i18n( "Do you want to check the spelling in the next sheet?") )
02472        != KMessageBox::Yes )
02473     return false;
02474 
02475   setActiveSheet( d->spell.currentSpellSheet );
02476 
02477   return true;
02478 }
02479 
02480 
02481 void View::spellCheckerMisspelling( const QString &,
02482                                            const QStringList &,
02483                                            unsigned int )
02484 {
02485   // scroll to the cell
02486   if ( !d->spell.spellCheckSelection )
02487   {
02488     d->spell.spellCurrCellX = d->spell.currentCell->column();
02489     d->spell.spellCurrCellY = d->spell.currentCell->row();
02490   }
02491 
02492   d->selection->initialize(QPoint(d->spell.spellCurrCellX, d->spell.spellCurrCellY));
02493 }
02494 
02495 
02496 void View::spellCheckerCorrected( const QString & old, const QString & corr,
02497                                          unsigned int pos )
02498 {
02499   Cell * cell;
02500 
02501   if (d->spell.spellCheckSelection)
02502   {
02503     cell = d->spell.currentSpellSheet->cellAt( d->spell.spellCurrCellX,
02504                                               d->spell.spellCurrCellY );
02505   }
02506   else
02507   {
02508     cell = d->spell.currentCell;
02509     d->spell.spellCurrCellX = cell->column();
02510     d->spell.spellCurrCellY = cell->row();
02511   }
02512 
02513   Q_ASSERT( cell );
02514   if ( !cell )
02515     return;
02516 
02517   doc()->emitBeginOperation(false);
02518   QString content( cell->text() );
02519 
02520   UndoSetText* undo = new UndoSetText( doc(), d->activeSheet,
02521                                                      content,
02522                                                      d->spell.spellCurrCellX,
02523                                                      d->spell.spellCurrCellY,
02524                                                      cell->formatType());
02525   content.replace( pos, old.length(), corr );
02526   cell->setCellText( content );
02527   d->editWidget->setText( content );
02528 
02529   if ( !d->spell.macroCmdSpellCheck )
02530       d->spell.macroCmdSpellCheck = new MacroUndoAction( doc(), i18n("Correct Misspelled Word") );
02531   d->spell.macroCmdSpellCheck->addCommand( undo );
02532   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
02533 }
02534 
02535 void View::spellCheckerDone( const QString & )
02536 {
02537     int result = d->spell.kspell->dlgResult();
02538 
02539     d->spell.kspell->cleanUp();
02540     delete d->spell.kspell;
02541     d->spell.kspell = 0L;
02542 
02543     if ( result != KS_CANCEL && result != KS_STOP )
02544     {
02545         if (d->spell.spellCheckSelection)
02546         {
02547             if ( (d->spell.spellCurrCellY <= d->spell.spellEndCellY)
02548                  && (d->spell.spellCurrCellX <= d->spell.spellEndCellX) )
02549             {
02550                 startKSpell();
02551                 return;
02552             }
02553         }
02554         else
02555         {
02556             if ( d->spell.currentCell )
02557             {
02558                 d->spell.currentCell = d->spell.currentCell->nextCell();
02559 
02560                 startKSpell();
02561 
02562                 return;
02563             }
02564         }
02565     }
02566     d->spell.replaceAll.clear();
02567 
02568     if ( d->spell.macroCmdSpellCheck )
02569     {
02570         doc()->addCommand( d->spell.macroCmdSpellCheck );
02571     }
02572     d->spell.macroCmdSpellCheck=0L;
02573 }
02574 
02575 void View::spellCheckerFinished()
02576 {
02577   if (d->canvas)
02578     d->canvas->setCursor( ArrowCursor );
02579 
02580   KSpell::spellStatus status = d->spell.kspell->status();
02581   d->spell.kspell->cleanUp();
02582   delete d->spell.kspell;
02583   d->spell.kspell = 0L;
02584   d->spell.replaceAll.clear();
02585 
02586   bool kspellNotConfigured=false;
02587 
02588   if (status == KSpell::Error)
02589   {
02590     KMessageBox::sorry(this, i18n("ISpell could not be started.\n"
02591                                   "Please make sure you have ISpell properly configured and in your PATH."));
02592     kspellNotConfigured=true;
02593   }
02594   else if (status == KSpell::Crashed)
02595   {
02596     KMessageBox::sorry(this, i18n("ISpell seems to have crashed."));
02597   }
02598 
02599   if (d->spell.macroCmdSpellCheck)
02600   {
02601       doc()->addCommand( d->spell.macroCmdSpellCheck );
02602   }
02603   d->spell.macroCmdSpellCheck=0L;
02604 
02605 
02606   if (kspellNotConfigured)
02607   {
02608     PreferenceDialog configDlg( this, 0 );
02609     configDlg.openPage( PreferenceDialog::KS_SPELLING);
02610     configDlg.exec();
02611   }
02612 }
02613 
02614 void View::initialPosition()
02615 {
02616     // Loading completed, pick initial worksheet
02617     QPtrListIterator<Sheet> it( doc()->map()->sheetList() );
02618     for( ; it.current(); ++it )
02619       addSheet( it.current() );
02620 
02621     Sheet * tbl = 0L;
02622     if ( doc()->isEmbedded() )
02623     {
02624         tbl = doc()->displaySheet();
02625     }
02626 
02627     if ( !tbl )
02628         tbl = doc()->map()->initialActiveSheet();
02629     if ( tbl )
02630       setActiveSheet( tbl );
02631     else
02632     {
02633       //activate first table which is not hiding
02634       tbl = doc()->map()->findSheet( doc()->map()->visibleSheets().first());
02635       if ( !tbl )
02636       {
02637         tbl = doc()->map()->firstSheet();
02638         if ( tbl )
02639         {
02640           tbl->setHidden( false );
02641           QString tabName = tbl->sheetName();
02642           d->tabBar->addTab( tabName );
02643         }
02644       }
02645       setActiveSheet( tbl );
02646     }
02647 
02648     refreshView();
02649 
02650     // Set the initial position for the marker as store in the XML file,
02651     // (1,1) otherwise
02652     int col = doc()->map()->initialMarkerColumn();
02653     if ( col <= 0 )
02654       col = 1;
02655     int row = doc()->map()->initialMarkerRow();
02656     if ( row <= 0 )
02657       row = 1;
02658     d->selection->initialize( QPoint(col, row) );
02659 
02660     // Set the initial X and Y offsets for the view.
02661     d->canvas->setXOffset( doc()->map()->initialXOffset() );
02662     d->canvas->setYOffset( doc()->map()->initialYOffset() );
02663 
02664     updateBorderButton();
02665     updateShowSheetMenu();
02666 
02667     d->actions->autoFormat->setEnabled(false);
02668     d->actions->sort->setEnabled(false);
02669     d->actions->mergeCell->setEnabled(false);
02670     d->actions->mergeCellHorizontal->setEnabled(false);
02671     d->actions->mergeCellVertical->setEnabled(false);
02672     d->actions->createStyle->setEnabled(false);
02673 
02674     d->actions->fillUp->setEnabled( false );
02675     d->actions->fillRight->setEnabled( false );
02676     d->actions->fillDown->setEnabled( false );
02677     d->actions->fillLeft->setEnabled( false );
02678 
02679     // make paint effective:
02680     doc()->decreaseNumOperation();
02681     d->actions->insertChartFrame->setEnabled(false);
02682 
02683     QRect vr( activeSheet()->visibleRect( d->canvas ) );
02684 
02685     doc()->emitBeginOperation( false );
02686     activeSheet()->setRegionPaintDirty( vr );
02687     doc()->emitEndOperation( vr );
02688 
02689     d->loading = true;
02690 
02691     if ( koDocument()->isReadWrite() )
02692       initConfig();
02693 
02694     d->adjustActions( !d->activeSheet->isProtected() );
02695     d->adjustWorkbookActions( !doc()->map()->isProtected() );
02696 }
02697 
02698 
02699 void View::updateEditWidgetOnPress()
02700 {
02701     if (!d->activeSheet)
02702         return;
02703 
02704     int column = d->canvas->markerColumn();
02705     int row    = d->canvas->markerRow();
02706 
02707     Cell* cell = d->activeSheet->cellAt( column, row );
02708     if ( !cell )
02709     {
02710         d->editWidget->setText( "" );
02711         return;
02712     }
02713     if ( d->activeSheet->isProtected() && cell->format()->isHideFormula( column, row ) )
02714         d->editWidget->setText( cell->strOutText() );
02715     else if ( d->activeSheet->isProtected() && cell->format()->isHideAll( column, row ) )
02716         d->editWidget->setText( "" );
02717     else
02718         d->editWidget->setText( cell->text() );
02719 
02720     d->updateButton(cell, column, row);
02721     d->adjustActions( d->activeSheet, cell );
02722 }
02723 
02724 void View::updateEditWidget()
02725 {
02726     if (!d->activeSheet)
02727         return;
02728 
02729     int column = d->canvas->markerColumn();
02730     int row    = d->canvas->markerRow();
02731 
02732     Cell * cell = d->activeSheet->cellAt( column, row );
02733     bool active = activeSheet()->getShowFormula()
02734         && !( d->activeSheet->isProtected() && cell && cell->format()->isHideFormula( column, row ) );
02735 
02736     if ( d->activeSheet && !d->activeSheet->isProtected() )
02737     {
02738       d->actions->alignLeft->setEnabled(!active);
02739       d->actions->alignCenter->setEnabled(!active);
02740       d->actions->alignRight->setEnabled(!active);
02741     }
02742 
02743     if ( !cell )
02744     {
02745         d->editWidget->setText( "" );
02746         if ( d->activeSheet->isProtected() )
02747           d->editWidget->setEnabled( false );
02748         else
02749           d->editWidget->setEnabled( true );
02750         return;
02751     }
02752 
02753     if ( d->activeSheet->isProtected() && cell->format()->isHideFormula( column, row ) )
02754         d->editWidget->setText( cell->strOutText() );
02755     else if ( d->activeSheet->isProtected() && cell->format()->isHideAll( column, row ) )
02756         d->editWidget->setText( "" );
02757     else
02758         d->editWidget->setText( cell->text() );
02759 
02760     if ( d->activeSheet->isProtected() && !cell->format()->notProtected( column, row ) )
02761       d->editWidget->setEnabled( false );
02762     else
02763       d->editWidget->setEnabled( true );
02764 
02765     if ( d->canvas->editor() )
02766     {
02767       d->canvas->editor()->setEditorFont(cell->format()->textFont(column, row), true);
02768       d->canvas->editor()->setFocus();
02769     }
02770     d->updateButton(cell, column, row);
02771     d->adjustActions( d->activeSheet, cell );
02772 }
02773 
02774 void View::activateFormulaEditor()
02775 {
02776 }
02777 
02778 void View::objectSelectedChanged()
02779 {
02780   if ( d->canvas->isObjectSelected() )
02781     d->actions->actionExtraProperties->setEnabled( true );
02782   else
02783     d->actions->actionExtraProperties->setEnabled( false );
02784 }
02785 
02786 void View::updateReadWrite( bool readwrite )
02787 {
02788     // d->cancelButton->setEnabled( readwrite );
02789     // d->okButton->setEnabled( readwrite );
02790   d->editWidget->setEnabled( readwrite );
02791 
02792   QValueList<KAction*> actions = actionCollection()->actions();
02793   QValueList<KAction*>::ConstIterator aIt = actions.begin();
02794   QValueList<KAction*>::ConstIterator aEnd = actions.end();
02795   for (; aIt != aEnd; ++aIt )
02796     (*aIt)->setEnabled( readwrite );
02797 
02798 //   d->actions->transform->setEnabled( false );
02799   if ( !doc() || !doc()->map() || doc()->map()->isProtected() )
02800   {
02801     d->actions->showSheet->setEnabled( false );
02802     d->actions->hideSheet->setEnabled( false );
02803   }
02804   else
02805   {
02806     d->actions->showSheet->setEnabled( true );
02807     d->actions->hideSheet->setEnabled( true );
02808   }
02809   d->actions->gotoCell->setEnabled( true );
02810   d->actions->viewZoom->setEnabled( true );
02811   d->actions->showPageBorders->setEnabled( true );
02812   d->actions->find->setEnabled( true);
02813   d->actions->replace->setEnabled( readwrite );
02814   if ( !doc()->isReadWrite())
02815       d->actions->copy->setEnabled( true );
02816   //  d->actions->newView->setEnabled( true );
02817   //doc()->KXMLGUIClient::action( "newView" )->setEnabled( true ); // obsolete (Werner)
02818 }
02819 
02820 void View::createTemplate()
02821 {
02822   int width = 60;
02823   int height = 60;
02824   QPixmap pix = doc()->generatePreview(QSize(width, height));
02825 
02826   KTempFile tempFile( QString::null, ".kst" );
02827   //Check that creation of temp file was successful
02828   if (tempFile.status() != 0)
02829   {
02830       qWarning("Creation of temprary file to store template failed.");
02831       return;
02832   }
02833 
02834   tempFile.setAutoDelete(true);
02835 
02836   doc()->saveNativeFormat( tempFile.name() );
02837 
02838   KoTemplateCreateDia::createTemplate( "kspread_template", Factory::global(),
02839                                            tempFile.name(), pix, this );
02840 
02841   Factory::global()->dirs()->addResourceType("kspread_template",
02842                                                        KStandardDirs::kde_default( "data" ) +
02843                                                        "kspread/templates/");
02844 }
02845 
02846 void View::sheetFormat()
02847 {
02848     FormatDialog dlg( this );
02849     dlg.exec();
02850 }
02851 
02852 void View::autoSum()
02853 {
02854     if (!activeSheet())
02855         return;
02856 
02857     // ######## Torben: Make sure that this can not be called
02858     // when canvas has a running editor
02859     if ( d->canvas->editor() )
02860         return;
02861 
02862   //Get the selected range and remove the current cell from it (as that is
02863   //where the result of the autosum will be stored - perhaps change
02864   //this behaviour??)
02865   Range rg;
02866   //rg.sheet=activeSheet();
02867   QRect sel = d->selection->selection(false);
02868 
02869   if (sel.height() > 1)
02870   {
02871     if (d->selection->marker().y()==sel.top())
02872       sel.setTop(sel.top()+1);
02873     if (d->selection->marker().y()==sel.bottom())
02874       sel.setBottom(sel.bottom()-1);
02875   }
02876   else
02877   {
02878     if (sel.width() > 1)
02879     {
02880       if (d->selection->marker().x()==sel.left())
02881         sel.setLeft(sel.left()+1);
02882 
02883       if (d->selection->marker().x()==sel.right())
02884         sel.setRight(sel.right()-1);
02885     }
02886     else
02887     {
02888       sel=QRect();
02889 
02890       // only 1 cell selected
02891       // try to automagically find cells the user wants to sum up
02892 
02893       int start = -1, end = -1;
02894 
02895       if ( (d->selection->marker().y() > 1) && activeSheet()->cellAt(d->selection->marker().x(), d->selection->marker().y()-1)->value().isNumber() )
02896       {
02897         // check cells above the current one
02898         start = end = d->selection->marker().y()-1;
02899         for (start--; (start > 0) && activeSheet()->cellAt(d->selection->marker().x(), start)->value().isNumber(); start--) ;
02900 
02901         Point startPoint, endPoint;
02902         startPoint.setRow(start+1);
02903         startPoint.setColumn(d->selection->marker().x());
02904         endPoint.setRow(end);
02905         endPoint.setColumn(d->selection->marker().x());
02906 
02907         QString str = Range(startPoint, endPoint).toString();
02908 
02909         d->canvas->createEditor( Canvas::CellEditor , true , true );
02910         d->canvas->editor()->setText("=SUM(" + str + ")");
02911         d->canvas->editor()->setCursorPosition(5 + str.length());
02912         return;
02913       }
02914       else if ( (d->selection->marker().x() > 1) && activeSheet()->cellAt(d->selection->marker().x()-1, d->selection->marker().y())->value().isNumber() )
02915       {
02916         // check cells to the left of the current one
02917         start = end = d->selection->marker().x()-1;
02918         for (start--; (start > 0) && activeSheet()->cellAt(start, d->selection->marker().y())->value().isNumber(); start--) ;
02919 
02920         Point startPoint, endPoint;
02921         startPoint.setColumn(start+1);
02922         startPoint.setRow(d->selection->marker().y());
02923         endPoint.setColumn(end);
02924         endPoint.setRow(d->selection->marker().y());
02925 
02926         QString str = Range(startPoint, endPoint).toString();
02927 
02928         d->canvas->createEditor( Canvas::CellEditor , true , true );
02929         d->canvas->editor()->setText("=SUM(" + str + ")");
02930         d->canvas->editor()->setCursorPosition(5 + str.length());
02931         return;
02932       }
02933     }
02934   }
02935 
02936   if ( (sel.width() > 1) && (sel.height() > 1) )
02937     sel=QRect();
02938 
02939   rg.setRange(sel);
02940 
02941   d->canvas->createEditor( Canvas::CellEditor , true , true );
02942 
02943 
02944   if ( (rg.range().isValid() ) && (!rg.range().isEmpty()) )
02945   {
02946     d->canvas->editor()->setText( "=SUM("+rg.toString()+")" );
02947     d->canvas->deleteEditor(true);
02948   }
02949   else
02950   {
02951     d->canvas->editor()->setText( "=SUM()" );
02952     d->canvas->editor()->setCursorPosition( 5 );
02953   }
02954 }
02955 
02956 /*
02957 void View::oszilloscope()
02958 {
02959     QDialog* dlg = new OsziDlg( this );
02960     dlg->show();
02961 }
02962 */
02963 
02964 void View::changeTextColor()
02965 {
02966   if ( d->activeSheet != 0L )
02967   {
02968     doc()->emitBeginOperation(false);
02969     d->activeSheet->setSelectionTextColor( selectionInfo(), d->actions->textColor->color() );
02970     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
02971   }
02972 }
02973 
02974 void View::setSelectionTextColor(const QColor &txtColor)
02975 {
02976   if (d->activeSheet != 0L)
02977   {
02978     doc()->emitBeginOperation(false);
02979     d->activeSheet->setSelectionTextColor( selectionInfo(), txtColor );
02980 
02981     markSelectionAsDirty();
02982     doc()->emitEndOperation();
02983   }
02984 }
02985 
02986 void View::changeBackgroundColor()
02987 {
02988   if ( d->activeSheet != 0L )
02989   {
02990     doc()->emitBeginOperation(false);
02991     d->activeSheet->setSelectionbgColor( selectionInfo(), d->actions->bgColor->color() );
02992     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
02993   }
02994 }
02995 
02996 void View::setSelectionBackgroundColor(const QColor &bgColor)
02997 {
02998   if (d->activeSheet != 0L)
02999   {
03000     doc()->emitBeginOperation(false);
03001     d->activeSheet->setSelectionbgColor( selectionInfo(), bgColor );
03002     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
03003   }
03004 }
03005 
03006 void View::changeBorderColor()
03007 {
03008   if ( d->activeSheet != 0L )
03009   {
03010     doc()->emitBeginOperation(false);
03011     d->activeSheet->setSelectionBorderColor( selectionInfo(), d->actions->borderColor->color() );
03012     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
03013   }
03014 }
03015 
03016 void View::setSelectionBorderColor(const QColor &bdColor)
03017 {
03018   if (d->activeSheet != 0L)
03019   {
03020     doc()->emitBeginOperation(false);
03021     d->activeSheet->setSelectionBorderColor( selectionInfo(), bdColor );
03022     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
03023   }
03024 }
03025 
03026 void View::helpUsing()
03027 {
03028   kapp->invokeHelp( );
03029 }
03030 
03031 void View::enableUndo( bool _b )
03032 {
03033   KAction* action = actionCollection()->action( "office_undo" );
03034   if( action ) action->setEnabled( _b );
03035 }
03036 
03037 void View::enableRedo( bool _b )
03038 {
03039   KAction* action = actionCollection()->action( "office_redo" );
03040   if( action ) action->setEnabled( _b );
03041 }
03042 
03043 void View::enableInsertColumn( bool _b )
03044 {
03045   if ( d->activeSheet && !d->activeSheet->isProtected() )
03046     d->actions->insertColumn->setEnabled( _b );
03047 }
03048 
03049 void View::enableInsertRow( bool _b )
03050 {
03051   if ( d->activeSheet && !d->activeSheet->isProtected() )
03052     d->actions->insertRow->setEnabled( _b );
03053 }
03054 
03055 void View::deleteColumn()
03056 {
03057   if ( !d->activeSheet )
03058     return;
03059 
03060   doc()->emitBeginOperation( false );
03061 
03062   QRect r( d->selection->selection() );
03063 
03064   d->activeSheet->removeColumn( r.left(), ( r.right()-r.left() ) );
03065 
03066   updateEditWidget();
03067   // Stefan: update the selection after deleting (a) column(s)
03068   d->selection->update();
03069 
03070   QRect vr( d->activeSheet->visibleRect( d->canvas ) );
03071   vr.setLeft( r.left() );
03072 
03073   doc()->emitEndOperation( vr );
03074 }
03075 
03076 void View::deleteRow()
03077 {
03078   if ( !d->activeSheet )
03079     return;
03080 
03081   doc()->emitBeginOperation( false );
03082   QRect r( d->selection->selection() );
03083   d->activeSheet->removeRow( r.top(),(r.bottom()-r.top()) );
03084 
03085   updateEditWidget();
03086   // Stefan: update the selection after deleting (a) column(s)
03087   d->selection->update();
03088 
03089   QRect vr( d->activeSheet->visibleRect( d->canvas ) );
03090   vr.setTop( r.top() );
03091 
03092   doc()->emitEndOperation( vr );
03093 }
03094 
03095 void View::insertColumn()
03096 {
03097   if ( !d->activeSheet )
03098     return;
03099 
03100   doc()->emitBeginOperation( false );
03101   QRect r( d->selection->selection() );
03102   d->activeSheet->insertColumn( r.left(), ( r.right()-r.left() ) );
03103 
03104   updateEditWidget();
03105 
03106   QRect vr( d->activeSheet->visibleRect( d->canvas ) );
03107   vr.setLeft( r.left() - 1 );
03108 
03109   doc()->emitEndOperation( vr );
03110 }
03111 
03112 void View::hideColumn()
03113 {
03114   if ( !d->activeSheet )
03115     return;
03116 
03117   if ( d->selection->isRowSelected() )
03118   {
03119     KMessageBox::error( this, i18n( "Area is too large." ) );
03120     return;
03121   }
03122 
03123   d->activeSheet->hideColumn(*selectionInfo());
03124 }
03125 
03126 void View::showColumn()
03127 {
03128   if ( !d->activeSheet )
03129     return;
03130 
03131   ShowColRow dlg( this, "showCol", ShowColRow::Column );
03132   dlg.exec();
03133 }
03134 
03135 void View::showSelColumns()
03136 {
03137   if ( !d->activeSheet )
03138     return;
03139 
03140   d->activeSheet->showColumn(*selectionInfo());
03141 }
03142 
03143 void View::insertRow()
03144 {
03145   if ( !d->activeSheet )
03146     return;
03147   doc()->emitBeginOperation( false );
03148   QRect r( d->selection->selection() );
03149   d->activeSheet->insertRow( r.top(), ( r.bottom() - r.top() ) );
03150 
03151   updateEditWidget();
03152   QRect vr( d->activeSheet->visibleRect( d->canvas ) );
03153   vr.setTop( r.top() - 1 );
03154 
03155   doc()->emitEndOperation( vr );
03156 }
03157 
03158 void View::hideRow()
03159 {
03160   if ( !d->activeSheet )
03161     return;
03162 
03163   if ( d->selection->isColumnSelected() )
03164   {
03165     KMessageBox::error( this, i18n( "Area is too large." ) );
03166     return;
03167   }
03168 
03169   d->activeSheet->hideRow(*selectionInfo());
03170 }
03171 
03172 void View::showRow()
03173 {
03174   if ( !d->activeSheet )
03175     return;
03176 
03177   ShowColRow dlg( this, "showRow", ShowColRow::Row );
03178   dlg.exec();
03179 }
03180 
03181 void View::showSelRows()
03182 {
03183   if ( !d->activeSheet )
03184     return;
03185 
03186   d->activeSheet->showRow(*selectionInfo());
03187 }
03188 
03189 void View::fontSelected( const QString & _font )
03190 {
03191   if ( d->toolbarLock )
03192     return;
03193 
03194   doc()->emitBeginOperation(false);
03195   if ( d->activeSheet != 0L )
03196     d->activeSheet->setSelectionFont( d->selection, _font.latin1() );
03197 
03198   // Dont leave the focus in the toolbars combo box ...
03199   if ( d->canvas->editor() )
03200   {
03201     Cell * cell = d->activeSheet->cellAt( d->selection->marker() );
03202     d->canvas->editor()->setEditorFont( cell->format()->textFont( cell->column(), cell->row() ), true );
03203     d->canvas->editor()->setFocus();
03204   }
03205   else
03206     d->canvas->setFocus();
03207 
03208   markSelectionAsDirty();
03209   doc()->emitEndOperation();
03210 }
03211 
03212 void View::decreaseFontSize()
03213 {
03214   setSelectionFontSize( -1 );
03215 }
03216 
03217 void View::increaseFontSize()
03218 {
03219   setSelectionFontSize( 1 );
03220 }
03221 
03222 void View::setSelectionFontSize( int size )
03223 {
03224   if ( d->activeSheet != NULL )
03225   {
03226     d->activeSheet->setSelectionSize( selectionInfo(), size );
03227   }
03228 }
03229 
03230 void View::lower()
03231 {
03232   if ( !d->activeSheet  )
03233     return;
03234 
03235   doc()->emitBeginOperation( false );
03236 
03237   d->activeSheet->setSelectionUpperLower( selectionInfo(), -1 );
03238   updateEditWidget();
03239 
03240   markSelectionAsDirty();
03241   doc()->emitEndOperation();
03242 }
03243 
03244 void View::upper()
03245 {
03246   if ( !d->activeSheet  )
03247     return;
03248 
03249   doc()->emitBeginOperation( false );
03250 
03251   d->activeSheet->setSelectionUpperLower( selectionInfo(), 1 );
03252   updateEditWidget();
03253 
03254   markSelectionAsDirty();
03255   doc()->emitEndOperation();
03256 }
03257 
03258 void View::firstLetterUpper()
03259 {
03260   if ( !d->activeSheet  )
03261     return;
03262   doc()->emitBeginOperation( false );
03263   d->activeSheet->setSelectionfirstLetterUpper( selectionInfo() );
03264   updateEditWidget();
03265 
03266   markSelectionAsDirty();
03267   doc()->emitEndOperation();
03268 }
03269 
03270 void View::verticalText(bool b)
03271 {
03272   if ( !d->activeSheet  )
03273     return;
03274 
03275   doc()->emitBeginOperation( false );
03276   d->activeSheet->setSelectionVerticalText( selectionInfo(), b );
03277   d->activeSheet->adjustArea(*selectionInfo());
03278   updateEditWidget(); // TODO Stefan: nescessary?
03279 
03280   markSelectionAsDirty();
03281   doc()->emitEndOperation();
03282 }
03283 
03284 void View::insertSpecialChar()
03285 {
03286   QString f( d->actions->selectFont->font() );
03287   QChar c = ' ';
03288 
03289   if ( d->specialCharDlg == 0 )
03290   {
03291     d->specialCharDlg = new KoCharSelectDia( this, "insert special char", f, c, false );
03292     connect( d->specialCharDlg, SIGNAL( insertChar( QChar, const QString & ) ),
03293              this, SLOT( slotSpecialChar( QChar, const QString & ) ) );
03294     connect( d->specialCharDlg, SIGNAL( finished() ),
03295              this, SLOT( slotSpecialCharDlgClosed() ) );
03296   }
03297   d->specialCharDlg->show();
03298 }
03299 
03300 void View::slotSpecialCharDlgClosed()
03301 {
03302   if ( d->specialCharDlg )
03303   {
03304     disconnect( d->specialCharDlg, SIGNAL(insertChar(QChar,const QString &)),
03305                 this, SLOT(slotSpecialChar(QChar,const QString &)));
03306     disconnect( d->specialCharDlg, SIGNAL( finished() ),
03307                 this, SLOT( slotSpecialCharDlgClosed() ) );
03308     d->specialCharDlg->deleteLater();
03309     d->specialCharDlg = 0L;
03310   }
03311 }
03312 
03313 void View::slotSpecialChar( QChar c, const QString & _font )
03314 {
03315   if ( d->activeSheet )
03316   {
03317     QPoint marker( d->selection->marker() );
03318     Cell * cell = d->activeSheet->nonDefaultCell( marker );
03319     if ( cell->format()->textFont( marker.x(), marker.y() ).family() != _font )
03320     {
03321       cell->format()->setTextFontFamily( _font );
03322     }
03323     EditWidget * edit = d->editWidget;
03324     QKeyEvent ev( QEvent::KeyPress, 0, 0, 0, QString( c ) );
03325     QApplication::sendEvent( edit, &ev );
03326   }
03327 }
03328 
03329 void View::insertMathExpr()
03330 {
03331   if ( d->activeSheet == 0L )
03332     return;
03333 
03334   FormulaDialog * dlg = new FormulaDialog( this, "Function" );
03335   dlg->show();
03336 
03337   /* TODO - because I search on 'TODO's :-) */
03338   // #### Is the dialog deleted when it's closed ? (David)
03339   // Torben thinks that not.
03340 }
03341 
03342 void View::formulaSelection( const QString &_math )
03343 {
03344   if ( d->activeSheet == 0 )
03345     return;
03346 
03347   if ( _math == i18n("Others...") )
03348   {
03349     insertMathExpr();
03350     return;
03351   }
03352 
03353   FormulaDialog *dlg = new FormulaDialog( this, "Formula Editor", _math );
03354   dlg->exec();
03355 }
03356 
03357 void View::fontSizeSelected( int _size )
03358 {
03359   if ( d->toolbarLock )
03360     return;
03361 
03362   doc()->emitBeginOperation( false );
03363 
03364   if ( d->activeSheet != 0L )
03365     d->activeSheet->setSelectionFont( selectionInfo(), 0L, _size );
03366 
03367   // Dont leave the focus in the toolbars combo box ...
03368   if ( d->canvas->editor() )
03369   {
03370     Cell * cell = d->activeSheet->cellAt( d->selection->marker() );
03371     d->canvas->editor()->setEditorFont( cell->format()->textFont( d->canvas->markerColumn(),
03372                                                                   d->canvas->markerRow() ), true );
03373     d->canvas->editor()->setFocus();
03374   }
03375   else
03376     d->canvas->setFocus();
03377 
03378   markSelectionAsDirty();
03379   doc()->emitEndOperation();
03380 }
03381 
03382 void View::bold( bool b )
03383 {
03384   if ( d->toolbarLock )
03385     return;
03386   if ( d->activeSheet == 0 )
03387     return;
03388 
03389   doc()->emitBeginOperation( false );
03390 
03391   int col = d->canvas->markerColumn();
03392   int row = d->canvas->markerRow();
03393   d->activeSheet->setSelectionFont( selectionInfo(), 0L, -1, b );
03394 
03395   if ( d->canvas->editor() )
03396   {
03397     Cell * cell = d->activeSheet->cellAt( col, row );
03398     d->canvas->editor()->setEditorFont( cell->format()->textFont( col, row ), true );
03399   }
03400 
03401   markSelectionAsDirty();
03402   doc()->emitEndOperation();
03403 }
03404 
03405 void View::underline( bool b )
03406 {
03407   if ( d->toolbarLock )
03408     return;
03409   if ( d->activeSheet == 0 )
03410     return;
03411 
03412   doc()->emitBeginOperation( false );
03413 
03414   int col = d->canvas->markerColumn();
03415   int row = d->canvas->markerRow();
03416 
03417   d->activeSheet->setSelectionFont( selectionInfo(), 0L, -1, -1, -1 ,b );
03418   if ( d->canvas->editor() )
03419   {
03420     Cell * cell = d->activeSheet->cellAt( col, row );
03421     d->canvas->editor()->setEditorFont( cell->format()->textFont( col, row ), true );
03422   }
03423 
03424   markSelectionAsDirty();
03425   doc()->emitEndOperation();
03426 }
03427 
03428 void View::strikeOut( bool b )
03429 {
03430   if ( d->toolbarLock )
03431     return;
03432   if ( d->activeSheet == 0 )
03433     return;
03434 
03435   doc()->emitBeginOperation( false );
03436 
03437   int col = d->canvas->markerColumn();
03438   int row = d->canvas->markerRow();
03439 
03440   d->activeSheet->setSelectionFont( selectionInfo(), 0L, -1, -1, -1 ,-1, b );
03441   if ( d->canvas->editor() )
03442   {
03443     Cell * cell = d->activeSheet->cellAt( col, row );
03444     d->canvas->editor()->setEditorFont( cell->format()->textFont( col, row ), true );
03445   }
03446 
03447   markSelectionAsDirty();
03448   doc()->emitEndOperation();
03449 }
03450 
03451 
03452 void View::italic( bool b )
03453 {
03454   if ( d->toolbarLock )
03455     return;
03456   if ( d->activeSheet == 0 )
03457     return;
03458 
03459   doc()->emitBeginOperation( false );
03460 
03461   int col = d->canvas->markerColumn();
03462   int row = d->canvas->markerRow();
03463 
03464   d->activeSheet->setSelectionFont( selectionInfo(), 0L, -1, -1, b );
03465   if ( d->canvas->editor() )
03466   {
03467     Cell * cell = d->activeSheet->cellAt( col, row );
03468     d->canvas->editor()->setEditorFont( cell->format()->textFont( col, row ), true );
03469   }
03470 
03471   markSelectionAsDirty();
03472   doc()->emitEndOperation();
03473 }
03474 
03475 void View::sortInc()
03476 {
03477   if (!activeSheet())
03478       return;
03479 
03480   QRect range = d->selection->selection();
03481   if ( d->selection->isSingular() )
03482   {
03483     KMessageBox::error( this, i18n( "You must select multiple cells." ) );
03484     return;
03485   }
03486 
03487   doc()->emitBeginOperation( false );
03488 
03489   // Entire row(s) selected ? Or just one row ?
03490   if ( d->selection->isRowSelected() || range.top() == range.bottom() )
03491     activeSheet()->sortByRow( range, range.top(), Sheet::Increase );
03492   else
03493     activeSheet()->sortByColumn( range, range.left(), Sheet::Increase );
03494   updateEditWidget();
03495 
03496   markSelectionAsDirty();
03497   doc()->emitEndOperation();
03498 }
03499 
03500 void View::sortDec()
03501 {
03502   QRect range = d->selection->selection();
03503   if ( d->selection->isSingular() )
03504   {
03505     KMessageBox::error( this, i18n( "You must select multiple cells." ) );
03506     return;
03507   }
03508 
03509   doc()->emitBeginOperation( false );
03510 
03511     // Entire row(s) selected ? Or just one row ?
03512   if ( d->selection->isRowSelected() || range.top() == range.bottom() )
03513     activeSheet()->sortByRow( range, range.top(), Sheet::Decrease );
03514   else
03515     activeSheet()->sortByColumn( range, range.left(), Sheet::Decrease );
03516   updateEditWidget();
03517 
03518   markSelectionAsDirty();
03519   doc()->emitEndOperation();
03520 }
03521 
03522 
03523 void View::borderBottom()
03524 {
03525   if ( d->activeSheet != 0L )
03526   {
03527     doc()->emitBeginOperation( false );
03528 
03529     d->activeSheet->borderBottom( d->selection, d->actions->borderColor->color() );
03530 
03531     markSelectionAsDirty();
03532     doc()->emitEndOperation();
03533   }
03534 }
03535 
03536 void View::setSelectionBottomBorderColor( const QColor & color )
03537 {
03538   if ( d->activeSheet != 0L )
03539   {
03540     doc()->emitBeginOperation( false );
03541     d->activeSheet->borderBottom( selectionInfo(), color );
03542 
03543     markSelectionAsDirty();
03544     doc()->emitEndOperation();
03545   }
03546 }
03547 
03548 void View::borderRight()
03549 {
03550   if ( d->activeSheet != 0L )
03551   {
03552     doc()->emitBeginOperation( false );
03553     if ( d->activeSheet->layoutDirection()==Sheet::RightToLeft )
03554       d->activeSheet->borderLeft( d->selection, d->actions->borderColor->color() );
03555     else
03556       d->activeSheet->borderRight( d->selection, d->actions->borderColor->color() );
03557 
03558     markSelectionAsDirty();
03559     doc()->emitEndOperation();
03560   }
03561 }
03562 
03563 void View::setSelectionRightBorderColor( const QColor & color )
03564 {
03565   if ( d->activeSheet != 0L )
03566   {
03567     doc()->emitBeginOperation( false );
03568     if ( d->activeSheet->layoutDirection()==Sheet::RightToLeft )
03569       d->activeSheet->borderLeft( selectionInfo(), color );
03570     else
03571       d->activeSheet->borderRight( selectionInfo(), color );
03572 
03573     markSelectionAsDirty();
03574     doc()->emitEndOperation();
03575   }
03576 }
03577 
03578 void View::borderLeft()
03579 {
03580   if ( d->activeSheet != 0L )
03581   {
03582     doc()->emitBeginOperation( false );
03583     if ( d->activeSheet->layoutDirection()==Sheet::RightToLeft )
03584       d->activeSheet->borderRight( d->selection, d->actions->borderColor->color() );
03585     else
03586       d->activeSheet->borderLeft( d->selection, d->actions->borderColor->color() );
03587 
03588     markSelectionAsDirty();
03589     doc()->emitEndOperation();
03590   }
03591 }
03592 
03593 void View::setSelectionLeftBorderColor( const QColor & color )
03594 {
03595   if ( d->activeSheet != 0L )
03596   {
03597     doc()->emitBeginOperation( false );
03598     if ( d->activeSheet->layoutDirection()==Sheet::RightToLeft )
03599       d->activeSheet->borderRight( selectionInfo(), color );
03600     else
03601       d->activeSheet->borderLeft( selectionInfo(), color );
03602 
03603     markSelectionAsDirty();
03604     doc()->emitEndOperation();
03605   }
03606 }
03607 
03608 void View::borderTop()
03609 {
03610   if ( d->activeSheet != 0L )
03611   {
03612     doc()->emitBeginOperation( false );
03613     d->activeSheet->borderTop( d->selection, d->actions->borderColor->color() );
03614 
03615     markSelectionAsDirty();
03616     doc()->emitEndOperation();
03617   }
03618 }
03619 
03620 void View::setSelectionTopBorderColor( const QColor & color )
03621 {
03622   if ( d->activeSheet != 0L )
03623   {
03624     doc()->emitBeginOperation( false );
03625     d->activeSheet->borderTop( selectionInfo(), color );
03626 
03627     markSelectionAsDirty();
03628     doc()->emitEndOperation();
03629   }
03630 }
03631 
03632 void View::borderOutline()
03633 {
03634   if ( d->activeSheet != 0L )
03635   {
03636     doc()->emitBeginOperation( false );
03637     d->activeSheet->borderOutline( d->selection, d->actions->borderColor->color() );
03638 
03639     markSelectionAsDirty();
03640     doc()->emitEndOperation();
03641   }
03642 }
03643 
03644 void View::setSelectionOutlineBorderColor( const QColor & color )
03645 {
03646   if ( d->activeSheet != 0L )
03647   {
03648     doc()->emitBeginOperation( false );
03649     d->activeSheet->borderOutline( selectionInfo(), color );
03650 
03651     markSelectionAsDirty();
03652     doc()->emitEndOperation();
03653   }
03654 }
03655 
03656 void View::borderAll()
03657 {
03658   if ( d->activeSheet != 0L )
03659   {
03660     doc()->emitBeginOperation( false );
03661     d->activeSheet->borderAll( d->selection, d->actions->borderColor->color() );
03662 
03663     markSelectionAsDirty();
03664     doc()->emitEndOperation();
03665   }
03666 }
03667 
03668 void View::setSelectionAllBorderColor( const QColor & color )
03669 {
03670   if ( d->activeSheet != 0L )
03671   {
03672     doc()->emitBeginOperation( false );
03673     d->activeSheet->borderAll( selectionInfo(), color );
03674 
03675     markSelectionAsDirty();
03676     doc()->emitEndOperation();
03677   }
03678 }
03679 
03680 void View::borderRemove()
03681 {
03682   if ( d->activeSheet != 0L )
03683   {
03684     doc()->emitBeginOperation(false);
03685     d->activeSheet->borderRemove( d->selection );
03686 
03687     markSelectionAsDirty();
03688     doc()->emitEndOperation();
03689   }
03690 }
03691 
03692 void View::addSheet( Sheet * _t )
03693 {
03694   doc()->emitBeginOperation( false );
03695 
03696   insertSheet( _t );
03697 
03698   // Connect some signals
03699   QObject::connect( _t, SIGNAL( sig_refreshView() ), SLOT( slotRefreshView() ) );
03700   QObject::connect( _t, SIGNAL( sig_updateView( Sheet* ) ), SLOT( slotUpdateView( Sheet* ) ) );
03701   QObject::connect( _t->print(), SIGNAL( sig_updateView( Sheet* ) ), SLOT( slotUpdateView( Sheet* ) ) );
03702   QObject::connect( _t, SIGNAL( sig_updateView( Sheet *, const Region& ) ),
03703                     SLOT( slotUpdateView( Sheet*, const Region& ) ) );
03704   QObject::connect( _t, SIGNAL( sig_updateView( EmbeddedObject* )), SLOT( slotUpdateView( EmbeddedObject* ) ) );
03705 
03706   QObject::connect( _t, SIGNAL( sig_updateHBorder( Sheet * ) ),
03707                     SLOT( slotUpdateHBorder( Sheet * ) ) );
03708   QObject::connect( _t, SIGNAL( sig_updateVBorder( Sheet * ) ),
03709                     SLOT( slotUpdateVBorder( Sheet * ) ) );
03710   QObject::connect( _t, SIGNAL( sig_nameChanged( Sheet*, const QString& ) ),
03711                     this, SLOT( slotSheetRenamed( Sheet*, const QString& ) ) );
03712   QObject::connect( _t, SIGNAL( sig_SheetHidden( Sheet* ) ),
03713                     this, SLOT( slotSheetHidden( Sheet* ) ) );
03714   QObject::connect( _t, SIGNAL( sig_SheetShown( Sheet* ) ),
03715                     this, SLOT( slotSheetShown( Sheet* ) ) );
03716   QObject::connect( _t, SIGNAL( sig_SheetRemoved( Sheet* ) ),
03717                     this, SLOT( slotSheetRemoved( Sheet* ) ) );
03718   // ########### Why do these signals not send a pointer to the sheet?
03719   // This will lead to bugs.
03720   QObject::connect( _t, SIGNAL( sig_updateChildGeometry( EmbeddedKOfficeObject* ) ),
03721                     SLOT( slotUpdateChildGeometry( EmbeddedKOfficeObject* ) ) );
03722   QObject::connect( _t, SIGNAL( sig_maxColumn( int ) ), d->canvas, SLOT( slotMaxColumn( int ) ) );
03723   QObject::connect( _t, SIGNAL( sig_maxRow( int ) ), d->canvas, SLOT( slotMaxRow( int ) ) );
03724 
03725   if ( !d->loading )
03726     updateBorderButton();
03727 
03728   if ( !d->activeSheet )
03729   {
03730     doc()->emitEndOperation();
03731     return;
03732   }
03733   doc()->emitEndOperation( *selectionInfo() );
03734 }
03735 
03736 void View::slotSheetRemoved( Sheet *_t )
03737 {
03738   doc()->emitBeginOperation( false );
03739 
03740   QString m_sheetName=_t->sheetName();
03741   d->tabBar->removeTab( _t->sheetName() );
03742   if (doc()->map()->findSheet( doc()->map()->visibleSheets().first()))
03743     setActiveSheet( doc()->map()->findSheet( doc()->map()->visibleSheets().first() ));
03744   else
03745     d->activeSheet = 0L;
03746 
03747   QValueList<Reference>::Iterator it;
03748   QValueList<Reference> area=doc()->listArea();
03749   for ( it = area.begin(); it != area.end(); ++it )
03750   {
03751     //remove Area Name when sheet target is removed
03752     if ( (*it).sheet_name == m_sheetName )
03753     {
03754       doc()->removeArea( (*it).ref_name );
03755       //now area name is used in formula
03756       //so you must recalc sheets when remove areaname
03757       Sheet * tbl;
03758 
03759       for ( tbl = doc()->map()->firstSheet(); tbl != 0L; tbl = doc()->map()->nextSheet() )
03760       {
03761         tbl->refreshRemoveAreaName((*it).ref_name);
03762       }
03763     }
03764   }
03765 
03766   doc()->emitEndOperation( *selectionInfo() );
03767 }
03768 
03769 void View::removeAllSheets()
03770 {
03771   doc()->emitBeginOperation(false);
03772   d->tabBar->clear();
03773 
03774   setActiveSheet( 0L );
03775 
03776   doc()->emitEndOperation();
03777 }
03778 
03779 void View::setActiveSheet( Sheet * _t, bool updateSheet )
03780 {
03781   if ( _t == d->activeSheet )
03782     return;
03783 
03784   doc()->emitBeginOperation(false);
03785 
03786   saveCurrentSheetSelection();
03787 
03788   Sheet * oldSheet = d->activeSheet;
03789 
03790   d->activeSheet = _t;
03791 
03792   if ( d->activeSheet == 0L )
03793   {
03794     doc()->emitEndOperation();
03795     return;
03796   }
03797 
03798   if ( oldSheet && oldSheet->layoutDirection()==Sheet::RightToLeft != d->activeSheet->layoutDirection()==Sheet::RightToLeft )
03799     refreshView();
03800 
03801   doc()->setDisplaySheet( d->activeSheet );
03802   if ( updateSheet )
03803   {
03804     d->tabBar->setActiveTab( _t->sheetName() );
03805     d->vBorderWidget->repaint();
03806     d->hBorderWidget->repaint();
03807     d->activeSheet->setRegionPaintDirty(QRect(QPoint(0,0), QPoint(KS_colMax, KS_rowMax)));
03808     d->canvas->slotMaxColumn( d->activeSheet->maxColumn() );
03809     d->canvas->slotMaxRow( d->activeSheet->maxRow() );
03810   }
03811 
03812   d->actions->showPageBorders->setChecked( d->activeSheet->isShowPageBorders() );
03813   d->actions->protectSheet->setChecked( d->activeSheet->isProtected() );
03814   d->actions->protectDoc->setChecked( doc()->map()->isProtected() );
03815   d->adjustActions( !d->activeSheet->isProtected() );
03816   d->adjustWorkbookActions( !doc()->map()->isProtected() );
03817 
03818   /* see if there was a previous selection on this other sheet */
03819   QMapIterator<Sheet*, QPoint> it = d->savedAnchors.find(d->activeSheet);
03820   QMapIterator<Sheet*, QPoint> it2 = d->savedMarkers.find(d->activeSheet);
03821 
03822   // TODO Stefan: store the save markers/anchors in the Selection?
03823   QPoint newAnchor = (it == d->savedAnchors.end()) ? QPoint(1,1) : *it;
03824   QPoint newMarker = (it2 == d->savedMarkers.end()) ? QPoint(1,1) : *it2;
03825 
03826   d->selection->clear();
03827   d->selection->setSheet( d->activeSheet );
03828   d->selection->initialize(QRect(newMarker, newAnchor));
03829 
03830   d->canvas->scrollToCell(newMarker);
03831   calcStatusBarOp();
03832 
03833   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
03834 }
03835 
03836 void View::slotSheetRenamed( Sheet* sheet, const QString& old_name )
03837 {
03838   doc()->emitBeginOperation( false );
03839   d->tabBar->renameTab( old_name, sheet->sheetName() );
03840   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
03841 }
03842 
03843 void View::slotSheetHidden( Sheet* )
03844 {
03845   doc()->emitBeginOperation(false);
03846   updateShowSheetMenu();
03847   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
03848 }
03849 
03850 void View::slotSheetShown( Sheet* )
03851 {
03852   doc()->emitBeginOperation(false);
03853   d->tabBar->setTabs( doc()->map()->visibleSheets() );
03854   updateShowSheetMenu();
03855   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
03856 }
03857 
03858 void View::changeSheet( const QString& _name )
03859 {
03860     if ( activeSheet()->sheetName() == _name )
03861         return;
03862 
03863     Sheet *t = doc()->map()->findSheet( _name );
03864     if ( !t )
03865     {
03866         kdDebug(36001) << "Unknown sheet " << _name << endl;
03867         return;
03868     }
03869     doc()->emitBeginOperation(false);
03870     d->canvas->closeEditor(); // for selection mode
03871     setActiveSheet( t, false /* False: Endless loop because of setActiveTab() => do the visual area update manually*/);
03872 
03873     d->canvas->updateEditor(); // for choose mode
03874     updateEditWidget();
03875     //refresh toggle button
03876     updateBorderButton();
03877 
03878     //update visible area
03879     d->vBorderWidget->repaint();
03880     d->hBorderWidget->repaint();
03881     d->canvas->slotMaxColumn( d->activeSheet->maxColumn() );
03882     d->canvas->slotMaxRow( d->activeSheet->maxRow() );
03883     t->setRegionPaintDirty( t->visibleRect( d->canvas ) );
03884     doc()->emitEndOperation();
03885 }
03886 
03887 void View::moveSheet( unsigned sheet, unsigned target )
03888 {
03889     if( doc()->map()->isProtected() ) return;
03890 
03891     QStringList vs = doc()->map()->visibleSheets();
03892 
03893     if( target >= vs.count() )
03894         doc()->map()->moveSheet( vs[ sheet ], vs[ vs.count()-1 ], false );
03895     else
03896         doc()->map()->moveSheet( vs[ sheet ], vs[ target ], true );
03897 
03898     d->tabBar->moveTab( sheet, target );
03899 }
03900 
03901 void View::sheetProperties()
03902 {
03903     // sanity check, shouldn't happen
03904     if( doc()->map()->isProtected() ) return;
03905     if( d->activeSheet->isProtected() ) return;
03906 
03907     bool directionChanged = false;
03908 
03909     SheetPropertiesDialog* dlg = new SheetPropertiesDialog( this );
03910     dlg->setLayoutDirection( d->activeSheet->layoutDirection() );
03911     dlg->setAutoCalc( d->activeSheet->getAutoCalc() );
03912     dlg->setShowGrid( d->activeSheet->getShowGrid() );
03913     dlg->setShowPageBorders( d->activeSheet->isShowPageBorders() );
03914     dlg->setShowFormula( d->activeSheet->getShowFormula() );
03915     dlg->setHideZero( d->activeSheet->getHideZero() );
03916     dlg->setShowFormulaIndicator( d->activeSheet->getShowFormulaIndicator() );
03917     dlg->setShowCommentIndicator( d->activeSheet->getShowCommentIndicator() );
03918     dlg->setColumnAsNumber( d->activeSheet->getShowColumnNumber() );
03919     dlg->setLcMode( d->activeSheet->getLcMode() );
03920     dlg->setCapitalizeFirstLetter( d->activeSheet->getFirstLetterUpper() );
03921 
03922     if( dlg->exec() )
03923     {
03924         SheetPropertiesCommand* command = new SheetPropertiesCommand( doc(), d->activeSheet );
03925 
03926         if ( d->activeSheet->layoutDirection() != dlg->layoutDirection() )
03927             directionChanged = true;
03928 
03929         command->setLayoutDirection( dlg->layoutDirection() );
03930         command->setAutoCalc( dlg->autoCalc() );
03931         command->setShowGrid( dlg->showGrid() );
03932         command->setShowPageBorders( dlg->showPageBorders() );
03933         command->setShowFormula( dlg->showFormula() );
03934         command->setHideZero( dlg->hideZero() );
03935         command->setShowFormulaIndicator( dlg->showFormulaIndicator() );
03936         command->setShowCommentIndicator( dlg->showCommentIndicator() );
03937         command->setColumnAsNumber( dlg->columnAsNumber() );
03938         command->setLcMode( dlg->lcMode() );
03939         command->setCapitalizeFirstLetter( dlg->capitalizeFirstLetter() );
03940         doc()->addCommand( command );
03941         command->execute();
03942     }
03943 
03944     delete dlg;
03945 
03946     if ( directionChanged )
03947     {
03948         // the scrollbar and hborder remain reversed otherwise
03949         d->horzScrollBar->setValue( d->horzScrollBar->maxValue() -
03950                                             d->horzScrollBar->value() );
03951         d->hBorderWidget->update();
03952     }
03953 }
03954 
03955 void View::insertSheet()
03956 {
03957   if ( doc()->map()->isProtected() )
03958   {
03959     KMessageBox::error( 0, i18n ( "You cannot change a protected sheet." ) );
03960     return;
03961   }
03962 
03963   doc()->emitBeginOperation( false );
03964   d->canvas->closeEditor();
03965   Sheet * t = doc()->map()->createSheet();
03966   KCommand* command = new AddSheetCommand( t );
03967   doc()->addCommand( command );
03968   updateEditWidget();
03969   setActiveSheet( t );
03970 
03971   if ( doc()->map()->visibleSheets().count() > 1 )
03972   {
03973     d->actions->removeSheet->setEnabled( true );
03974     d->actions->hideSheet->setEnabled( true );
03975   }
03976 
03977   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
03978 }
03979 
03980 void View::hideSheet()
03981 {
03982   if ( !d->activeSheet )
03983     return;
03984 
03985   if ( doc()->map()->visibleSheets().count() ==  1)
03986   {
03987      KMessageBox::error( this, i18n("You cannot hide the last visible sheet.") );
03988      return;
03989   }
03990 
03991   QStringList vs = doc()->map()->visibleSheets();
03992   int i = vs.findIndex( d->activeSheet->tableName() ) - 1;
03993   if( i < 0 ) i = 1;
03994   QString sn = vs[i];
03995 
03996   doc()->emitBeginOperation(false);
03997 
03998   KCommand* command = new HideSheetCommand( activeSheet() );
03999   doc()->addCommand( command );
04000   command->execute();
04001 
04002   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
04003 
04004   d->tabBar->removeTab( d->activeSheet->sheetName() );
04005   d->tabBar->setActiveTab( sn );
04006 }
04007 
04008 void View::showSheet()
04009 {
04010   if ( !d->activeSheet )
04011     return;
04012 
04013   ShowDialog dlg( this, "Sheet show");
04014   dlg.exec();
04015 }
04016 
04017 void View::copySelection()
04018 {
04019   if ( !d->activeSheet )
04020     return;
04021 
04022   if ( canvasWidget()->isObjectSelected() )
04023   {
04024     canvasWidget()->copyOasisObjects();
04025     return;
04026   }
04027   if ( !d->canvas->editor() )
04028   {
04029     d->activeSheet->copySelection( selectionInfo() );
04030 
04031     updateEditWidget();
04032   }
04033   else
04034     d->canvas->editor()->copy();
04035 }
04036 
04037 void View::copyAsText()
04038 {
04039   if ( !d->activeSheet )
04040     return;
04041   d->activeSheet->copyAsText( selectionInfo() );
04042 }
04043 
04044 
04045 void View::cutSelection()
04046 {
04047   if ( !d->activeSheet )
04048     return;
04049   //don't used this function when we edit a cell.
04050   doc()->emitBeginOperation(false);
04051 
04052   if ( canvasWidget()->isObjectSelected() )
04053   {
04054     canvasWidget()->copyOasisObjects();
04055     markSelectionAsDirty();
04056     doc()->emitEndOperation();
04057 
04058     KMacroCommand * macroCommand = 0L;
04059     QPtrListIterator<EmbeddedObject> it( doc()->embeddedObjects() );
04060     for ( ; it.current() ; ++it )
04061     {
04062       if ( it.current()->sheet() == canvasWidget()->activeSheet() && it.current()->isSelected() )
04063       {
04064         if( !macroCommand )
04065           macroCommand = new KMacroCommand( i18n( "Cut Objects" ) );
04066         RemoveObjectCommand *cmd = new RemoveObjectCommand( it.current(), true );
04067         macroCommand->addCommand( cmd );
04068       }
04069     }
04070     if ( macroCommand )
04071     {
04072       doc()->addCommand( macroCommand );
04073       canvasWidget()->setMouseSelectedObject( false );
04074       macroCommand->execute();
04075     }
04076 
04077     return;
04078   }
04079   if ( !d->canvas->editor())
04080   {
04081     d->activeSheet->cutSelection( selectionInfo() );
04082     calcStatusBarOp();
04083     updateEditWidget();
04084     }
04085 else
04086     d->canvas->editor()->cut();
04087 
04088   markSelectionAsDirty();
04089   doc()->emitEndOperation();
04090 }
04091 
04092 void View::paste()
04093 {
04094   if ( !d->activeSheet )
04095     return;
04096 
04097   if (!koDocument()->isReadWrite()) // don't paste into a read only document
04098     return;
04099 
04100   QMimeSource *data = QApplication::clipboard()->data( QClipboard::Clipboard );
04101   for ( int i=0; data->format(i) != 0; i++ )
04102     kdDebug() << "format:" << data->format(i) << endl;
04103 
04104   if ( data->provides( KoStoreDrag::mimeType("application/vnd.oasis.opendocument.spreadsheet" ) ))
04105   {
04106     canvasWidget()->deselectAllObjects();
04107     QCString returnedTypeMime = "application/vnd.oasis.opendocument.spreadsheet";
04108     const QByteArray arr = data->encodedData( returnedTypeMime );
04109     if( arr.isEmpty() )
04110       return;
04111     QBuffer buffer( arr );
04112     KoStore * store = KoStore::createStore( &buffer, KoStore::Read );
04113 
04114     KoOasisStore oasisStore( store );
04115     QDomDocument doc;
04116     QString errorMessage;
04117     bool ok = oasisStore.loadAndParse( "content.xml", doc, errorMessage );
04118     if ( !ok ) {
04119       kdError(32001) << "Error parsing content.xml: " << errorMessage << endl;
04120       return;
04121     }
04122 
04123     KoOasisStyles oasisStyles;
04124     QDomDocument stylesDoc;
04125     (void)oasisStore.loadAndParse( "styles.xml", stylesDoc, errorMessage );
04126     // Load styles from style.xml
04127     oasisStyles.createStyleMap( stylesDoc, true );
04128     // Also load styles from content.xml
04129     oasisStyles.createStyleMap( doc, false );
04130 
04131     // from KSpreadDoc::loadOasis:
04132     QDomElement content = doc.documentElement();
04133     QDomElement realBody ( KoDom::namedItemNS( content, KoXmlNS::office, "body" ) );
04134     if ( realBody.isNull() )
04135     {
04136       kdDebug() << "Invalid OASIS OpenDocument file. No office:body tag found." << endl;
04137       return;
04138     }
04139     QDomElement body = KoDom::namedItemNS( realBody, KoXmlNS::office, "spreadsheet" );
04140 
04141     if ( body.isNull() )
04142     {
04143       kdError(32001) << "No office:spreadsheet found!" << endl;
04144       QDomElement childElem;
04145       QString localName;
04146       forEachElement( childElem, realBody ) {
04147         localName = childElem.localName();
04148       }
04149       return;
04150     }
04151 
04152     KoOasisLoadingContext context( d->doc, oasisStyles, store );
04153     Q_ASSERT( !oasisStyles.officeStyle().isNull() );
04154 
04155     //load in first
04156     d->doc->styleManager()->loadOasisStyleTemplate( oasisStyles );
04157 
04158 //     // TODO check versions and mimetypes etc.
04159     d->doc->loadOasisAreaName( body );
04160     d->doc->loadOasisCellValidation( body );
04161 
04162     //Copied from kspread_doc.cc - refactor into one place asap.
04163     QDictIterator<QDomElement> it( oasisStyles.styles("table-cell") );
04164     QDict<Style> styleElements;
04165     for (;it.current();++it)
04166     {
04167     if ( it.current()->hasAttributeNS( KoXmlNS::style , "name" ) )
04168     {
04169         QString name = it.current()->attributeNS( KoXmlNS::style , "name" , QString::null );
04170         styleElements.insert( name , new Style());
04171         styleElements[name]->loadOasisStyle( oasisStyles , *(it.current()) );
04172     }
04173     }
04174 
04175     // all <sheet:sheet> goes to workbook
04176     bool result = d->doc->map()->loadOasis( body, context, styleElements );
04177 
04178     //release unused styles (again, copied from kspread_doc.cc, needs to be refactored into one place asap.)
04179     QDictIterator<Style> styleIter( styleElements );
04180     for (;styleIter.current();++styleIter)
04181         if (styleIter.current()->release())
04182             delete styleIter.current();
04183 
04184     if (!result)
04185       return;
04186 
04187   }
04188   else
04189   {
04190     //TODO:  What if the clipboard data is available in both pixmap and OASIS format? (ie. for embedded parts)
04191     QPixmap clipboardPixmap = QApplication::clipboard()->pixmap( QClipboard::Clipboard );
04192     if (!clipboardPixmap.isNull())
04193     {
04194         d->activeSheet->insertPicture( markerDocumentPosition()  , clipboardPixmap );
04195     }
04196   }
04197 
04198   doc()->emitBeginOperation( false );
04199   if ( !d->canvas->editor() )
04200   {
04201       //kdDebug(36001) << "Pasting. Rect= " << d->selection->selection(false) << " bytes" << endl;
04202     d->activeSheet->paste( d->selection->lastRange(), true,
04203                            Paste::Normal, Paste::OverWrite,
04204                            false, 0, true );
04205     calcStatusBarOp();
04206     updateEditWidget();
04207   }
04208   else
04209   {
04210     d->canvas->editor()->paste();
04211   }
04212   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
04213 }
04214 
04215 void View::specialPaste()
04216 {
04217   if ( !d->activeSheet )
04218     return;
04219 
04220   SpecialDialog dlg( this, "Special Paste" );
04221   if ( dlg.exec() )
04222   {
04223     if ( d->activeSheet->getAutoCalc() )
04224     {
04225       doc()->emitBeginOperation( false );
04226       d->activeSheet->recalc();
04227       doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
04228     }
04229     calcStatusBarOp();
04230     updateEditWidget();
04231   }
04232 }
04233 
04234 void View::removeComment()
04235 {
04236   if ( !d->activeSheet )
04237         return;
04238 
04239   doc()->emitBeginOperation(false);
04240   d->activeSheet->setSelectionRemoveComment( selectionInfo() );
04241   updateEditWidget();
04242 
04243   markSelectionAsDirty();
04244   doc()->emitEndOperation();
04245 }
04246 
04247 
04248 void View::changeAngle()
04249 {
04250   if ( !d->activeSheet )
04251     return;
04252 
04253   AngleDialog dlg( this, "Angle" ,
04254                     QPoint( d->canvas->markerColumn(), d->canvas->markerRow() ));
04255   if ( dlg.exec() )
04256   {
04257     //TODO Stefan: where is the angle operation?
04258     d->activeSheet->adjustArea(*selectionInfo());
04259   }
04260 }
04261 
04262 void View::setSelectionAngle( int angle )
04263 {
04264   doc()->emitBeginOperation( false );
04265 
04266   if ( d->activeSheet != NULL )
04267   {
04268     d->activeSheet->setSelectionAngle( selectionInfo(), angle );
04269     d->activeSheet->adjustArea(*selectionInfo());
04270   }
04271 
04272   markSelectionAsDirty();
04273   doc()->emitEndOperation();
04274 }
04275 
04276 void View::mergeCell()
04277 {
04278   // sanity check
04279   if( !d->activeSheet )
04280     return;
04281   d->activeSheet->mergeCells(*selectionInfo());
04282 }
04283 
04284 void View::mergeCellHorizontal()
04285 {
04286   // sanity check
04287   if( !d->activeSheet )
04288     return;
04289   d->activeSheet->mergeCells(*selectionInfo(), true);
04290 }
04291 
04292 void View::mergeCellVertical()
04293 {
04294   // sanity check
04295   if( !d->activeSheet )
04296     return;
04297   d->activeSheet->mergeCells(*selectionInfo(), false, true);
04298 }
04299 
04300 void View::dissociateCell()
04301 {
04302   // sanity check
04303   if( !d->activeSheet )
04304     return;
04305   d->activeSheet->dissociateCells(*selectionInfo());
04306 }
04307 
04308 
04309 void View::increaseIndent()
04310 {
04311   if ( !d->activeSheet )
04312     return;
04313 
04314   doc()->emitBeginOperation( false );
04315   d->activeSheet->increaseIndent( d->selection );
04316   updateEditWidget();
04317 
04318   markSelectionAsDirty();
04319   doc()->emitEndOperation();
04320 }
04321 
04322 void View::decreaseIndent()
04323 {
04324   if ( !d->activeSheet )
04325     return;
04326 
04327   doc()->emitBeginOperation( false );
04328   int column = d->canvas->markerColumn();
04329   int row = d->canvas->markerRow();
04330 
04331   d->activeSheet->decreaseIndent( d->selection );
04332   Cell * cell = d->activeSheet->cellAt( column, row );
04333   if ( cell )
04334     if ( !d->activeSheet->isProtected() )
04335       d->actions->decreaseIndent->setEnabled( cell->format()->getIndent( column, row ) > 0.0 );
04336 
04337   markSelectionAsDirty();
04338   doc()->emitEndOperation();
04339 }
04340 
04341 void View::goalSeek()
04342 {
04343   if ( d->canvas->editor() )
04344   {
04345     d->canvas->deleteEditor( true ); // save changes
04346   }
04347 
04348   GoalSeekDialog * dlg
04349     = new GoalSeekDialog( this, QPoint( d->canvas->markerColumn(),
04350                                             d->canvas->markerRow() ),
04351                               "GoalSeekDialog" );
04352   dlg->show();
04353   /* dialog autodeletes itself */
04354 }
04355 
04356 void View::subtotals()
04357 {
04358   if (!activeSheet())
04359       return;
04360 
04361   QRect selection( d->selection->selection() );
04362   if ( ( selection.width() < 2 ) || ( selection.height() < 2 ) )
04363   {
04364     KMessageBox::error( this, i18n("You must select multiple cells.") );
04365     return;
04366   }
04367 
04368   SubtotalDialog dlg(this, selection, "SubtotalDialog" );
04369   if ( dlg.exec() )
04370   {
04371     doc()->emitBeginOperation( false );
04372 
04373     d->selection->initialize( QRect(dlg.selection().topLeft(), dlg.selection().bottomRight()));//, dlg.sheet() );
04374     doc()->emitEndOperation( selection );
04375   }
04376 }
04377 
04378 void View::multipleOperations()
04379 {
04380   if ( d->canvas->editor() )
04381   {
04382     d->canvas->deleteEditor( true ); // save changes
04383   }
04384   //  MultipleOpDlg * dlg = new MultipleOpDlg( this, "MultipleOpDlg" );
04385   //  dlg->show();
04386 }
04387 
04388 void View::textToColumns()
04389 {
04390   if (!activeSheet())
04391       return;
04392 
04393   d->canvas->closeEditor();
04394 
04395   QRect area=d->selection->selection();
04396 
04397   //Only use the first column
04398   area.setRight(area.left());
04399 
04400 /* if ( area.width() > 1 )
04401   {
04402   //Only use the first column
04403 
04404     KMessageBox::error( this, i18n("You must not select an area containing more than one column.") );
04405     return;
04406   }*/
04407 
04408   CSVDialog dialog( this, "CSVDialog", area, CSVDialog::Column );
04409   if( !dialog.cancelled() )
04410     dialog.exec();
04411 }
04412 
04413 void View::consolidate()
04414 {
04415   d->canvas->closeEditor();
04416   ConsolidateDialog * dlg = new ConsolidateDialog( this, "ConsolidateDialog" );
04417   dlg->show();
04418   // dlg destroys itself
04419 }
04420 
04421 void View::sortList()
04422 {
04423   if (!activeSheet()) return;
04424 
04425   ListDialog dlg( this, "List selection" );
04426   dlg.exec();
04427 }
04428 
04429 void View::gotoCell()
04430 {
04431   if (!activeSheet()) return;
04432 
04433   GotoDialog dlg( this, "GotoCell" );
04434   dlg.exec();
04435 }
04436 
04437 void View::find()
04438 {
04439    if (!activeSheet()) return;
04440 
04441     FindDlg dlg( this, "Find", d->findOptions, d->findStrings );
04442     dlg.setHasSelection( !d->selection->isSingular() );
04443     dlg.setHasCursor( true );
04444     if ( KFindDialog::Accepted != dlg.exec() )
04445         return;
04446 
04447     // Save for next time
04448     d->findOptions = dlg.options();
04449     d->findStrings = dlg.findHistory();
04450     d->typeValue = dlg.searchType();
04451     d->directionValue = dlg.searchDirection();
04452 
04453     // Create the KFind object
04454     delete d->find;
04455     delete d->replace;
04456     d->find = new KFind( dlg.pattern(), dlg.options(), this );
04457     d->replace = 0L;
04458 
04459     d->searchInSheets.currentSheet = activeSheet();
04460     d->searchInSheets.firstSheet = d->searchInSheets.currentSheet;
04461 
04462     initFindReplace();
04463     findNext();
04464 }
04465 
04466 // Initialize a find or replace operation, using d->find or d->replace,
04467 // and d->findOptions.
04468 void View::initFindReplace()
04469 {
04470     KFind* findObj = d->find ? d->find : d->replace;
04471     Q_ASSERT( findObj );
04472     connect(findObj, SIGNAL( highlight( const QString &, int, int ) ),
04473             this, SLOT( slotHighlight( const QString &, int, int ) ) );
04474     connect(findObj, SIGNAL( findNext() ),
04475             this, SLOT( findNext() ) );
04476 
04477     bool bck = d->findOptions & KFindDialog::FindBackwards;
04478     Sheet* currentSheet = d->searchInSheets.currentSheet;
04479 
04480     QRect region = ( d->findOptions & KFindDialog::SelectedText )
04481                    ? d->selection->selection()
04482                    : QRect( 1, 1, currentSheet->maxColumn(), currentSheet->maxRow() ); // All cells
04483 
04484     int colStart = !bck ? region.left() : region.right();
04485     int colEnd = !bck ? region.right() : region.left();
04486     int rowStart = !bck ? region.top() :region.bottom();
04487     int rowEnd = !bck ? region.bottom() : region.top();
04488     if ( d->findOptions & KFindDialog::FromCursor ) {
04489         QPoint marker( d->selection->marker() );
04490         colStart = marker.x();
04491         rowStart = marker.y();
04492     }
04493     d->findLeftColumn = region.left();
04494     d->findRightColumn = region.right();
04495     d->findPos = QPoint( colStart, rowStart );
04496     d->findEnd = QPoint( colEnd, rowEnd );
04497     //kdDebug() << k_funcinfo << d->findPos << " to " << d->findEnd << endl;
04498     //kdDebug() << k_funcinfo << "leftcol=" << d->findLeftColumn << " rightcol=" << d->findRightColumn << endl;
04499 }
04500 
04501 void View::findNext()
04502 {
04503     KFind* findObj = d->find ? d->find : d->replace;
04504     if ( !findObj )  {
04505         find();
04506         return;
04507     }
04508     KFind::Result res = KFind::NoMatch;
04509     Cell* cell = findNextCell();
04510     bool forw = ! ( d->findOptions & KFindDialog::FindBackwards );
04511     while ( res == KFind::NoMatch && cell )
04512     {
04513         if ( findObj->needData() )
04514         {
04515             if ( d->typeValue == FindOption::Note )
04516                 findObj->setData( cell->format()->comment( cell->column(), cell->row() ) );
04517             else
04518                 findObj->setData( cell->text() );
04519             d->findPos = QPoint( cell->column(), cell->row() );
04520             //kdDebug() << "setData(cell " << d->findPos << ")" << endl;
04521         }
04522 
04523         // Let KFind inspect the text fragment, and display a dialog if a match is found
04524         if ( d->find )
04525             res = d->find->find();
04526         else
04527             res = d->replace->replace();
04528 
04529         if ( res == KFind::NoMatch )  {
04530             // Go to next cell, skipping unwanted cells
04531             if ( d->directionValue == FindOption::Row )
04532             {
04533                 if ( forw )
04534                     ++d->findPos.rx();
04535                 else
04536                     --d->findPos.rx();
04537             }
04538             else
04539             {
04540                if ( forw )
04541                     ++d->findPos.ry();
04542                 else
04543                     --d->findPos.ry();
04544              }
04545             cell = findNextCell();
04546         }
04547     }
04548 
04549     if ( res == KFind::NoMatch )
04550     {
04551         //emitUndoRedo();
04552         //removeHighlight();
04553         if ( findObj->shouldRestart() ) {
04554             d->findOptions &= ~KFindDialog::FromCursor;
04555             findObj->resetCounts();
04556             findNext();
04557         }
04558         else { // done, close the 'find next' dialog
04559             if ( d->find )
04560                 d->find->closeFindNextDialog();
04561             else
04562                 d->replace->closeReplaceNextDialog();
04563         }
04564     }
04565 }
04566 
04567 Cell* View::nextFindValidCell( int col, int row )
04568 {
04569     Cell *cell = d->searchInSheets.currentSheet->cellAt( col, row );
04570     if ( cell->isDefault() || cell->isObscured() || cell->isFormula() )
04571         cell = 0L;
04572     if ( d->typeValue == FindOption::Note && cell && cell->format()->comment(col, row).isEmpty())
04573         cell = 0L;
04574     return cell;
04575 }
04576 
04577 Cell* View::findNextCell()
04578 {
04579     // getFirstCellRow / getNextCellRight would be faster at doing that,
04580     // but it doesn't seem to be easy to combine it with 'start a column d->find.x()'...
04581 
04582     Sheet* sheet = d->searchInSheets.currentSheet;
04583     Cell* cell = 0L;
04584     bool forw = ! ( d->findOptions & KFindDialog::FindBackwards );
04585     int col = d->findPos.x();
04586     int row = d->findPos.y();
04587     int maxRow = sheet->maxRow();
04588     //kdDebug() << "findNextCell starting at " << col << "," << row << "   forw=" << forw << endl;
04589 
04590     if ( d->directionValue == FindOption::Row )
04591     {
04592         while ( !cell && row != d->findEnd.y() && (forw ? row < maxRow : row >= 0) )
04593         {
04594             while ( !cell && (forw ? col <= d->findRightColumn : col >= d->findLeftColumn) )
04595             {
04596                 cell = nextFindValidCell( col, row );
04597                 if ( forw ) ++col;
04598                 else --col;
04599             }
04600             if ( cell )
04601                 break;
04602             // Prepare looking in the next row
04603             if ( forw )  {
04604                 col = d->findLeftColumn;
04605                 ++row;
04606             } else {
04607                 col = d->findRightColumn;
04608                 --row;
04609             }
04610             //kdDebug() << "next row: " << col << "," << row << endl;
04611         }
04612     }
04613     else
04614     {
04615         while ( !cell && (forw ? col <= d->findRightColumn : col >= d->findLeftColumn) )
04616         {
04617             while ( !cell && row != d->findEnd.y() && (forw ? row < maxRow : row >= 0) )
04618             {
04619                 cell = nextFindValidCell( col, row );
04620                 if ( forw ) ++row;
04621                 else --row;
04622             }
04623             if ( cell )
04624                 break;
04625             // Prepare looking in the next col
04626             if ( forw )  {
04627                 row = 0;
04628                 ++col;
04629             } else {
04630                 col = maxRow;
04631                 --col;
04632             }
04633             //kdDebug() << "next row: " << col << "," << row << endl;
04634         }
04635     }
04636     // if ( !cell )
04637     // No more next cell - TODO go to next sheet (if not looking in a selection)
04638     // (and make d->findEnd (max,max) in that case...)
04639     //kdDebug() << k_funcinfo << " returning " << cell << endl;
04640     return cell;
04641 }
04642 
04643 void View::findPrevious()
04644 {
04645     KFind* findObj = d->find ? d->find : d->replace;
04646     if ( !findObj )  {
04647         find();
04648         return;
04649     }
04650     //kdDebug() << "findPrevious" << endl;
04651     int opt = d->findOptions;
04652     bool forw = ! ( opt & KFindDialog::FindBackwards );
04653     if ( forw )
04654         d->findOptions = ( opt | KFindDialog::FindBackwards );
04655     else
04656         d->findOptions = ( opt & ~KFindDialog::FindBackwards );
04657 
04658     findNext();
04659 
04660     d->findOptions = opt; // restore initial options
04661 }
04662 
04663 void View::replace()
04664 {
04665     SearchDlg dlg( this, "Replace", d->findOptions, d->findStrings, d->replaceStrings );
04666     dlg.setHasSelection( !d->selection->isSingular() );
04667     dlg.setHasCursor( true );
04668     if ( KReplaceDialog::Accepted != dlg.exec() )
04669       return;
04670 
04671     d->findOptions = dlg.options();
04672     d->findStrings = dlg.findHistory();
04673     d->replaceStrings = dlg.replacementHistory();
04674     d->typeValue = dlg.searchType();
04675 
04676     delete d->find;
04677     delete d->replace;
04678     d->find = 0L;
04679     d->replace = new KReplace( dlg.pattern(), dlg.replacement(), dlg.options() );
04680     initFindReplace();
04681     connect(
04682         d->replace, SIGNAL( replace( const QString &, int, int, int ) ),
04683         this, SLOT( slotReplace( const QString &, int, int, int ) ) );
04684 
04685     if ( !doc()->undoLocked() )
04686     {
04687         QRect region( d->findPos, d->findEnd );
04688         //TODO create undo/redo for comment
04689         UndoChangeAreaTextCell *undo = new UndoChangeAreaTextCell( doc(), d->searchInSheets.currentSheet, region );
04690         doc()->addCommand( undo );
04691     }
04692 
04693     findNext();
04694 
04695 #if 0
04696     // Refresh the editWidget
04697     // TODO - after a replacement only?
04698     Cell *cell = activeSheet()->cellAt( canvasWidget()->markerColumn(),
04699                                                canvasWidget()->markerRow() );
04700     if ( cell->text() != 0L )
04701         d->editWidget->setText( cell->text() );
04702     else
04703         d->editWidget->setText( "" );
04704 #endif
04705 }
04706 
04707 void View::slotHighlight( const QString &/*text*/, int /*matchingIndex*/, int /*matchedLength*/ )
04708 {
04709     d->selection->initialize( d->findPos );
04710     KDialogBase *baseDialog=0L;
04711     if ( d->find )
04712         baseDialog = d->find->findNextDialog();
04713     else
04714         baseDialog = d->replace->replaceNextDialog();
04715     kdDebug()<<" baseDialog :"<<baseDialog<<endl;
04716     QRect globalRect( d->findPos, d->findEnd );
04717     globalRect.moveTopLeft( canvasWidget()->mapToGlobal( globalRect.topLeft() ) );
04718     KDialog::avoidArea( baseDialog, QRect( d->findPos, d->findEnd ));
04719 }
04720 
04721 void View::slotReplace( const QString &newText, int, int, int )
04722 {
04723     // Which cell was this again?
04724     Cell *cell = d->searchInSheets.currentSheet->cellAt( d->findPos );
04725 
04726     // ...now I remember, update it!
04727     cell->setDisplayDirtyFlag();
04728     if ( d->typeValue == FindOption::Value )
04729         cell->setCellText( newText );
04730     else if ( d->typeValue == FindOption::Note )
04731       cell->format()->setComment( newText );
04732     cell->clearDisplayDirtyFlag();
04733 }
04734 
04735 void View::conditional()
04736 {
04737   QRect rect( d->selection->selection() );
04738 
04739   if ( util_isRowOrColumnSelected(rect))
04740   {
04741     KMessageBox::error( this, i18n("Area is too large.") );
04742   }
04743   else
04744   {
04745     ConditionalDialog dlg( this, "ConditionalDialog", rect);
04746     dlg.exec();
04747   }
04748 }
04749 
04750 void View::validity()
04751 {
04752   QRect rect( d->selection->selection() );
04753 
04754   if (d->selection->isColumnOrRowSelected())
04755   {
04756     KMessageBox::error( this, i18n("Area is too large."));
04757   }
04758   else
04759   {
04760     DlgValidity dlg( this,"validity",rect);
04761     dlg.exec();
04762   }
04763 }
04764 
04765 
04766 void View::insertSeries()
04767 {
04768     d->canvas->closeEditor();
04769     SeriesDlg dlg( this, "Series", QPoint( d->canvas->markerColumn(), d->canvas->markerRow() ) );
04770     dlg.exec();
04771 }
04772 
04773 void View::sort()
04774 {
04775     if ( d->selection->isSingular() )
04776     {
04777         KMessageBox::error( this, i18n("You must select multiple cells.") );
04778         return;
04779     }
04780 
04781     SortDialog dlg( this, "Sort" );
04782     dlg.exec();
04783 }
04784 
04785 void View::removeHyperlink()
04786 {
04787     QPoint marker( d->selection->marker() );
04788     Cell * cell = d->activeSheet->cellAt( marker );
04789     if( !cell ) return;
04790     if( cell->link().isEmpty() ) return;
04791 
04792     LinkCommand* command = new LinkCommand( cell, QString::null, QString::null );
04793     doc()->addCommand( command );
04794     command->execute();
04795 
04796   canvasWidget()->setFocus();
04797   d->editWidget->setText( cell->text() );
04798 }
04799 
04800 void View::insertHyperlink()
04801 {
04802     if (!activeSheet())
04803         return;
04804 
04805     d->canvas->closeEditor();
04806 
04807     QPoint marker( d->selection->marker() );
04808     Cell* cell = d->activeSheet->cellAt( marker );
04809 
04810     LinkDialog* dlg = new LinkDialog( this );
04811     dlg->setCaption( i18n( "Insert Link" ) );
04812     if( cell )
04813     {
04814       dlg->setText( cell->text() );
04815       if( !cell->link().isEmpty() )
04816       {
04817         dlg->setCaption( i18n( "Edit Link" ) );
04818         dlg->setLink( cell->link() );
04819       }
04820     }
04821 
04822     if( dlg->exec() == KDialog::Accepted )
04823     {
04824         cell = d->activeSheet->nonDefaultCell( marker );
04825 
04826         LinkCommand* command = new LinkCommand( cell, dlg->text(), dlg->link() );
04827         doc()->addCommand( command );
04828         command->execute();
04829 
04830         //refresh editWidget
04831       canvasWidget()->setFocus();
04832       d->editWidget->setText( cell->text() );
04833     }
04834     delete dlg;
04835 }
04836 
04837 void View::insertFromDatabase()
04838 {
04839 #ifndef QT_NO_SQL
04840     d->canvas->closeEditor();
04841 
04842     QRect rect = d->selection->selection();
04843 
04844   QStringList str = QSqlDatabase::drivers();
04845   if ( str.isEmpty() )
04846     {
04847       KMessageBox::error( this, i18n("No database drivers available.  To use this feature you need "
04848         "to install the necessary Qt 3 database drivers.") );
04849 
04850     return;
04851     }
04852 
04853     DatabaseDialog dlg(this, rect, "DatabaseDialog");
04854     dlg.exec();
04855 #endif
04856 }
04857 
04858 void View::insertFromTextfile()
04859 {
04860     d->canvas->closeEditor();
04861     //KMessageBox::information( this, "Not implemented yet, work in progress...");
04862 
04863     CSVDialog dialog( this, "CSVDialog", d->selection->selection(), CSVDialog::File );
04864     if( !dialog.cancelled() )
04865       dialog.exec();
04866 }
04867 
04868 void View::insertFromClipboard()
04869 {
04870     d->canvas->closeEditor();
04871 
04872     CSVDialog dialog( this, "CSVDialog", d->selection->selection(), CSVDialog::Clipboard );
04873     if( !dialog.cancelled() )
04874       dialog.exec();
04875 }
04876 
04877 void View::setupPrinter( KPrinter &prt )
04878 {
04879     if (!activeSheet())
04880         return;
04881 
04882     SheetPrint* print = d->activeSheet->print();
04883 
04884     //apply page layout parameters
04885     KoFormat pageFormat = print->paperFormat();
04886 
04887     prt.setPageSize( static_cast<KPrinter::PageSize>( KoPageFormat::printerPageSize( pageFormat ) ) );
04888 
04889     if ( print->orientation() == PG_LANDSCAPE || pageFormat == PG_SCREEN )
04890         prt.setOrientation( KPrinter::Landscape );
04891     else
04892         prt.setOrientation( KPrinter::Portrait );
04893 
04894     prt.setFullPage( true );
04895 
04896     //add possibility to select the sheets to print:
04897 //     kdDebug() << "Adding sheet selection page." << endl;
04898     KPSheetSelectPage* sheetpage = new KPSheetSelectPage();
04899     prt.addDialogPage(sheetpage);
04900 
04901 //     kdDebug() << "Iterating through available sheets and initializing list of available sheets." << endl;
04902     QPtrList<Sheet> sheetlist = doc()->map()->sheetList();
04903     Sheet* sheet = sheetlist.last();
04904     while ( sheet )
04905     {
04906       kdDebug() << "Adding " << sheet->sheetName() << endl;
04907       sheetpage->prependAvailableSheet(sheet->sheetName());
04908       sheet = sheetlist.prev();
04909     }
04910 }
04911 
04912 void View::print( KPrinter &prt )
04913 {
04914     if (!activeSheet())
04915         return;
04916 
04917     //save the current active sheet for later, so we can restore it at the end
04918     Sheet* selectedsheet = this->activeSheet();
04919 
04920     //print all sheets in the order given by the print dialog (Sheet Selection)
04921     QStringList sheetlist = KPSheetSelectPage::selectedSheets(prt);
04922 
04923     if (sheetlist.empty())
04924     {
04925       kdDebug() << "No sheet for printing selected, printing active sheet" << endl;
04926       sheetlist.append(d->activeSheet->sheetName());
04927     }
04928 
04929     QPainter painter;
04930     painter.begin( &prt );
04931 
04932     bool firstpage = true;
04933 
04934     QStringList::iterator sheetlistiterator;
04935     for (sheetlistiterator = sheetlist.begin(); sheetlistiterator != sheetlist.end(); ++sheetlistiterator)
04936     {
04937         kdDebug() << "  printing sheet " << *sheetlistiterator << endl;
04938         Sheet* sheet = doc()->map()->findSheet(*sheetlistiterator);
04939         if (sheet == NULL)
04940         {
04941           kdWarning() << i18n("Sheet %1 could not be found for printing").arg(*sheetlistiterator) << endl;
04942           continue;
04943         }
04944 
04945         setActiveSheet(sheet,FALSE);
04946 
04947         SheetPrint* print = d->activeSheet->print();
04948 
04949         if (firstpage)
04950           firstpage=false;
04951         else
04952         {
04953           kdDebug() << " inserting new page" << endl;
04954           prt.newPage();
04955         }
04956 
04957         if ( d->canvas->editor() )
04958         {
04959             d->canvas->deleteEditor( true ); // save changes
04960         }
04961 
04962         int oldZoom = doc()->zoom();
04963 
04964         //Comment from KWord
04965         //   We don't get valid metrics from the printer - and we want a better resolution
04966         //   anyway (it's the PS driver that takes care of the printer resolution).
04967         //But KSpread uses fixed 300 dpis, so we can use it.
04968 
04969         QPaintDeviceMetrics metrics( &prt );
04970 
04971         int dpiX = metrics.logicalDpiX();
04972         int dpiY = metrics.logicalDpiY();
04973 
04974         doc()->setZoomAndResolution( int( print->zoom() * 100 ), dpiX, dpiY );
04975 
04976         //store the current setting in a temporary variable
04977         KoOrientation _orient = print->orientation();
04978 
04979         //use the current orientation from print dialog
04980         if ( prt.orientation() == KPrinter::Landscape )
04981         {
04982             print->setPaperOrientation( PG_LANDSCAPE );
04983         }
04984         else
04985         {
04986             print->setPaperOrientation( PG_PORTRAIT );
04987         }
04988 
04989         bool result = print->print( painter, &prt );
04990 
04991         //Restore original orientation
04992         print->setPaperOrientation( _orient );
04993 
04994         doc()->setZoomAndResolution( oldZoom, KoGlobal::dpiX(), KoGlobal::dpiY() );
04995         doc()->newZoomAndResolution( true, false );
04996 
04997         // Repaint at correct zoom
04998         doc()->emitBeginOperation( false );
04999         setZoom( oldZoom, false );
05000         doc()->emitEndOperation();
05001 
05002         // Nothing to print
05003         if( !result )
05004         {
05005             if( !prt.previewOnly() )
05006             {
05007                 KMessageBox::information( 0,
05008                 i18n("Nothing to print for sheet %1.").arg(
05009                 d->activeSheet->sheetName()) );
05010                 //@todo: make sure we really can comment this out,
05011                 //       what to do with partially broken printouts?
05012 //                 prt.abort();
05013             }
05014         }
05015     }
05016 
05017     painter.end();
05018     this->setActiveSheet(selectedsheet);
05019 }
05020 
05021 void View::insertChart( const QRect& _geometry, KoDocumentEntry& _e )
05022 {
05023     if ( !d->activeSheet )
05024       return;
05025 
05026     // Transform the view coordinates to document coordinates
05027     KoRect unzoomedRect = doc()->unzoomRect( _geometry );
05028     unzoomedRect.moveBy( d->canvas->xOffset(), d->canvas->yOffset() );
05029 
05030     InsertObjectCommand *cmd = 0;
05031     if ( d->selection->isColumnOrRowSelected() )
05032     {
05033       KMessageBox::error( this, i18n("Area is too large."));
05034       return;
05035     }
05036     else
05037       cmd = new InsertObjectCommand( unzoomedRect, _e, d->selection->selection(), d->canvas  );
05038 
05039     doc()->addCommand( cmd );
05040     cmd->execute();
05041 }
05042 
05043 void View::insertChild( const QRect& _geometry, KoDocumentEntry& _e )
05044 {
05045   if ( !d->activeSheet )
05046     return;
05047 
05048   // Transform the view coordinates to document coordinates
05049   KoRect unzoomedRect = doc()->unzoomRect( _geometry );
05050   unzoomedRect.moveBy( d->canvas->xOffset(), d->canvas->yOffset() );
05051 
05052   InsertObjectCommand *cmd = new InsertObjectCommand( unzoomedRect, _e, d->canvas );
05053   doc()->addCommand( cmd );
05054   cmd->execute();
05055 }
05056 
05057 KoPoint View::markerDocumentPosition()
05058 {
05059     QPoint marker=selectionInfo()->marker();
05060 
05061     return KoPoint( d->activeSheet->dblColumnPos(marker.x()),
05062                 d->activeSheet->dblRowPos(marker.y()) );
05063 }
05064 
05065 void View::insertPicture()
05066 {
05067   //Note:  We don't use the usual insert handler here (which allows the user to drag-select the target area
05068   //for the object) because when inserting raster graphics, it is usually desireable to insert at 100% size,
05069   //since the graphic won't look right if inserted with an incorrect aspect ratio or if blurred due to the
05070   //scaling.  If the user wishes to change the size and/or aspect ratio, they can do that afterwards.
05071   //This behaviour can be seen in other spreadsheets.
05072   //-- Robert Knight 12/02/06 <robertknight@gmail.com>
05073 
05074   KURL file = KFileDialog::getImageOpenURL( QString::null, d->canvas );
05075 
05076   if (file.isEmpty())
05077     return;
05078 
05079   if ( !d->activeSheet )
05080         return;
05081 
05082   InsertObjectCommand *cmd = new InsertObjectCommand( KoRect(markerDocumentPosition(),KoSize(0,0)) , file, d->canvas );
05083   doc()->addCommand( cmd );
05084   cmd->execute();
05085 }
05086 
05087 void View::slotUpdateChildGeometry( EmbeddedKOfficeObject */*_child*/ )
05088 {
05089     // ##############
05090     // TODO
05091     /*
05092   if ( _child->sheet() != d->activeSheet )
05093     return;
05094 
05095   // Find frame for child
05096   ChildFrame *f = 0L;
05097   QPtrListIterator<ChildFrame> it( m_lstFrames );
05098   for ( ; it.current() && !f; ++it )
05099     if ( it.current()->child() == _child )
05100       f = it.current();
05101 
05102   assert( f != 0L );
05103 
05104   // Are we already up to date ?
05105   if ( _child->geometry() == f->partGeometry() )
05106     return;
05107 
05108   // TODO zooming
05109   f->setPartGeometry( _child->geometry() );
05110     */
05111 }
05112 
05113 void View::toggleProtectDoc( bool mode )
05114 {
05115    if ( !doc() || !doc()->map() )
05116      return;
05117 
05118    QCString passwd;
05119    if ( mode )
05120    {
05121      int result = KPasswordDialog::getNewPassword( passwd, i18n( "Protect Document" ) );
05122      if ( result != KPasswordDialog::Accepted )
05123      {
05124        d->actions->protectDoc->setChecked( false );
05125        return;
05126      }
05127 
05128      QCString hash( "" );
05129      QString password( passwd );
05130      if ( password.length() > 0 )
05131        SHA1::getHash( password, hash );
05132      doc()->map()->setProtected( hash );
05133    }
05134    else
05135    {
05136      int result = KPasswordDialog::getPassword( passwd, i18n( "Unprotect Document" ) );
05137      if ( result != KPasswordDialog::Accepted )
05138      {
05139        d->actions->protectDoc->setChecked( true );
05140        return;
05141      }
05142 
05143      QCString hash( "" );
05144      QString password( passwd );
05145      if ( password.length() > 0 )
05146        SHA1::getHash( password, hash );
05147      if ( !doc()->map()->checkPassword( hash ) )
05148      {
05149        KMessageBox::error( 0, i18n( "Password is incorrect." ) );
05150        d->actions->protectDoc->setChecked( true );
05151        return;
05152      }
05153 
05154      doc()->map()->setProtected( QCString() );
05155    }
05156 
05157    doc()->setModified( true );
05158    d->adjustWorkbookActions( !mode );
05159 }
05160 
05161 void View::toggleProtectSheet( bool mode )
05162 {
05163    if ( !d->activeSheet )
05164        return;
05165 
05166    QCString passwd;
05167    if ( mode )
05168    {
05169      int result = KPasswordDialog::getNewPassword( passwd, i18n( "Protect Sheet" ) );
05170      if ( result != KPasswordDialog::Accepted )
05171      {
05172        d->actions->protectSheet->setChecked( false );
05173        return;
05174      }
05175 
05176      QCString hash( "" );
05177      QString password( passwd );
05178      if ( password.length() > 0 )
05179        SHA1::getHash( password, hash );
05180 
05181      d->activeSheet->setProtected( hash );
05182    }
05183    else
05184    {
05185      int result = KPasswordDialog::getPassword( passwd, i18n( "Unprotect Sheet" ) );
05186      if ( result != KPasswordDialog::Accepted )
05187      {
05188        d->actions->protectSheet->setChecked( true );
05189        return;
05190      }
05191 
05192      QCString hash( "" );
05193      QString password( passwd );
05194      if ( password.length() > 0 )
05195        SHA1::getHash( password, hash );
05196 
05197      if ( !d->activeSheet->checkPassword( hash ) )
05198      {
05199        KMessageBox::error( 0, i18n( "Password is incorrect." ) );
05200        d->actions->protectSheet->setChecked( true );
05201        return;
05202      }
05203 
05204      d->activeSheet->setProtected( QCString() );
05205    }
05206    doc()->setModified( true );
05207    d->adjustActions( !mode );
05208    doc()->emitBeginOperation();
05209    // d->activeSheet->setRegionPaintDirty( QRect(QPoint( 0, 0 ), QPoint( KS_colMax, KS_rowMax ) ) );
05210    refreshView();
05211    updateEditWidget();
05212    doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
05213 }
05214 
05215 void View::togglePageBorders( bool mode )
05216 {
05217   if ( !d->activeSheet )
05218     return;
05219 
05220   doc()->emitBeginOperation( false );
05221   d->activeSheet->setShowPageBorders( mode );
05222   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
05223 }
05224 
05225 void View::viewZoom( const QString & s )
05226 {
05227 
05228   int oldZoom = doc()->zoom();
05229 
05230   bool ok = false;
05231   QRegExp regexp("(\\d+)"); // "Captured" non-empty sequence of digits
05232   regexp.search(s);
05233   int newZoom=regexp.cap(1).toInt(&ok);
05234   if ( !ok || newZoom < 10 ) //zoom should be valid and >10
05235     newZoom = oldZoom;
05236   if ( newZoom != oldZoom )
05237   {
05238     d->actions->viewZoom->setZoom( newZoom );
05239 
05240     doc()->emitBeginOperation( false );
05241 
05242     d->canvas->closeEditor();
05243     setZoom( newZoom, true );
05244 
05245     if (activeSheet())
05246     {
05247         QRect r( d->activeSheet->visibleRect( d->canvas ) );
05248         r.setWidth( r.width() + 2 );
05249         doc()->emitEndOperation( r );
05250     }
05251   }
05252 }
05253 
05254 void View::setZoom( int zoom, bool /*updateViews*/ )
05255 {
05256   kdDebug() << "---------SetZoom: " << zoom << endl;
05257 
05258   // Set the zoom in KoView (for embedded views)
05259   doc()->emitBeginOperation( false );
05260 
05261   doc()->setZoomAndResolution( zoom, KoGlobal::dpiX(), KoGlobal::dpiY());
05262   //KoView::setZoom( doc()->zoomedResolutionY() /* KoView only supports one zoom */ );
05263 
05264   Q_ASSERT(d->activeSheet);
05265 
05266   if (d->activeSheet)  //this is 0 when viewing a document in konqueror!? (see Q_ASSERT above)
05267     d->activeSheet->setRegionPaintDirty(QRect(QPoint(0,0), QPoint(KS_colMax, KS_rowMax)));
05268 
05269   doc()->refreshInterface();
05270   doc()->emitEndOperation();
05271 }
05272 
05273 void View::showStatusBar( bool b )
05274 {
05275   doc()->setShowStatusBar( b );
05276   refreshView();
05277 }
05278 
05279 void View::showTabBar( bool b )
05280 {
05281   doc()->setShowTabBar( b );
05282   refreshView();
05283 }
05284 
05285 void View::showFormulaBar( bool b )
05286 {
05287   doc()->setShowFormulaBar( b );
05288   refreshView();
05289 }
05290 
05291 void View::preference()
05292 {
05293   if ( !d->activeSheet )
05294     return;
05295 
05296   PreferenceDialog dlg( this, "Preference" );
05297   if ( dlg.exec() )
05298   {
05299     doc()->emitBeginOperation( false );
05300     d->activeSheet->refreshPreference();
05301     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
05302   }
05303 }
05304 
05305 void View::addModifyComment()
05306 {
05307   if ( !d->activeSheet )
05308     return;
05309 
05310   CommentDialog dlg( this, "comment",
05311                      QPoint( d->canvas->markerColumn(),
05312                              d->canvas->markerRow() ) );
05313   if ( dlg.exec() )
05314     updateEditWidget();
05315 }
05316 
05317 void View::setSelectionComment( QString comment )
05318 {
05319   if ( d->activeSheet != NULL )
05320   {
05321     doc()->emitBeginOperation( false );
05322 
05323     d->activeSheet->setSelectionComment( selectionInfo(), comment.stripWhiteSpace() );
05324     updateEditWidget();
05325 
05326     markSelectionAsDirty();
05327     doc()->emitEndOperation();
05328   }
05329 }
05330 
05331 void View::editCell()
05332 {
05333   if ( d->canvas->editor() )
05334     return;
05335 
05336   d->canvas->createEditor(true);
05337 }
05338 
05339 bool View::showSheet(const QString& sheetName) {
05340   Sheet *t=doc()->map()->findSheet(sheetName);
05341   if ( !t )
05342   {
05343     kdDebug(36001) << "Unknown sheet " <<sheetName<<  endl;
05344     return false;
05345   }
05346   d->canvas->closeEditor();
05347   setActiveSheet( t );
05348 
05349   return true;
05350 }
05351 
05352 void View::nextSheet()
05353 {
05354   Sheet * t = doc()->map()->nextSheet( activeSheet() );
05355   if ( !t )
05356   {
05357     kdDebug(36001) << "Unknown sheet " <<  endl;
05358     return;
05359   }
05360   d->canvas->closeEditor();
05361   setActiveSheet( t );
05362   d->tabBar->setActiveTab( t->sheetName() );
05363   d->tabBar->ensureVisible( t->sheetName() );
05364 }
05365 
05366 void View::previousSheet()
05367 {
05368   Sheet * t = doc()->map()->previousSheet( activeSheet() );
05369   if ( !t )
05370   {
05371     kdDebug(36001) << "Unknown sheet "  << endl;
05372     return;
05373   }
05374   d->canvas->closeEditor();
05375   setActiveSheet( t );
05376   d->tabBar->setActiveTab( t->sheetName() );
05377   d->tabBar->ensureVisible( t->sheetName() );
05378 }
05379 
05380 void View::firstSheet()
05381 {
05382   Sheet *t = doc()->map()->firstSheet();
05383   if ( !t )
05384   {
05385     kdDebug(36001) << "Unknown sheet " <<  endl;
05386     return;
05387   }
05388   d->canvas->closeEditor();
05389   setActiveSheet( t );
05390   d->tabBar->setActiveTab( t->sheetName() );
05391   d->tabBar->ensureVisible( t->sheetName() );
05392 }
05393 
05394 void View::lastSheet()
05395 {
05396   Sheet *t = doc()->map()->lastSheet( );
05397   if ( !t )
05398   {
05399     kdDebug(36001) << "Unknown sheet " <<  endl;
05400     return;
05401   }
05402   d->canvas->closeEditor();
05403   setActiveSheet( t );
05404   d->tabBar->setActiveTab( t->sheetName() );
05405   d->tabBar->ensureVisible( t->sheetName() );
05406 }
05407 
05408 void View::keyPressEvent ( QKeyEvent* _ev )
05409 {
05410   // Dont eat accelerators
05411   if ( _ev->state() & ( Qt::AltButton | Qt::ControlButton ) )
05412   {
05413     if ( _ev->state() & ( Qt::ControlButton ) )
05414     {
05415       switch( _ev->key() )
05416       {
05417 #ifndef NDEBUG
05418        case Qt::Key_V: // Ctrl+Shift+V to show debug (similar to KWord)
05419         if ( _ev->state() & Qt::ShiftButton )
05420           d->activeSheet->printDebug();
05421 #endif
05422        default:
05423         QWidget::keyPressEvent( _ev );
05424         return;
05425       }
05426     }
05427     QWidget::keyPressEvent( _ev );
05428   }
05429   else
05430     QApplication::sendEvent( d->canvas, _ev );
05431 }
05432 
05433 KoDocument * View::hitTest( const QPoint& /*pos*/ )
05434 {
05435 //     // Code copied from KoView::hitTest
05436 //     KoViewChild *viewChild;
05437 //
05438 //     QWMatrix m = matrix();
05439 //     m.translate( d->canvas->xOffset() / doc()->zoomedResolutionX(),
05440 //                  d->canvas->yOffset() / doc()->zoomedResolutionY() );
05441 //
05442 //     KoDocumentChild *docChild = selectedChild();
05443 //     if ( docChild )
05444 //     {
05445 //         if ( ( viewChild = child( docChild->document() ) ) )
05446 //         {
05447 //             if ( viewChild->frameRegion( m ).contains( pos ) )
05448 //                 return 0;
05449 //         }
05450 //         else
05451 //             if ( docChild->frameRegion( m ).contains( pos ) )
05452 //                 return 0;
05453 //     }
05454 //
05455 //     docChild = activeChild();
05456 //     if ( docChild )
05457 //     {
05458 //         if ( ( viewChild = child( docChild->document() ) ) )
05459 //         {
05460 //             if ( viewChild->frameRegion( m ).contains( pos ) )
05461 //                 return 0;
05462 //         }
05463 //         else
05464 //             if ( docChild->frameRegion( m ).contains( pos ) )
05465 //                 return 0;
05466 //     }
05467 //
05468 //     QPtrListIterator<KoDocumentChild> it( doc()->children() );
05469 //     for (; it.current(); ++it )
05470 //     {
05471 //         // Is the child document on the visible sheet ?
05472 //         if ( ((EmbeddedKOfficeObject*)it.current())->sheet() == d->activeSheet )
05473 //         {
05474 //             KoDocument *doc = it.current()->hitTest( pos, m );
05475 //             if ( doc )
05476 //                 return doc;
05477 //         }
05478 //     }
05479 //
05480   return doc();
05481 }
05482 
05483 int View::leftBorder() const
05484 {
05485   return int( d->canvas->doc()->zoomItX( YBORDER_WIDTH ) );
05486 }
05487 
05488 int View::rightBorder() const
05489 {
05490   return d->vertScrollBar->width();
05491 }
05492 
05493 int View::topBorder() const
05494 {
05495   return d->toolWidget->height() + int( d->canvas->doc()->zoomItX( Format::globalRowHeight() + 2 ) );
05496 }
05497 
05498 int View::bottomBorder() const
05499 {
05500   return d->horzScrollBar->height();
05501 }
05502 
05503 void View::refreshView()
05504 {
05505   kdDebug() << "refreshing view" << endl;
05506 
05507   Sheet * sheet = activeSheet();
05508   if ( !sheet )
05509     return;
05510 
05511   d->adjustActions( !sheet->isProtected() );
05512   d->actions->viewZoom->setZoom( doc()->zoom() );
05513 
05514   bool active = sheet->getShowFormula();
05515   if ( sheet && !sheet->isProtected() )
05516   {
05517     d->actions->alignLeft->setEnabled( !active );
05518     d->actions->alignCenter->setEnabled( !active );
05519     d->actions->alignRight->setEnabled( !active );
05520   }
05521 
05522   d->tabBar->setReadOnly( !doc()->isReadWrite() || doc()->map()->isProtected() );
05523 
05524   d->toolWidget->setShown( doc()->showFormulaBar() );
05525   d->editWidget->showEditWidget( doc()->showFormulaBar() );
05526   d->hBorderWidget->setShown( doc()->showColumnHeader() );
05527   d->vBorderWidget->setShown( doc()->showRowHeader() );
05528   d->vertScrollBar->setShown( doc()->showVerticalScrollBar() );
05529   d->horzScrollBar->setShown( doc()->showHorizontalScrollBar() );
05530   d->tabBar->setShown( doc()->showTabBar() );
05531   if ( statusBar() ) statusBar()->setShown( doc()->showStatusBar() );
05532 
05533   d->canvas->updatePosWidget();
05534 
05535   d->hBorderWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum );
05536   d->hBorderWidget->setMinimumHeight( doc()->zoomItY( Format::globalRowHeight() + 2 ) );
05537   d->vBorderWidget->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding );
05538   d->vBorderWidget->setMinimumWidth( doc()->zoomItX( YBORDER_WIDTH ) );
05539 
05540   Sheet::LayoutDirection sheetDir = sheet->layoutDirection();
05541   bool interfaceIsRTL = QApplication::reverseLayout();
05542 
05543   kdDebug()<<" sheetDir == Sheet::LeftToRight :"<<( sheetDir == Sheet::LeftToRight )<<endl;
05544   if ((sheetDir == Sheet::LeftToRight && !interfaceIsRTL) ||
05545       (sheetDir == Sheet::RightToLeft && interfaceIsRTL))
05546   {
05547     d->formulaBarLayout->setDirection( QBoxLayout::LeftToRight );
05548     d->viewLayout->setOrigin( QGridLayout::TopLeft );
05549     d->tabScrollBarLayout->setDirection( QBoxLayout::LeftToRight );
05550     d->tabBar->setReverseLayout( interfaceIsRTL );
05551   }
05552   else
05553   {
05554     d->formulaBarLayout->setDirection( QBoxLayout::RightToLeft );
05555     d->viewLayout->setOrigin( QGridLayout::TopRight );
05556     d->tabScrollBarLayout->setDirection( QBoxLayout::RightToLeft );
05557     d->tabBar->setReverseLayout( !interfaceIsRTL );
05558   }
05559 
05560 }
05561 
05562 void View::resizeEvent( QResizeEvent * )
05563 {
05564   refreshView();
05565 }
05566 
05567 void View::popupChildMenu( KoChild* child, const QPoint& /*global_pos*/ )
05568 {
05569     if ( !child )
05570   return;
05571 
05572     delete d->popupChild;
05573 
05574 //     d->popupChildObject = static_cast<EmbeddedKOfficeObject*>(child);
05575 //
05576 //     d->popupChild = new QPopupMenu( this );
05577 //
05578 //     d->popupChild->insertItem( i18n("Delete Embedded Document"), this, SLOT( slotPopupDeleteChild() ) );
05579 //
05580 //     d->popupChild->popup( global_pos );
05581 
05582 }
05583 
05584 void View::slotPopupDeleteChild()
05585 {
05586 //     if ( !d->popupChildObject || !d->popupChildObject->sheet() )
05587 //   return;
05588 
05589     //Removed popup warning dialog because
05590     // a) It is annoying from a user's persepective
05591     // b) The behaviour should be consistant with other KOffice apps
05592 
05593     /*int ret = KMessageBox::warningContinueCancel(this,i18n("You are about to remove this embedded document.\nDo you want to continue?"),i18n("Delete Embedded Document"),KGuiItem(i18n("&Delete"),"editdelete"));
05594     if ( ret == KMessageBox::Continue )
05595     {
05596 
05597 }*/
05598 //     doc()->emitBeginOperation(false);
05599 //     d->popupChildObject->sheet()->deleteChild( d->popupChildObject );
05600 //     d->popupChildObject = 0;
05601 //     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
05602 }
05603 
05604 void View::popupColumnMenu( const QPoint & _point )
05605 {
05606   assert( d->activeSheet );
05607 
05608   if ( !koDocument()->isReadWrite() )
05609     return;
05610 
05611     delete d->popupColumn ;
05612 
05613     d->popupColumn = new QPopupMenu( this );
05614 
05615     bool isProtected = d->activeSheet->isProtected();
05616 
05617     if ( !isProtected )
05618     {
05619       d->actions->cellLayout->plug( d->popupColumn );
05620       d->popupColumn->insertSeparator();
05621       d->actions->cut->plug( d->popupColumn );
05622     }
05623     d->actions->copy->plug( d->popupColumn );
05624     if ( !isProtected )
05625     {
05626       d->actions->paste->plug( d->popupColumn );
05627       d->actions->specialPaste->plug( d->popupColumn );
05628       d->actions->insertCellCopy->plug( d->popupColumn );
05629       d->popupColumn->insertSeparator();
05630       d->actions->defaultFormat->plug( d->popupColumn );
05631       // If there is no selection
05632       if (!d->selection->isColumnOrRowSelected())
05633       {
05634         d->actions->areaName->plug( d->popupColumn );
05635       }
05636 
05637       d->actions->resizeColumn->plug( d->popupColumn );
05638       d->popupColumn->insertItem( i18n("Adjust Column"), this, SLOT(slotPopupAdjustColumn() ) );
05639       d->popupColumn->insertSeparator();
05640       d->actions->insertColumn->plug( d->popupColumn );
05641       d->actions->deleteColumn->plug( d->popupColumn );
05642       d->actions->hideColumn->plug( d->popupColumn );
05643 
05644       d->actions->showSelColumns->setEnabled(false);
05645 
05646       ColumnFormat* format;
05647       //kdDebug(36001) << "Column: L: " << rect.left() << endl;
05648       Region::ConstIterator endOfList = d->selection->constEnd();
05649       for (Region::ConstIterator it = d->selection->constBegin(); it != endOfList; ++it)
05650       {
05651         QRect range = (*it)->rect().normalize();
05652         int col;
05653         for (col = range.left(); col < range.right(); ++col)
05654         {
05655           format = activeSheet()->columnFormat(col);
05656 
05657           if ( format->isHide() )
05658           {
05659             d->actions->showSelColumns->setEnabled( true );
05660             d->actions->showSelColumns->plug( d->popupColumn );
05661             break;
05662           }
05663         }
05664         if (range.left() > 1 && col == range.right())
05665         {
05666           bool allHidden = true;
05667           for (col = 1; col < range.left(); ++col)
05668           {
05669             format = activeSheet()->columnFormat(col);
05670 
05671             allHidden &= format->isHide();
05672           }
05673           if (allHidden)
05674           {
05675             d->actions->showSelColumns->setEnabled( true );
05676             d->actions->showSelColumns->plug( d->popupColumn );
05677             break;
05678           }
05679         }
05680         else
05681         {
05682           break;
05683         }
05684       }
05685     }
05686 
05687     QObject::connect( d->popupColumn, SIGNAL(activated( int ) ), this, SLOT( slotActivateTool( int ) ) );
05688 
05689     d->popupColumn->popup( _point );
05690 }
05691 
05692 void View::slotPopupAdjustColumn()
05693 {
05694   if ( !d->activeSheet )
05695       return;
05696 
05697   d->activeSheet->adjustColumn(*selectionInfo());
05698 }
05699 
05700 void View::popupRowMenu( const QPoint & _point )
05701 {
05702     assert( d->activeSheet );
05703 
05704     if ( !koDocument()->isReadWrite() )
05705       return;
05706 
05707     delete d->popupRow ;
05708 
05709     d->popupRow= new QPopupMenu();
05710 
05711     bool isProtected = d->activeSheet->isProtected();
05712 
05713     if ( !isProtected )
05714     {
05715         d->actions->cellLayout->plug( d->popupRow );
05716         d->popupRow->insertSeparator();
05717         d->actions->cut->plug( d->popupRow );
05718     }
05719     d->actions->copy->plug( d->popupRow );
05720     if ( !isProtected )
05721     {
05722       d->actions->paste->plug( d->popupRow );
05723       d->actions->specialPaste->plug( d->popupRow );
05724       d->actions->insertCellCopy->plug( d->popupRow );
05725       d->popupRow->insertSeparator();
05726       d->actions->defaultFormat->plug( d->popupRow );
05727       // If there is no selection
05728       if (!d->selection->isColumnOrRowSelected())
05729       {
05730         d->actions->areaName->plug(d->popupRow);
05731       }
05732 
05733       d->actions->resizeRow->plug( d->popupRow );
05734       d->popupRow->insertItem( i18n("Adjust Row"), this, SLOT( slotPopupAdjustRow() ) );
05735       d->popupRow->insertSeparator();
05736       d->actions->insertRow->plug( d->popupRow );
05737       d->actions->deleteRow->plug( d->popupRow );
05738       d->actions->hideRow->plug( d->popupRow );
05739 
05740       d->actions->showSelColumns->setEnabled(false);
05741 
05742       RowFormat* format;
05743       Region::ConstIterator endOfList = d->selection->constEnd();
05744       for (Region::ConstIterator it = d->selection->constBegin(); it != endOfList; ++it)
05745       {
05746         QRect range = (*it)->rect().normalize();
05747         int row;
05748         for (row = range.top(); row < range.bottom(); ++row)
05749         {
05750           format = activeSheet()->rowFormat(row);
05751 
05752           if ( format->isHide() )
05753           {
05754             d->actions->showSelRows->setEnabled( true );
05755             d->actions->showSelRows->plug( d->popupRow );
05756             break;
05757           }
05758         }
05759         if (range.top() > 1 && row == range.bottom())
05760         {
05761           bool allHidden = true;
05762           for (row = 1; row < range.top(); ++row)
05763           {
05764             format = activeSheet()->rowFormat(row);
05765 
05766             allHidden &= format->isHide();
05767           }
05768           if (allHidden)
05769           {
05770             d->actions->showSelRows->setEnabled( true );
05771             d->actions->showSelRows->plug( d->popupRow );
05772             break;
05773           }
05774         }
05775         else
05776         {
05777           break;
05778         }
05779       }
05780     }
05781 
05782     QObject::connect( d->popupRow, SIGNAL( activated( int ) ), this, SLOT( slotActivateTool( int ) ) );
05783     d->popupRow->popup( _point );
05784 }
05785 
05786 void View::slotPopupAdjustRow()
05787 {
05788   if ( !d->activeSheet )
05789       return;
05790 
05791   d->activeSheet->adjustRow(*selectionInfo());
05792 }
05793 
05794 
05795 void View::slotListChoosePopupMenu( )
05796 {
05797   if ( !koDocument()->isReadWrite() )
05798     return;
05799 
05800   assert( d->activeSheet );
05801   delete d->popupListChoose;
05802 
05803   d->popupListChoose = new QPopupMenu();
05804   int id = 0;
05805   QRect selection( d->selection->selection() );
05806   Cell * cell = d->activeSheet->cellAt( d->canvas->markerColumn(), d->canvas->markerRow() );
05807   QString tmp = cell->text();
05808   QStringList itemList;
05809 
05810   for ( int col = selection.left(); col <= selection.right(); ++col )
05811   {
05812     Cell * c = d->activeSheet->getFirstCellColumn( col );
05813     while ( c )
05814     {
05815       if ( !c->isPartOfMerged()
05816            && !( col == d->canvas->markerColumn()
05817                  && c->row() == d->canvas->markerRow()) )
05818       {
05819         if ( c->value().isString() && c->text() != tmp && !c->text().isEmpty() )
05820         {
05821           if ( itemList.findIndex( c->text() ) == -1 )
05822             itemList.append(c->text());
05823         }
05824       }
05825 
05826       c = d->activeSheet->getNextCellDown( col, c->row() );
05827     }
05828   }
05829 
05830   /* TODO: remove this later:
05831     for( ;c; c = c->nextCell() )
05832    {
05833      int col = c->column();
05834      if ( selection.left() <= col && selection.right() >= col
05835     &&!c->isPartOfMerged()&& !(col==d->canvas->markerColumn()&& c->row()==d->canvas->markerRow()))
05836        {
05837    if (c->isString() && c->text()!=tmp && !c->text().isEmpty())
05838      {
05839        if (itemList.findIndex(c->text())==-1)
05840                  itemList.append(c->text());
05841      }
05842 
05843        }
05844     }
05845  */
05846 
05847   for ( QStringList::Iterator it = itemList.begin(); it != itemList.end();++it )
05848     d->popupListChoose->insertItem( (*it), id++ );
05849 
05850   if ( id == 0 )
05851     return;
05852   RowFormat * rl = d->activeSheet->rowFormat( d->canvas->markerRow());
05853   double tx = d->activeSheet->dblColumnPos( d->canvas->markerColumn(), d->canvas );
05854   double ty = d->activeSheet->dblRowPos(d->canvas->markerRow(), d->canvas );
05855   double h = rl->dblHeight( d->canvas );
05856   if ( cell->extraYCells() )
05857     h = cell->extraHeight();
05858   ty += h;
05859 
05860   if ( d->activeSheet->layoutDirection()==Sheet::RightToLeft )
05861   {
05862     tx = canvasWidget()->width() - tx;
05863   }
05864 
05865   QPoint p( (int)tx, (int)ty );
05866   QPoint p2 = d->canvas->mapToGlobal( p );
05867 
05868   if ( d->activeSheet->layoutDirection()==Sheet::RightToLeft )
05869   {
05870     p2.setX( p2.x() - d->popupListChoose->sizeHint().width() + 1 );
05871   }
05872 
05873   d->popupListChoose->popup( p2 );
05874   QObject::connect( d->popupListChoose, SIGNAL( activated( int ) ),
05875                     this, SLOT( slotItemSelected( int ) ) );
05876 }
05877 
05878 
05879 void View::slotItemSelected( int id )
05880 {
05881   QString tmp = d->popupListChoose->text( id );
05882   int x = d->canvas->markerColumn();
05883   int y = d->canvas->markerRow();
05884   Cell * cell = d->activeSheet->nonDefaultCell( x, y );
05885 
05886   if ( tmp == cell->text() )
05887     return;
05888 
05889   doc()->emitBeginOperation( false );
05890 
05891   if ( !doc()->undoLocked() )
05892   {
05893     UndoSetText* undo = new UndoSetText( doc(), d->activeSheet, cell->text(),
05894                                                        x, y, cell->formatType() );
05895     doc()->addCommand( undo );
05896   }
05897 
05898   cell->setCellText( tmp );
05899   d->editWidget->setText( tmp );
05900 
05901   doc()->emitEndOperation( QRect( x, y, 1, 1 ) );
05902 }
05903 
05904 void View::openPopupMenu( const QPoint & _point )
05905 {
05906     assert( d->activeSheet );
05907     delete d->popupMenu;
05908 
05909     if ( !koDocument()->isReadWrite() )
05910         return;
05911 
05912     d->popupMenu = new QPopupMenu();
05913 
05914     EmbeddedObject *obj;
05915     if ( d->canvas->isObjectSelected() && ( obj = d->canvas->getObject( d->canvas->mapFromGlobal( _point ), d->activeSheet ) ) && obj->isSelected() )
05916     {
05917       d->actions->deleteCell->plug( d->popupMenu );
05918       d->popupMenu->insertSeparator();
05919       d->actions->cut->plug( d->popupMenu );
05920       d->actions->copy->plug( d->popupMenu );
05921       d->actions->paste->plug( d->popupMenu );
05922       d->popupMenu->popup( _point );
05923       d->popupMenu->insertSeparator();
05924       d->actions->actionExtraProperties->plug( d->popupMenu );
05925       return;
05926     }
05927 
05928     Cell * cell = d->activeSheet->cellAt( d->canvas->markerColumn(), d->canvas->markerRow() );
05929 
05930     bool isProtected = d->activeSheet->isProtected();
05931     if ( !cell->isDefault() && cell->format()->notProtected( d->canvas->markerColumn(), d->canvas->markerRow() )
05932          && d->selection->isSingular() )
05933       isProtected = false;
05934 
05935     if ( !isProtected )
05936     {
05937       d->actions->cellLayout->plug( d->popupMenu );
05938       d->popupMenu->insertSeparator();
05939       d->actions->cut->plug( d->popupMenu );
05940     }
05941     d->actions->copy->plug( d->popupMenu );
05942     if ( !isProtected )
05943       d->actions->paste->plug( d->popupMenu );
05944 
05945     if ( !isProtected )
05946     {
05947       d->actions->specialPaste->plug( d->popupMenu );
05948       d->actions->insertCellCopy->plug( d->popupMenu );
05949       d->popupMenu->insertSeparator();
05950       d->actions->deleteCell->plug( d->popupMenu );
05951       d->actions->adjust->plug( d->popupMenu );
05952       d->actions->defaultFormat->plug( d->popupMenu );
05953 
05954       // If there is no selection
05955       if (!d->selection->isColumnOrRowSelected())
05956       {
05957         d->actions->areaName->plug( d->popupMenu );
05958         d->popupMenu->insertSeparator();
05959         d->actions->insertCell->plug( d->popupMenu );
05960         d->actions->removeCell->plug( d->popupMenu );
05961       }
05962 
05963       d->popupMenu->insertSeparator();
05964       d->actions->addModifyComment->plug( d->popupMenu );
05965       if ( !cell->format()->comment(d->canvas->markerColumn(), d->canvas->markerRow()).isEmpty() )
05966       {
05967         d->actions->removeComment->plug( d->popupMenu );
05968       }
05969 
05970       if (activeSheet()->testListChoose(selectionInfo()))
05971       {
05972   d->popupMenu->insertSeparator();
05973   d->popupMenu->insertItem( i18n("Selection List..."), this, SLOT( slotListChoosePopupMenu() ) );
05974       }
05975     }
05976 
05977     // Remove informations about the last tools we offered
05978     d->toolList.clear();
05979     d->toolList.setAutoDelete( true );
05980 
05981     if ( !isProtected && !activeSheet()->getWordSpelling( selectionInfo() ).isEmpty() )
05982     {
05983       d->popupMenuFirstToolId = 10;
05984       int i = 0;
05985       QValueList<KDataToolInfo> tools = KDataToolInfo::query( "QString", "text/plain", doc()->instance() );
05986       if ( tools.count() > 0 )
05987       {
05988         d->popupMenu->insertSeparator();
05989         QValueList<KDataToolInfo>::Iterator entry = tools.begin();
05990         for( ; entry != tools.end(); ++entry )
05991         {
05992           QStringList lst = (*entry).userCommands();
05993           QStringList::ConstIterator it = lst.begin();
05994 
05995           // ### Torben: Insert pixmaps here, too
05996           for (; it != lst.end(); ++it )
05997             d->popupMenu->insertItem( *it, d->popupMenuFirstToolId + i++ );
05998 
05999           lst = (*entry).commands();
06000           it = lst.begin();
06001           for (; it != lst.end(); ++it )
06002           {
06003             Private::ToolEntry *t = new Private::ToolEntry;
06004             t->command = *it;
06005             t->info = *entry;
06006             d->toolList.append( t );
06007           }
06008         }
06009 
06010         QObject::connect( d->popupMenu, SIGNAL( activated( int ) ), this, SLOT( slotActivateTool( int ) ) );
06011       }
06012     }
06013 
06014     d->popupMenu->popup( _point );
06015 }
06016 
06017 void View::slotActivateTool( int _id )
06018 {
06019   if (!activeSheet()) return;
06020 
06021   // Is it the id of a tool in the latest popupmenu ?
06022   if ( _id < d->popupMenuFirstToolId )
06023     return;
06024 
06025   Private::ToolEntry* entry = d->toolList.at( _id - d->popupMenuFirstToolId );
06026 
06027   KDataTool* tool = entry->info.createTool();
06028   if ( !tool )
06029   {
06030       kdDebug(36001) << "Could not create Tool" << endl;
06031       return;
06032   }
06033 
06034   QString text = activeSheet()->getWordSpelling( selectionInfo() );
06035 
06036   if ( tool->run( entry->command, &text, "QString", "text/plain") )
06037   {
06038       doc()->emitBeginOperation(false);
06039 
06040       activeSheet()->setWordSpelling( selectionInfo(), text);
06041 
06042       Cell *cell = d->activeSheet->cellAt( d->canvas->markerColumn(), d->canvas->markerRow() );
06043       d->editWidget->setText( cell->text() );
06044 
06045       doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06046   }
06047 }
06048 
06049 void View::deleteSelection()
06050 {
06051     if (!activeSheet()) return;
06052 
06053     if ( canvasWidget()->isObjectSelected() )
06054     {
06055       deleteSelectedObjects();
06056       return;
06057     }
06058 
06059     doc()->emitBeginOperation( false );
06060     d->activeSheet->deleteSelection( selectionInfo() );
06061     calcStatusBarOp();
06062     updateEditWidget();
06063 
06064     markSelectionAsDirty();
06065     doc()->emitEndOperation();
06066 }
06067 
06068 void View::deleteSelectedObjects()
06069 {
06070   KMacroCommand * macroCommand = 0L;
06071   QPtrListIterator<EmbeddedObject> it( doc()->embeddedObjects() );
06072   for ( ; it.current() ; ++it )
06073   {
06074     if ( it.current()->sheet() == canvasWidget()->activeSheet() && it.current()->isSelected() )
06075     {
06076      // d->activeSheet->setRegionPaintDirty( it.
06077       if( !macroCommand )
06078         macroCommand = new KMacroCommand( i18n( "Remove Object" ) );
06079       RemoveObjectCommand *cmd = new RemoveObjectCommand( it.current() );
06080       macroCommand->addCommand( cmd );
06081     }
06082   }
06083   if ( macroCommand )
06084   {
06085     doc()->addCommand( macroCommand );
06086     canvasWidget()->setMouseSelectedObject( false );
06087     macroCommand->execute();
06088   }
06089 }
06090 
06091 void View::adjust()
06092 {
06093   if ( !d->activeSheet )
06094     return;
06095 
06096   d->activeSheet->adjustArea(*selectionInfo());
06097 }
06098 
06099 void View::clearTextSelection()
06100 {
06101     if (!activeSheet())
06102         return;
06103 
06104     doc()->emitBeginOperation( false );
06105     d->activeSheet->clearTextSelection( selectionInfo() );
06106 
06107     updateEditWidget();
06108 
06109     markSelectionAsDirty();
06110     doc()->emitEndOperation();
06111 }
06112 
06113 void View::clearCommentSelection()
06114 {
06115     if (!activeSheet())
06116         return;
06117 
06118     doc()->emitBeginOperation( false );
06119     d->activeSheet->setSelectionRemoveComment( selectionInfo() );
06120 
06121     updateEditWidget();
06122 
06123     markSelectionAsDirty();
06124     doc()->emitEndOperation();
06125 }
06126 
06127 void View::clearValiditySelection()
06128 {
06129     if (!activeSheet())
06130         return;
06131 
06132     doc()->emitBeginOperation( false );
06133     d->activeSheet->clearValiditySelection( selectionInfo() );
06134 
06135     updateEditWidget();
06136 
06137     markSelectionAsDirty();
06138     doc()->emitEndOperation();
06139 }
06140 
06141 void View::clearConditionalSelection()
06142 {
06143     if (!activeSheet())
06144         return;
06145 
06146     doc()->emitBeginOperation( false );
06147     d->activeSheet->clearConditionalSelection( selectionInfo() );
06148 
06149     updateEditWidget();
06150 
06151     markSelectionAsDirty();
06152     doc()->emitEndOperation();
06153 }
06154 
06155 void View::fillRight()
06156 {
06157   if (!activeSheet())
06158       return;
06159 
06160   doc()->emitBeginOperation( false );
06161   d->activeSheet->fillSelection( selectionInfo(), Sheet::Right );
06162 
06163   markSelectionAsDirty();
06164   doc()->emitEndOperation();
06165 }
06166 
06167 void View::fillLeft()
06168 {
06169   if (!activeSheet())
06170       return;
06171 
06172   doc()->emitBeginOperation( false );
06173   d->activeSheet->fillSelection( selectionInfo(), Sheet::Left );
06174 
06175   markSelectionAsDirty();
06176   doc()->emitEndOperation();
06177 }
06178 
06179 void View::fillUp()
06180 {
06181   if (!activeSheet())
06182       return;
06183 
06184   doc()->emitBeginOperation( false );
06185   d->activeSheet->fillSelection( selectionInfo(), Sheet::Up );
06186 
06187   markSelectionAsDirty();
06188   doc()->emitEndOperation();
06189 }
06190 
06191 void View::fillDown()
06192 {
06193   if (!activeSheet())
06194       return;
06195 
06196   doc()->emitBeginOperation( false );
06197   d->activeSheet->fillSelection( selectionInfo(), Sheet::Down );
06198 
06199   markSelectionAsDirty();
06200   doc()->emitEndOperation();
06201 }
06202 
06203 void View::defaultSelection()
06204 {
06205   if (!activeSheet())
06206     return;
06207 
06208   doc()->emitBeginOperation( false );
06209   d->activeSheet->defaultSelection( selectionInfo() );
06210 
06211   updateEditWidget();
06212 
06213   markSelectionAsDirty();
06214   doc()->emitEndOperation();
06215 }
06216 
06217 void View::slotInsert()
06218 {
06219   QRect r( d->selection->selection() );
06220   InsertDialog dlg( this, "InsertDialog", r, InsertDialog::Insert );
06221   dlg.exec();
06222 }
06223 
06224 void View::slotRemove()
06225 {
06226   QRect r( d->selection->selection() );
06227   InsertDialog dlg( this, "Remove", r, InsertDialog::Remove );
06228   dlg.exec();
06229 }
06230 
06231 void View::slotInsertCellCopy()
06232 {
06233   if ( !d->activeSheet )
06234     return;
06235 
06236   if ( !d->activeSheet->testAreaPasteInsert() )
06237   {
06238     doc()->emitBeginOperation( false );
06239     d->activeSheet->paste( d->selection->lastRange(), true,
06240                            Paste::Normal, Paste::OverWrite, true );
06241     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06242   }
06243   else
06244   {
06245     PasteInsertDialog dlg( this, "Remove", d->selection->selection() );
06246     dlg.exec();
06247   }
06248 
06249   if ( d->activeSheet->getAutoCalc() )
06250   {
06251     doc()->emitBeginOperation( false );
06252     d->activeSheet->recalc();
06253     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06254   }
06255   updateEditWidget();
06256 }
06257 
06258 void View::setAreaName()
06259 {
06260   AreaDialog dlg( this, "Area Name",QPoint(d->canvas->markerColumn(), d->canvas->markerRow()) );
06261   dlg.exec();
06262 }
06263 
06264 void View::showAreaName()
06265 {
06266   reference dlg( this, "Show Area" );
06267   dlg.exec();
06268 }
06269 
06270 void View::resizeRow()
06271 {
06272    if (!activeSheet()) return;
06273 
06274   if ( d->selection->isColumnSelected() )
06275     KMessageBox::error( this, i18n("Area is too large."));
06276   else
06277   {
06278     ResizeRow dlg( this );
06279     dlg.exec();
06280   }
06281 }
06282 
06283 void View::resizeColumn()
06284 {
06285   if (!activeSheet()) return;
06286 
06287 
06288   if ( d->selection->isRowSelected() )
06289     KMessageBox::error( this, i18n( "Area is too large." ) );
06290   else
06291   {
06292     ResizeColumn dlg( this );
06293     dlg.exec();
06294   }
06295 }
06296 
06297 void View::equalizeRow()
06298 {
06299   if (!activeSheet()) return;
06300 
06301   if ( d->selection->isColumnSelected() )
06302     KMessageBox::error( this, i18n( "Area is too large." ) );
06303   else
06304   {
06305     doc()->emitBeginOperation( false );
06306     canvasWidget()->equalizeRow();
06307     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06308   }
06309 }
06310 
06311 void View::equalizeColumn()
06312 {
06313   if (!activeSheet())
06314       return;
06315 
06316   if ( d->selection->isRowSelected() )
06317     KMessageBox::error( this, i18n( "Area is too large." ) );
06318   else
06319   {
06320     doc()->emitBeginOperation( false );
06321     canvasWidget()->equalizeColumn();
06322     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06323   }
06324 }
06325 
06326 
06327 void View::layoutDlg()
06328 {
06329   if (!activeSheet())
06330       return;
06331 
06332   CellFormatDialog dlg( this, d->activeSheet );
06333 }
06334 
06335 void View::extraProperties()
06336 {
06337     if (!activeSheet())
06338         return;
06339     //d->canvas->setToolEditMode( TEM_MOUSE );
06340 
06341     d->m_propertyEditor = new PropertyEditor( this, "KPrPropertyEditor", d->activeSheet, doc() );
06342     d->m_propertyEditor->setCaption( i18n( "Properties" ) );
06343 
06344     connect( d->m_propertyEditor, SIGNAL( propertiesOk() ), this, SLOT( propertiesOk() ) );
06345     d->m_propertyEditor->exec();
06346     disconnect( d->m_propertyEditor, SIGNAL( propertiesOk() ), this, SLOT( propertiesOk() ) );
06347 
06348     delete d->m_propertyEditor;
06349     d->m_propertyEditor = 0;
06350 }
06351 
06352 void View::propertiesOk()
06353 {
06354     KCommand *cmd = d->m_propertyEditor->getCommand();
06355 
06356     if ( cmd )
06357     {
06358         cmd->execute();
06359         doc()->addCommand( cmd );
06360     }
06361 }
06362 
06363 void View::styleDialog()
06364 {
06365   StyleDlg dlg( this, doc()->styleManager() );
06366   dlg.exec();
06367 
06368   d->actions->selectStyle->setItems( doc()->styleManager()->styleNames() );
06369   if ( d->activeSheet )
06370   {
06371     d->activeSheet->setLayoutDirtyFlag();
06372     d->activeSheet->setRegionPaintDirty( d->activeSheet->visibleRect( d->canvas ) );
06373   }
06374   if ( d->canvas )
06375     d->canvas->repaint();
06376 }
06377 
06378 void View::paperLayoutDlg()
06379 {
06380   if ( d->canvas->editor() )
06381   {
06382     d->canvas->deleteEditor( true ); // save changes
06383   }
06384   SheetPrint* print = d->activeSheet->print();
06385 
06386   KoPageLayout pl;
06387   pl.format = print->paperFormat();
06388   pl.orientation = print->orientation();
06389 
06390   pl.ptWidth =  MM_TO_POINT( print->paperWidth() );
06391   pl.ptHeight = MM_TO_POINT( print->paperHeight() );
06392   pl.ptLeft =   MM_TO_POINT( print->leftBorder() );
06393   pl.ptRight =  MM_TO_POINT( print->rightBorder() );
06394   pl.ptTop =    MM_TO_POINT( print->topBorder() );
06395   pl.ptBottom = MM_TO_POINT( print->bottomBorder() );
06396 
06397   KoHeadFoot hf;
06398   hf.headLeft  = print->localizeHeadFootLine( print->headLeft()  );
06399   hf.headRight = print->localizeHeadFootLine( print->headRight() );
06400   hf.headMid   = print->localizeHeadFootLine( print->headMid()   );
06401   hf.footLeft  = print->localizeHeadFootLine( print->footLeft()  );
06402   hf.footRight = print->localizeHeadFootLine( print->footRight() );
06403   hf.footMid   = print->localizeHeadFootLine( print->footMid()   );
06404 
06405   KoUnit::Unit unit = doc()->unit();
06406 
06407   PaperLayout * dlg
06408     = new PaperLayout( this, "PageLayout", pl, hf,
06409                               FORMAT_AND_BORDERS | HEADER_AND_FOOTER,
06410                               unit, d->activeSheet, this );
06411   dlg->show();
06412   // dlg destroys itself
06413 }
06414 
06415 void View::definePrintRange()
06416 {
06417   d->activeSheet->print()->definePrintRange( selectionInfo() );
06418 }
06419 
06420 void View::resetPrintRange()
06421 {
06422   d->activeSheet->print()->resetPrintRange();
06423 }
06424 
06425 void View::wrapText( bool b )
06426 {
06427   if ( d->toolbarLock )
06428     return;
06429 
06430   if ( d->activeSheet != 0L )
06431   {
06432     doc()->emitBeginOperation( false );
06433     d->activeSheet->setSelectionMultiRow( selectionInfo(), b );
06434     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06435   }
06436 }
06437 
06438 void View::alignLeft( bool b )
06439 {
06440   if ( d->toolbarLock )
06441     return;
06442 
06443   if ( d->activeSheet != 0L )
06444   {
06445     doc()->emitBeginOperation( false );
06446     if ( !b )
06447       d->activeSheet->setSelectionAlign( selectionInfo(),
06448                                    Format::Undefined );
06449     else
06450       d->activeSheet->setSelectionAlign( selectionInfo(),
06451                                    Format::Left );
06452 
06453     markSelectionAsDirty();
06454     doc()->emitEndOperation();
06455   }
06456 }
06457 
06458 void View::alignRight( bool b )
06459 {
06460   if ( d->toolbarLock )
06461     return;
06462 
06463   if ( d->activeSheet != 0L )
06464   {
06465     doc()->emitBeginOperation( false );
06466     if ( !b )
06467       d->activeSheet->setSelectionAlign( selectionInfo(), Format::Undefined );
06468     else
06469       d->activeSheet->setSelectionAlign( selectionInfo(), Format::Right );
06470 
06471     markSelectionAsDirty();
06472     doc()->emitEndOperation();
06473   }
06474 }
06475 
06476 void View::alignCenter( bool b )
06477 {
06478   if ( d->toolbarLock )
06479     return;
06480 
06481   if ( d->activeSheet != 0L )
06482   {
06483     doc()->emitBeginOperation( false );
06484     if ( !b )
06485       d->activeSheet->setSelectionAlign( selectionInfo(), Format::Undefined );
06486     else
06487       d->activeSheet->setSelectionAlign( selectionInfo(), Format::Center );
06488 
06489     markSelectionAsDirty();
06490     doc()->emitEndOperation();
06491   }
06492 }
06493 
06494 void View::alignTop( bool b )
06495 {
06496   if ( d->toolbarLock )
06497     return;
06498 
06499   if ( d->activeSheet != 0L )
06500   {
06501     doc()->emitBeginOperation( false );
06502     if ( !b )
06503       d->activeSheet->setSelectionAlignY( selectionInfo(), Format::UndefinedY );
06504     else
06505       d->activeSheet->setSelectionAlignY( selectionInfo(), Format::Top );
06506 
06507     markSelectionAsDirty();
06508     doc()->emitEndOperation();
06509   }
06510 }
06511 
06512 void View::alignBottom( bool b )
06513 {
06514   if ( d->toolbarLock )
06515     return;
06516 
06517   if ( d->activeSheet != 0L )
06518   {
06519     doc()->emitBeginOperation( false );
06520     if ( !b )
06521       d->activeSheet->setSelectionAlignY( selectionInfo(), Format::UndefinedY );
06522     else
06523       d->activeSheet->setSelectionAlignY( selectionInfo(), Format::Bottom );
06524 
06525     markSelectionAsDirty();
06526     doc()->emitEndOperation();
06527   }
06528 }
06529 
06530 void View::alignMiddle( bool b )
06531 {
06532   if ( d->toolbarLock )
06533     return;
06534 
06535   if ( d->activeSheet != 0L )
06536   {
06537     doc()->emitBeginOperation( false );
06538     if ( !b )
06539       d->activeSheet->setSelectionAlignY( selectionInfo(), Format::UndefinedY );
06540     else
06541       d->activeSheet->setSelectionAlignY( selectionInfo(), Format::Middle );
06542 
06543     markSelectionAsDirty();
06544     doc()->emitEndOperation();
06545   }
06546 }
06547 
06548 void View::moneyFormat(bool b)
06549 {
06550   if ( d->toolbarLock )
06551     return;
06552 
06553   doc()->emitBeginOperation( false );
06554   if ( d->activeSheet != 0L )
06555     d->activeSheet->setSelectionMoneyFormat( selectionInfo(), b );
06556   updateEditWidget();
06557 
06558   markSelectionAsDirty();
06559   doc()->emitEndOperation();
06560 }
06561 
06562 void View::createStyleFromCell()
06563 {
06564   if ( !d->activeSheet )
06565     return;
06566 
06567   QPoint p( d->selection->selection().topLeft() );
06568   Cell * cell = d->activeSheet->nonDefaultCell( p.x(), p.y() );
06569 
06570   bool ok = false;
06571   QString styleName( "" );
06572 
06573   while( true )
06574   {
06575     styleName = KInputDialog::getText( i18n( "Create Style From Cell" ),
06576                                        i18n( "Enter name:" ), styleName, &ok, this );
06577 
06578     if ( !ok ) // User pushed an OK button.
06579       return;
06580 
06581     styleName = styleName.stripWhiteSpace();
06582 
06583     if ( styleName.length() < 1 )
06584     {
06585       KNotifyClient::beep();
06586       KMessageBox::sorry( this, i18n( "The style name cannot be empty." ) );
06587       continue;
06588     }
06589 
06590     if ( doc()->styleManager()->style( styleName ) != 0 )
06591     {
06592       KNotifyClient::beep();
06593       KMessageBox::sorry( this, i18n( "A style with this name already exists." ) );
06594       continue;
06595     }
06596     break;
06597   }
06598 
06599   CustomStyle * style = new CustomStyle( cell->format()->style(), styleName );
06600 
06601   doc()->styleManager()->m_styles[ styleName ] = style;
06602   cell->format()->setStyle( style );
06603   QStringList lst( d->actions->selectStyle->items() );
06604   lst.push_back( styleName );
06605   d->actions->selectStyle->setItems( lst );
06606 }
06607 
06608 void View::styleSelected( const QString & style )
06609 {
06610   if (d->activeSheet )
06611   {
06612     Style * s = doc()->styleManager()->style( style );
06613 
06614     if ( s )
06615     {
06616       doc()->emitBeginOperation(false);
06617       d->activeSheet->setSelectionStyle( selectionInfo(), s );
06618 
06619       markSelectionAsDirty();
06620       doc()->emitEndOperation();
06621     }
06622   }
06623 }
06624 
06625 void View::precisionPlus()
06626 {
06627   setSelectionPrecision( 1 );
06628 }
06629 
06630 void View::precisionMinus()
06631 {
06632   setSelectionPrecision( -1 );
06633 }
06634 
06635 void View::setSelectionPrecision( int delta )
06636 {
06637   if ( d->activeSheet != NULL )
06638   {
06639     doc()->emitBeginOperation( false );
06640     d->activeSheet->setSelectionPrecision( selectionInfo(), delta );
06641 
06642     markSelectionAsDirty();
06643     doc()->emitEndOperation();
06644   }
06645 }
06646 
06647 void View::percent( bool b )
06648 {
06649   if ( d->toolbarLock )
06650     return;
06651 
06652   doc()->emitBeginOperation( false );
06653   if ( d->activeSheet != 0L )
06654     d->activeSheet->setSelectionPercent( selectionInfo() ,b );
06655   updateEditWidget();
06656 
06657   markSelectionAsDirty();
06658   doc()->emitEndOperation();
06659 }
06660 
06661 
06662 void View::insertObject()
06663 {
06664   if (!activeSheet())
06665       return;
06666 
06667   doc()->emitBeginOperation( false );
06668   KoDocumentEntry e =  d->actions->insertPart->documentEntry();//KoPartSelectDia::selectPart( d->canvas );
06669   if ( e.isEmpty() )
06670   {
06671     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06672     return;
06673   }
06674 
06675   //Don't start handles more than once
06676   delete d->insertHandler;
06677 
06678   d->insertHandler = new InsertPartHandler( this, d->canvas, e );
06679   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06680 }
06681 
06682 void View::insertChart()
06683 {
06684   if (!activeSheet())
06685       return;
06686 
06687   if ( d->selection->isColumnOrRowSelected() )
06688   {
06689     KMessageBox::error( this, i18n("Area too large."));
06690     return;
06691   }
06692   QValueList<KoDocumentEntry> vec = KoDocumentEntry::query( true, "'KOfficeChart' in ServiceTypes" );
06693   if ( vec.isEmpty() )
06694   {
06695     KMessageBox::error( this, i18n("No charting component registered.") );
06696     return;
06697   }
06698 
06699   //Don't start handles more than once
06700   delete d->insertHandler;
06701 
06702   doc()->emitBeginOperation( false );
06703 
06704   d->insertHandler = new InsertChartHandler( this, d->canvas, vec[0] );
06705   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06706 }
06707 
06708 
06709 
06710 /*
06711   // TODO Use KoView setScaling/xScaling/yScaling instead
06712 void View::zoomMinus()
06713 {
06714   if ( m_fZoom <= 0.25 )
06715     return;
06716 
06717   m_fZoom -= 0.25;
06718 
06719   if ( d->activeSheet != 0L )
06720     d->activeSheet->setLayoutDirtyFlag();
06721 
06722   d->canvas->repaint();
06723   d->vBorderWidget->repaint();
06724   d->hBorderWidget->repaint();
06725 }
06726 
06727 void View::zoomPlus()
06728 {
06729   if ( m_fZoom >= 3 )
06730     return;
06731 
06732   m_fZoom += 0.25;
06733 
06734   if ( d->activeSheet != 0L )
06735     d->activeSheet->setLayoutDirtyFlag();
06736 
06737   d->canvas->repaint();
06738   d->vBorderWidget->repaint();
06739   d->hBorderWidget->repaint();
06740 }
06741 */
06742 
06743 void View::removeSheet()
06744 {
06745   if ( doc()->map()->count() <= 1 || ( doc()->map()->visibleSheets().count() <= 1 ) )
06746   {
06747     KNotifyClient::beep();
06748     KMessageBox::sorry( this, i18n("You cannot delete the only sheet."), i18n("Remove Sheet") ); // FIXME bad english? no english!
06749     return;
06750   }
06751   KNotifyClient::beep();
06752   int ret = KMessageBox::warningContinueCancel( this, i18n( "You are about to remove the active sheet.\nDo you want to continue?" ),
06753                                        i18n( "Remove Sheet" ),KGuiItem(i18n("&Delete"),"editdelete") );
06754 
06755   if ( ret == KMessageBox::Continue )
06756   {
06757     doc()->emitBeginOperation( false );
06758     if ( d->canvas->editor() )
06759     {
06760       d->canvas->deleteEditor( false );
06761     }
06762     doc()->setModified( true );
06763     Sheet * tbl = activeSheet();
06764     KCommand* command = new RemoveSheetCommand( tbl );
06765     doc()->addCommand( command );
06766     command->execute();
06767 
06768 
06769 #if 0
06770     UndoRemoveSheet * undo = new UndoRemoveSheet( doc(), tbl );
06771     doc()->addCommand( undo );
06772     tbl->doc()->map()->takeSheet( tbl );
06773     doc()->takeSheet( tbl );
06774 #endif
06775     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06776   }
06777 }
06778 
06779 
06780 void View::slotRename()
06781 {
06782 
06783   Sheet * sheet = activeSheet();
06784 
06785   if( sheet->isProtected() )
06786   {
06787       KMessageBox::error( 0, i18n ( "You cannot change a protected sheet." ) );
06788       return;
06789   }
06790 
06791   bool ok;
06792   QString activeName = sheet->sheetName();
06793   QString newName = KInputDialog::getText( i18n("Rename Sheet"),i18n("Enter name:"), activeName, &ok, this );
06794 
06795   if( !ok ) return;
06796 
06797   while (!util_validateSheetName(newName))
06798   {
06799     KNotifyClient::beep();
06800     KMessageBox::information( this, i18n("Sheet name contains illegal characters. Only numbers and letters are allowed."),
06801       i18n("Change Sheet Name") );
06802 
06803     newName = newName.simplifyWhiteSpace();
06804     int n = newName.find('-');
06805     if ( n > -1 ) newName[n] = '_';
06806     n = newName.find('!');
06807     if ( n > -1 ) newName[n] = '_';
06808     n = newName.find('$');
06809     if ( n > -1 ) newName[n] = '_';
06810 
06811     newName = KInputDialog::getText( i18n("Rename Sheet"),i18n("Enter name:"), newName, &ok, this );
06812 
06813     if ( !ok ) return;
06814   }
06815 
06816   if ( (newName.stripWhiteSpace()).isEmpty() ) // Sheet name is empty.
06817   {
06818     KNotifyClient::beep();
06819     KMessageBox::information( this, i18n("Sheet name cannot be empty."), i18n("Change Sheet Name") );
06820     // Recursion
06821     slotRename();
06822   }
06823   else if ( newName != activeName ) // Sheet name changed.
06824   {
06825     // Is the name already used
06826     if ( doc()->map()->findSheet( newName ) )
06827     {
06828       KNotifyClient::beep();
06829       KMessageBox::information( this, i18n("This name is already used."), i18n("Change Sheet Name") );
06830       // Recursion
06831       slotRename();
06832       return;
06833     }
06834 
06835     KCommand* command = new RenameSheetCommand( sheet, newName );
06836     doc()->addCommand( command );
06837     command->execute();
06838 
06839     //sheet->setSheetName( newName );
06840 
06841     doc()->emitBeginOperation(false);
06842     updateEditWidget();
06843     doc()->setModified( true );
06844     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06845   }
06846 }
06847 
06848 void View::setText (const QString & _text, bool array)
06849 {
06850   if ( d->activeSheet == 0L )
06851     return;
06852 
06853   if (array) {
06854     // array version
06855     d->activeSheet->setArrayFormula (d->selection, _text);
06856   }
06857   else
06858   {
06859     // non-array version
06860     int x = d->canvas->markerColumn();
06861     int y = d->canvas->markerRow();
06862 
06863     d->activeSheet->setText( y, x, _text );
06864 
06865     Cell * cell = d->activeSheet->cellAt( x, y );
06866     if ( cell->value().isString() && !_text.isEmpty() && !_text.at(0).isDigit() && !cell->isFormula() )
06867       doc()->addStringCompletion( _text );
06868   }
06869 }
06870 
06871 //------------------------------------------------
06872 //
06873 // Document signals
06874 //
06875 //------------------------------------------------
06876 
06877 void View::slotAddSheet( Sheet *_sheet )
06878 {
06879   addSheet( _sheet );
06880 }
06881 
06882 void View::slotRefreshView()
06883 {
06884   refreshView();
06885   d->canvas->repaint();
06886   d->vBorderWidget->repaint();
06887   d->hBorderWidget->repaint();
06888 }
06889 
06890 void View::slotUpdateView( Sheet *_sheet )
06891 {
06892   // Do we display this sheet ?
06893   if ( ( !activeSheet() ) || ( _sheet != d->activeSheet ) )
06894     return;
06895 
06896   d->activeSheet->setRegionPaintDirty( d->activeSheet->visibleRect( d->canvas ) );
06897   doc()->emitEndOperation();
06898 }
06899 
06900 void View::slotUpdateView( Sheet * _sheet, const Region& region )
06901 {
06902   // qDebug("void View::slotUpdateView( Sheet *_sheet, const QRect& %i %i|%i %i )\n",_rect.left(),_rect.top(),_rect.right(),_rect.bottom());
06903 
06904   // Do we display this sheet ?
06905   if ( _sheet != d->activeSheet )
06906     return;
06907 
06908   // doc()->emitBeginOperation( false );
06909   d->activeSheet->setRegionPaintDirty( region );
06910   doc()->emitEndOperation( region );
06911 }
06912 
06913 void View::slotUpdateView( EmbeddedObject *obj )
06914 {
06915   d->canvas->repaintObject( obj );
06916 }
06917 
06918 void View::slotUpdateHBorder( Sheet * _sheet )
06919 {
06920   // kdDebug(36001)<<"void View::slotUpdateHBorder( Sheet *_sheet )\n";
06921 
06922   // Do we display this sheet ?
06923   if ( _sheet != d->activeSheet )
06924     return;
06925 
06926   doc()->emitBeginOperation(false);
06927   d->hBorderWidget->update();
06928   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06929 }
06930 
06931 void View::slotUpdateVBorder( Sheet *_sheet )
06932 {
06933   // kdDebug("void View::slotUpdateVBorder( Sheet *_sheet )\n";
06934 
06935   // Do we display this sheet ?
06936   if ( _sheet != d->activeSheet )
06937     return;
06938 
06939   doc()->emitBeginOperation( false );
06940   d->vBorderWidget->update();
06941   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
06942 }
06943 
06944 void View::slotChangeSelection(const KSpread::Region& changedRegion)
06945 {
06946 //   kdDebug() << *selectionInfo() << endl;
06947 
06948   if (!changedRegion.isValid())
06949   {
06950     return;
06951   }
06952 
06953   doc()->emitBeginOperation( false );
06954 
06955   bool colSelected = d->selection->isColumnSelected();
06956   bool rowSelected = d->selection->isRowSelected();
06957   if (d->activeSheet && !d->activeSheet->isProtected())
06958   {
06959     // Activate or deactivate some actions.
06960     d->actions->resizeRow->setEnabled( !colSelected );
06961     d->actions->equalizeRow->setEnabled( !colSelected );
06962     d->actions->hideRow->setEnabled( !colSelected );
06963     d->actions->validity->setEnabled( !colSelected && !rowSelected);
06964     d->actions->conditional->setEnabled( !colSelected && !rowSelected);
06965     d->actions->resizeColumn->setEnabled( !rowSelected );
06966     d->actions->equalizeColumn->setEnabled( !rowSelected );
06967     d->actions->hideColumn->setEnabled( !rowSelected );
06968     d->actions->textToColumns->setEnabled( !rowSelected );
06969 
06970     bool simpleSelection = d->selection->isSingular() || colSelected || rowSelected;
06971     d->actions->autoFormat->setEnabled( !simpleSelection );
06972     d->actions->sort->setEnabled( !simpleSelection );
06973     d->actions->mergeCell->setEnabled( !simpleSelection );
06974     d->actions->mergeCellHorizontal->setEnabled( !simpleSelection );
06975     d->actions->mergeCellVertical->setEnabled( !simpleSelection );
06976     d->actions->fillRight->setEnabled( !simpleSelection );
06977     d->actions->fillUp->setEnabled( !simpleSelection );
06978     d->actions->fillDown->setEnabled( !simpleSelection );
06979     d->actions->fillLeft->setEnabled( !simpleSelection );
06980     d->actions->insertChartFrame->setEnabled( !simpleSelection );
06981     d->actions->sortDec->setEnabled( !simpleSelection );
06982     d->actions->sortInc->setEnabled( !simpleSelection);
06983     d->actions->createStyle->setEnabled( simpleSelection ); // just from one cell
06984 
06985     bool contiguousSelection = d->selection->isContiguous();
06986     d->actions->subTotals->setEnabled(contiguousSelection);
06987   }
06988   d->actions->selectStyle->setCurrentItem( -1 );
06989   // delayed recalculation of the operation shown in the status bar
06990   d->statusBarOpTimer.start(250, true);
06991   // Send some event around. This is read for example
06992   // by the calculator plugin.
06993 //   SelectionChanged ev(*selectionInfo(), activeSheet()->name());
06994 //   QApplication::sendEvent( this, &ev );
06995 
06996   d->canvas->setSelectionChangePaintDirty( d->activeSheet, changedRegion );
06997   d->vBorderWidget->update();
06998   d->hBorderWidget->update();
06999 
07000   if (colSelected || rowSelected)
07001   {
07002     doc()->emitEndOperation(/* *selectionInfo() */);
07003     return;
07004   }
07005 
07006   d->canvas->validateSelection();
07007 
07008   //Don't scroll to the marker if there is an active embedded object, since this may cause
07009   //the canvas to scroll so that the object isn't in the visible area.
07010   //There is still the problem of the object no longer being visible immediately after deactivating the child
07011   //as the sheet jumps back to the marker though.
07012   if (!activeChild())
07013     d->canvas->scrollToCell(selectionInfo()->marker());
07014 
07015   // Perhaps the user is entering a value in the cell.
07016   // In this case we may not touch the EditWidget
07017   if ( !d->canvas->editor() && !d->canvas->chooseMode() )
07018   {
07019     updateEditWidgetOnPress();
07020   }
07021   d->canvas->updatePosWidget();
07022 
07023   doc()->emitEndOperation(/* *selectionInfo() */);
07024 }
07025 
07026 void View::slotChangeChoice(const KSpread::Region& changedRegion)
07027 {
07028   if (!changedRegion.isValid())
07029   {
07030     return;
07031   }
07032   doc()->emitBeginOperation( false );
07033   d->canvas->updateEditor();
07034   d->canvas->setSelectionChangePaintDirty( d->activeSheet, changedRegion );
07035   d->canvas->scrollToCell(choice()->marker());
07036   doc()->emitEndOperation( *choice() );
07037   kdDebug() << "Choice: " << *choice() << endl;
07038 }
07039 
07040 void View::calcStatusBarOp()
07041 {
07042   Sheet * sheet = activeSheet();
07043   ValueCalc* calc = d->doc->calc();
07044   Value val;
07045   QRect tmpRect(d->selection->selection());
07046   MethodOfCalc tmpMethod = doc()->getTypeOfCalc();
07047   if ( tmpMethod != NoneCalc )
07048   {
07049 
07050     Value range = sheet->valueRange (tmpRect.left(), tmpRect.top(),
07051         tmpRect.right(), tmpRect.bottom());
07052     switch (tmpMethod)
07053     {
07054       case SumOfNumber:
07055         val = calc->sum (range);
07056       break;
07057       case Average:
07058         val = calc->avg (range);
07059       break;
07060       case Min:
07061         val = calc->min (range);
07062       break;
07063       case Max:
07064         val = calc->max (range);
07065       break;
07066       case CountA:
07067         val = Value (calc->count (range));
07068         break;
07069       case Count:
07070         val = Value (calc->count (range, false));
07071       case NoneCalc:
07072       break;
07073       default:
07074       break;
07075     }
07076 
07077   }
07078 
07079   QString res = d->doc->converter()->asString (val).asString ();
07080   QString tmp;
07081   switch(tmpMethod )
07082   {
07083    case SumOfNumber:
07084     tmp = i18n("Sum: ") + res;
07085     break;
07086    case Average:
07087     tmp = i18n("Average: ") + res;
07088     break;
07089    case Min:
07090     tmp = i18n("Min: ") + res;
07091     break;
07092    case Max:
07093     tmp = i18n("Max: ") + res;
07094     break;
07095    case Count:
07096     tmp = i18n("Count: ") + res;
07097     break;
07098    case CountA:
07099     tmp = i18n("CountA: ") + res;
07100     break;
07101    case NoneCalc:
07102     tmp = "";
07103     break;
07104   }
07105 
07106   //doc()->emitBeginOperation();
07107   if ( d->calcLabel )
07108     d->calcLabel->setText(QString(" ") + tmp + ' ');
07109   //doc()->emitEndOperation();
07110 }
07111 
07112 void View::statusBarClicked(int _id)
07113 {
07114   if ( !koDocument()->isReadWrite() || !factory() )
07115     return;
07116   if ( _id == 0 ) //menu calc
07117   {
07118     QPoint mousepos = QCursor::pos();
07119     ((QPopupMenu*)factory()->container( "calc_popup" , this ) )->popup( mousepos );
07120   }
07121 }
07122 
07123 void View::menuCalc( bool )
07124 {
07125   doc()->emitBeginOperation(false);
07126   if ( d->actions->calcMin->isChecked() )
07127   {
07128     doc()->setTypeOfCalc( Min );
07129   }
07130   else if ( d->actions->calcMax->isChecked() )
07131   {
07132     doc()->setTypeOfCalc( Max );
07133   }
07134   else if ( d->actions->calcCount->isChecked() )
07135   {
07136     doc()->setTypeOfCalc( Count );
07137   }
07138   else if ( d->actions->calcAverage->isChecked() )
07139   {
07140     doc()->setTypeOfCalc( Average );
07141   }
07142   else if ( d->actions->calcSum->isChecked() )
07143   {
07144     doc()->setTypeOfCalc( SumOfNumber );
07145   }
07146   else if ( d->actions->calcCountA->isChecked() )
07147   {
07148     doc()->setTypeOfCalc( CountA );
07149   }
07150   else if ( d->actions->calcNone->isChecked() )
07151     doc()->setTypeOfCalc( NoneCalc );
07152 
07153   calcStatusBarOp();
07154 
07155   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
07156 }
07157 
07158 
07159 QWMatrix View::matrix() const
07160 {
07161   QWMatrix m;
07162   m.scale( d->doc->zoomedResolutionX(),
07163            d->doc->zoomedResolutionY() );
07164   m.translate( - d->canvas->xOffset(), - d->canvas->yOffset() );
07165   return m;
07166 }
07167 
07168 void View::transformPart()
07169 {
07170     Q_ASSERT( selectedChild() );
07171 
07172     if ( d->transformToolBox.isNull() )
07173     {
07174         d->transformToolBox = new KoTransformToolBox( selectedChild(), topLevelWidget() );
07175         d->transformToolBox->show();
07176 
07177         d->transformToolBox->setDocumentChild( selectedChild() );
07178     }
07179     else
07180     {
07181         d->transformToolBox->show();
07182         d->transformToolBox->raise();
07183     }
07184 }
07185 
07186 void View::slotChildSelected( KoDocumentChild* /*ch*/ )
07187 {
07188 //   if ( d->activeSheet && !d->activeSheet->isProtected() )
07189 //   {
07190 //     d->actions->transform->setEnabled( true );
07191 //
07192 //     if ( !d->transformToolBox.isNull() )
07193 //     {
07194 //         d->transformToolBox->setEnabled( true );
07195 //         d->transformToolBox->setDocumentChild( ch );
07196 //     }
07197 //   }
07198 
07199 
07200   doc()->emitBeginOperation( false );
07201   d->activeSheet->setRegionPaintDirty(QRect(QPoint(0,0), QPoint(KS_colMax, KS_rowMax)));
07202 
07203   doc()->emitEndOperation();
07204   paintUpdates();
07205 }
07206 
07207 void View::slotChildUnselected( KoDocumentChild* )
07208 {
07209 //   if ( d->activeSheet && !d->activeSheet->isProtected() )
07210 //   {
07211 //     d->actions->transform->setEnabled( false );
07212 //
07213 //     if ( !d->transformToolBox.isNull() )
07214 //     {
07215 //         d->transformToolBox->setEnabled( false );
07216 //     }
07217 //     deleteEditor( true );
07218 //   }
07219 
07220 
07221   doc()->emitBeginOperation( false );
07222   d->activeSheet->setRegionPaintDirty(QRect(QPoint(0,0), QPoint(KS_colMax, KS_rowMax)));
07223   doc()->emitEndOperation();
07224   paintUpdates();
07225 }
07226 
07227 
07228 void View::deleteEditor( bool saveChanges )
07229 {
07230     doc()->emitBeginOperation( false );
07231     d->canvas->deleteEditor( saveChanges );
07232 
07233     markSelectionAsDirty();
07234     doc()->emitEndOperation();
07235 }
07236 
07237 DCOPObject * View::dcopObject()
07238 {
07239   if ( !d->dcop )
07240     d->dcop = new ViewIface( this );
07241 
07242   return d->dcop;
07243 }
07244 
07245 QWidget * View::canvas() const
07246 {
07247   return canvasWidget();
07248 }
07249 
07250 int View::canvasXOffset() const
07251 {
07252   if (!d->activeSheet)
07253       return 0;
07254 
07255   double zoomedResX = d->activeSheet->doc()->zoomedResolutionX();
07256   return int( canvasWidget()->xOffset() * zoomedResX );
07257 }
07258 
07259 int View::canvasYOffset() const
07260 {
07261   if (!d->activeSheet)
07262      return 0;
07263 
07264   double zoomedResY = d->activeSheet->doc()->zoomedResolutionY();
07265   return int( canvasWidget()->yOffset() * zoomedResY );
07266 }
07267 
07268 
07269 void View::guiActivateEvent( KParts::GUIActivateEvent *ev )
07270 {
07271   if ( d->activeSheet )
07272   {
07273     doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
07274 
07275     if ( ev->activated() )
07276     {
07277       if ( d->calcLabel )
07278         calcStatusBarOp();
07279     }
07280     else
07281     {
07282       /*if (d->calcLabel)
07283         {
07284         disconnect(d->calcLabel,SIGNAL(pressed( int )),this,SLOT(statusBarClicked(int)));
07285         }*/
07286     }
07287   }
07288 
07289   KoView::guiActivateEvent( ev );
07290 }
07291 
07292 void View::popupTabBarMenu( const QPoint & _point )
07293 {
07294   if ( !koDocument()->isReadWrite() || !factory() )
07295     return;
07296   if ( d->tabBar )
07297   {
07298     bool state = ( doc()->map()->visibleSheets().count() > 1 );
07299     if ( d->activeSheet && d->activeSheet->isProtected() )
07300     {
07301       d->actions->removeSheet->setEnabled( false );
07302       d->actions->hideSheet->setEnabled( false );
07303       d->actions->showSheet->setEnabled( false );
07304     }
07305     else
07306     {
07307       d->actions->removeSheet->setEnabled( state);
07308       d->actions->hideSheet->setEnabled( state );
07309       d->actions->showSheet->setEnabled( doc()->map()->hiddenSheets().count()>0 );
07310     }
07311     if ( !doc() || !doc()->map() || doc()->map()->isProtected() )
07312     {
07313       d->actions->insertSheet->setEnabled( false );
07314       d->actions->renameSheet->setEnabled( false );
07315       d->actions->showSheet->setEnabled( false );
07316       d->actions->hideSheet->setEnabled( false );
07317       d->actions->removeSheet->setEnabled( false );
07318     }
07319     static_cast<QPopupMenu*>(factory()->container("menupage_popup",this))->popup(_point);
07320   }
07321 }
07322 
07323 void View::updateBorderButton()
07324 {
07325   //  doc()->emitBeginOperation( false );
07326   if ( d->activeSheet )
07327     d->actions->showPageBorders->setChecked( d->activeSheet->isShowPageBorders() );
07328   //  doc()->emitEndOperation();
07329 }
07330 
07331 void View::removeSheet( Sheet *_t )
07332 {
07333   doc()->emitBeginOperation(false);
07334   QString m_tablName=_t->sheetName();
07335   d->tabBar->removeTab( m_tablName );
07336   setActiveSheet( doc()->map()->findSheet( doc()->map()->visibleSheets().first() ));
07337 
07338   bool state = doc()->map()->visibleSheets().count() > 1;
07339   d->actions->removeSheet->setEnabled( state );
07340   d->actions->hideSheet->setEnabled( state );
07341   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
07342 }
07343 
07344 void View::insertSheet( Sheet* sheet )
07345 {
07346   doc()->emitBeginOperation( false );
07347   QString tabName = sheet->sheetName();
07348   if ( !sheet->isHidden() )
07349   {
07350     d->tabBar->addTab( tabName );
07351   }
07352 
07353   bool state = ( doc()->map()->visibleSheets().count() > 1 );
07354   d->actions->removeSheet->setEnabled( state );
07355   d->actions->hideSheet->setEnabled( state );
07356   doc()->emitEndOperation( sheet->visibleRect( d->canvas ) );
07357 }
07358 
07359 QColor View::borderColor() const
07360 {
07361   return d->actions->borderColor->color();
07362 }
07363 
07364 void View::updateShowSheetMenu()
07365 {
07366   doc()->emitBeginOperation( false );
07367   if ( d->activeSheet->isProtected() )
07368     d->actions->showSheet->setEnabled( false );
07369   else
07370     d->actions->showSheet->setEnabled( doc()->map()->hiddenSheets().count() > 0 );
07371   doc()->emitEndOperation( d->activeSheet->visibleRect( d->canvas ) );
07372 }
07373 
07374 void View::closeEditor()
07375 {
07376   if ( d->activeSheet ) { // #45822
07377     doc()->emitBeginOperation( false );
07378     d->canvas->closeEditor();
07379 
07380     markSelectionAsDirty();
07381     doc()->emitEndOperation();
07382   }
07383 }
07384 
07385 void View::markSelectionAsDirty()
07386 {
07387     if (!d->activeSheet)
07388       return;
07389 
07390     d->activeSheet->setRegionPaintDirty( *selectionInfo() );
07391 }
07392 
07393 void View::paintUpdates()
07394 {
07395   /* don't do any begin/end operation here -- this is what is called at an
07396      endOperation
07397   */
07398   d->canvas->paintUpdates();
07399 }
07400 
07401 void View::commandExecuted()
07402 {
07403   updateEditWidget();
07404   calcStatusBarOp();
07405 }
07406 
07407 void View::initialiseMarkerFromSheet( Sheet *_sheet, const QPoint &point )
07408 {
07409     d->savedMarkers.replace( _sheet, point);
07410 }
07411 
07412 QPoint View::markerFromSheet( Sheet *_sheet ) const
07413 {
07414     QMapIterator<Sheet*, QPoint> it2 = d->savedMarkers.find(_sheet);
07415     QPoint newMarker = (it2 == d->savedMarkers.end()) ? QPoint(1,1) : *it2;
07416     return newMarker;
07417 }
07418 
07419 void View::saveCurrentSheetSelection()
07420 {
07421     /* save the current selection on this sheet */
07422     if (d->activeSheet != NULL)
07423     {
07424         d->savedAnchors.replace(d->activeSheet, d->selection->anchor());
07425         kdDebug() << " Current scrollbar vert value: " << d->canvas->vertScrollBar()->value() << endl;
07426         kdDebug() << "Saving marker pos: " << d->selection->marker() << endl;
07427         d->savedMarkers.replace(d->activeSheet, d->selection->marker());
07428     }
07429 }
07430 
07431 void View::handleDamages( const QValueList<Damage*>& damages )
07432 {
07433     QValueList<Damage*>::ConstIterator it;
07434     for( it = damages.begin(); it != damages.end(); ++it )
07435     {
07436         Damage* damage = *it;
07437         if( !damage ) continue;
07438 
07439         if( damage->type() == Damage::Cell )
07440         {
07441             CellDamage* cd = static_cast<CellDamage*>( damage );
07442             Cell* damagedCell = cd->cell();
07443             Sheet* damagedSheet = damagedCell->sheet();
07444             QRect drect( damagedCell->column(), damagedCell->row(), 1, 1 );
07445             damagedSheet->setRegionPaintDirty( drect );
07446             paintUpdates();
07447         }
07448 
07449         if( damage->type() == Damage::Sheet )
07450         {
07451             SheetDamage* sd = static_cast<SheetDamage*>( damage );
07452             Sheet* damagedSheet = sd->sheet();
07453 
07454             if( sd->action() == SheetDamage::PropertiesChanged )
07455             {
07456                 CellBinding  * b = 0;
07457                 for ( b = damagedSheet->firstCellBinding(); b != 0;
07458                     b = damagedSheet->nextCellBinding() )
07459                         b->cellChanged( 0 );
07460 
07461                 d->activeSheet->setRegionPaintDirty( QRect(QPoint(0,0),
07462                     QPoint(KS_colMax, KS_rowMax)));
07463 
07464                 paintUpdates();
07465                 refreshView();
07466             }
07467 
07468         }
07469 
07470     }
07471 }
07472 
07473 void View::runInternalTests()
07474 {
07475     // run various tests, only for developers
07476     KSpread::TestRunner* runner = new KSpread::TestRunner();
07477     runner->exec();
07478     delete runner;
07479 }
07480 
07481 void View::runInspector()
07482 {
07483     // useful to inspect objects
07484     if(!d->activeSheet) return;
07485     Cell * cell = d->activeSheet->cellAt( d->selection->marker() );
07486     KSpread::Inspector* ins = new KSpread::Inspector( cell );
07487     ins->exec();
07488     delete ins;
07489 }
07490 
07491 QColor View::highlightColor()
07492 {
07493     return QApplication::palette().active().highlight().light( 175 );
07494 }
07495 
07496 } // namespace KSpread
07497 
07498 #include "kspread_view.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys