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