kspread Library API Documentation

kspread_selection.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include "kspread_selection.h"
00021 #include "kspread_canvas.h"
00022 #include "kspread_cell.h"
00023 #include "kspread_doc.h"
00024 #include "kspread_global.h"
00025 #include "kspread_sheet.h"
00026 #include "kspread_view.h"
00027 
00028 KSpreadSelection::KSpreadSelection(KSpreadView* view)
00029 {
00030   m_marker = QPoint(1,1);
00031   m_cursorPosition = QPoint(1,1);
00032   m_anchor = QPoint(1,1);
00033 
00034   m_chooseMarker = QPoint(0,0);
00035   m_chooseAnchor = QPoint(0,0);
00036   m_chooseCursor = QPoint(0,0);
00037 
00038   m_chooseSheet = NULL;
00039   m_pView = view;
00040 }
00041 
00042 KSpreadSelection::~KSpreadSelection()
00043 {
00044 }
00045 
00046 /******************************************
00047  * Functions dealing with the current selection
00048  */
00049 /*
00050 void KSpreadSelection::unselect()
00051 {
00052     // No selection? Then do nothing.
00053     if ( singleCellSelection() )
00054         return;
00055 
00056     QRect r = m_rctSelection;
00057     // Discard the selection
00058     KSpreadCell *cell = cellAt(marker());
00059     m_rctSelection.setCoords( m_marker.x(), m_marker.y(),
00060                               m_marker.x() + cell->extraXCells(),
00061                               m_marker.y() + cell->extraYCells() );
00062 
00063     // Emit signal so that the views can update.
00064 //    emit sig_unselect( this, r );
00065 }
00066 */
00067 
00068 QPoint KSpreadSelection::marker() const
00069 {
00070   return m_marker;
00071 }
00072 
00073 QRect KSpreadSelection::selection(bool extend) const
00074 {
00075   int left, top, right, bottom;
00076   left = QMIN(m_anchor.x(), m_marker.x());
00077   top = QMIN(m_anchor.y(), m_marker.y());
00078   right = QMAX(m_anchor.x(), m_marker.x());
00079   bottom = QMAX(m_anchor.y(), m_marker.y());
00080   QRect selection(QPoint(left, top), QPoint(right, bottom));
00081 
00082   if (extend)
00083       return extendToMergedAreas(selection);
00084   return selection;
00085 }
00086 
00087 bool KSpreadSelection::singleCellSelection() const
00088 {
00089   const KSpreadCell* cell =
00090     m_pView->activeSheet()->cellAt(m_marker.x(), m_marker.y());
00091 
00092   QRect currentSelection = selection();
00093   return ((currentSelection.topLeft() == m_marker) &&
00094           (currentSelection.width() - 1 == cell->extraXCells()) &&
00095           (currentSelection.height() - 1 == cell->extraYCells()));
00096 }
00097 
00098 QRect KSpreadSelection::selectionHandleArea() const
00099 {
00100   int column, row;
00101 
00102   // complete rows/columns are selected, use the marker.
00103   if ( util_isRowSelected(selection()) ||
00104        util_isColumnSelected(selection()) )
00105   {
00106     column = marker().x();
00107     row = marker().y();
00108   }
00109   else
00110   {
00111     column = selection().right();
00112     row = selection().bottom();
00113   }
00114   const KSpreadCell* cell = m_pView->activeSheet()->cellAt(column, row);
00115 
00116   double xpos = m_pView->activeSheet()->dblColumnPos( column );
00117   double ypos = m_pView->activeSheet()->dblRowPos( row );
00118   double width = cell->dblWidth( column );
00119   double height = cell->dblHeight( row );
00120 
00121   QPoint rightBottom( m_pView->doc()->zoomItX( xpos + width ),
00122                       m_pView->doc()->zoomItY( ypos + height ) );
00123 
00124   QRect handle( ( rightBottom.x() - 2 ),
00125                 ( rightBottom.y() - 2 ),
00126                 ( 5 ),
00127                 ( 5 ) );
00128   return handle;
00129 }
00130 
00131 void KSpreadSelection::setSelection( const QPoint &newMarker,
00132                                      const QPoint &newAnchor,
00133                                      KSpreadSheet *sheet )
00134 {
00135   QRect oldSelection = selection();
00136   QPoint oldMarker = m_marker;
00137   m_marker = newMarker;
00138   m_anchor = newAnchor;
00139 
00140   QRect newSelection = selection();
00141 
00142   //kdDebug(36001) << "setSelection: anchor = " << newAnchor
00143   //         << " marker = " << newMarker << endl;
00144 
00145   const KSpreadCell* cell = sheet->cellAt(newMarker);
00146   if (!util_isColumnSelected(newSelection) &&
00147       !util_isRowSelected(newSelection) &&
00148       cell->isObscured() && cell->isObscuringForced())
00149   {
00150     cell = cell->obscuringCells().first();
00151     m_marker = QPoint(cell->column(), cell->row());
00152   }
00153 
00154   newSelection = selection();
00155 
00156   /* see if we've actually changed anything */
00157   if ( newSelection == oldSelection && newMarker == oldMarker &&
00158        m_pView->activeSheet() == sheet )
00159     return;
00160 
00161   /* see if the cursor position is still valid */
00162   if (!setCursorPosition(m_cursorPosition))
00163   {
00164     setCursorPosition(newMarker);
00165   }
00166 
00167   m_pView->enableInsertColumn( !util_isRowSelected( newSelection ) );
00168   m_pView->enableInsertRow( !util_isColumnSelected( newSelection ) );
00169   m_pView->slotChangeSelection( sheet, oldSelection, oldMarker );
00170 }
00171 
00172 void KSpreadSelection::setMarker( const QPoint &point,
00173                                   KSpreadSheet* sheet )
00174 {
00175   QPoint topLeft(point);
00176   const KSpreadCell* cell = sheet->cellAt(topLeft);
00177   if (cell->isObscured() && cell->isObscuringForced())
00178   {
00179     cell = cell->obscuringCells().first();
00180     topLeft = QPoint(cell->column(), cell->row());
00181   }
00182 
00183   QPoint botRight(topLeft.x() + cell->extraXCells(),
00184                   topLeft.y() + cell->extraYCells());
00185   setSelection( topLeft, botRight, sheet );
00186 }
00187 
00188 QPoint KSpreadSelection::selectionAnchor()const
00189 {
00190   return m_anchor;
00191   /* the anchor is in the opposite corner of the selection rect from the marker */
00192 
00193   /* these show where the marker is */
00194 /*
00195   bool atTop;
00196   bool atLeft;
00197   QRect anchorArea;
00198 
00199   atLeft = m_marker.x() == m_rctSelection.left();
00200   atTop = m_marker.y() == m_rctSelection.top();
00201 
00202   QPoint anchor(atLeft ? m_rctSelection.right() : m_rctSelection.left(),
00203                 atTop ? m_rctSelection.bottom() : m_rctSelection.top());
00204 
00205   KSpreadSheet* sheet = m_pView->activeSheet();
00206   KSpreadCell* cell = sheet->cellAt(anchor);
00207 
00208   if (cell->isObscured())
00209   {
00210     cell = cell->obscuringCells().first();
00211     anchorArea = QRect(QPoint(cell->column(), cell->row()), anchor);
00212   }
00213   else
00214   {
00215     anchorArea = QRect(anchor, anchor);
00216   }
00217 
00218   return anchorArea;
00219 */
00220 }
00221 
00222 bool KSpreadSelection::setCursorPosition( const QPoint &position )
00223 {
00224   const KSpreadCell* cell = m_pView->activeSheet()->cellAt(m_marker);
00225 
00226   QRect markerArea(m_marker, QPoint(m_marker.x() + cell->mergedXCells(),
00227                                     m_marker.y() + cell->mergedYCells()));
00228 
00229   if (markerArea.contains(position))
00230   {
00231     m_cursorPosition = position;
00232     return true;
00233   }
00234   return false;
00235 }
00236 
00237 QPoint KSpreadSelection::cursorPosition()const
00238 {
00239   return m_cursorPosition;
00240 }
00241 
00242 QRect KSpreadSelection::getChooseRect()const
00243 {
00244   QRect chooseRect;
00245 
00246   chooseRect.setLeft(QMIN(m_chooseMarker.x(), m_chooseAnchor.x()));
00247   chooseRect.setRight(QMAX(m_chooseMarker.x(), m_chooseAnchor.x()));
00248   chooseRect.setTop(QMIN(m_chooseMarker.y(), m_chooseAnchor.y()));
00249   chooseRect.setBottom(QMAX(m_chooseMarker.y(), m_chooseAnchor.y()));
00250 
00251   return chooseRect;
00252 }
00253 
00254 
00255 
00256 QRect KSpreadSelection::extendToMergedAreas(QRect area) const
00257 {
00258   const KSpreadCell *cell = m_pView->activeSheet()->
00259                 cellAt(area.left(), area.top());
00260 
00261   if( util_isColumnSelected(area) ||
00262       util_isRowSelected(area) )
00263     return area;
00264 
00265   else if ( !(cell->isObscured() && cell->isObscuringForced()) &&
00266             (cell->extraXCells() + 1) >= area.width() &&
00267             (cell->extraYCells() + 1) >= area.height())
00268   {
00269     /* if just a single cell is selected, we need to merge even when
00270        the obscuring isn't forced.  But only if this is the cell that
00271        is doing the obscuring -- we still want to be able to click on a cell
00272        that is being obscured.
00273     */
00274     area.setWidth(cell->extraXCells() + 1);
00275     area.setHeight(cell->extraYCells() + 1);
00276   }
00277   else
00278   {
00279     int top=area.top();
00280     int left=area.left();
00281     int bottom=area.bottom();
00282     int right=area.right();
00283     for ( int x = area.left(); x <= area.right(); x++ )
00284       for ( int y = area.top(); y <= area.bottom(); y++ )
00285       {
00286         cell = m_pView->activeSheet()->cellAt( x, y );
00287         if( cell->isForceExtraCells())
00288         {
00289           right=QMAX(right,cell->extraXCells()+x);
00290           bottom=QMAX(bottom,cell->extraYCells()+y);
00291         }
00292         else if ( cell->isObscured() && cell->isObscuringForced() )
00293         {
00294           cell = cell->obscuringCells().first();
00295           left=QMIN(left,cell->column());
00296           top=QMIN(top,cell->row());
00297           bottom=QMAX(bottom,cell->row() + cell->extraYCells());
00298           right=QMAX(right,cell->column() + cell->extraXCells());
00299         }
00300       }
00301 
00302     area.setCoords(left,top,right,bottom);
00303   }
00304   return area;
00305 }
KDE Logo
This file is part of the documentation for kspread Library Version 1.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Feb 13 09:43:13 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003