From koffice Mon Sep 25 20:50:37 2000 From: John Califf Date: Mon, 25 Sep 2000 20:50:37 +0000 To: koffice Subject: another Kword gui patch X-MARC-Message: https://marc.info/?l=koffice&m=96991521116486 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--------------B5EBACE066B276D13EF4D325" This is a multi-part message in MIME format. --------------B5EBACE066B276D13EF4D325 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Attached is a patch to kword_page.cc which fixes these problems or adds these following featuers: 1. Middle button click - clicking middle button in a text frame in edit mode to insert text from clipboard was placing the text where the cursor was, not where the user clicked with mouse. It now moves cursor as near as possible to mouse click location and inserts text there, making that line editable. Also, annoying insertion of "" message into document when clipboard is empty is now eliminated. 2. Right button crash - clicking the right mouse button in edit mode often caused crashes because the algorithm assumed that the cursor was near the mouse click locaton. Cursor is now moved to the mouse click location as with middle button click. This is used to determine the type of object clicked on for an informational dialog yet to be coded. The click does return the correct object type for future use and crashes have been eliminated. 3. Improvements to scrolling within frame viewports with PageUp and PageDown. A new algorithm is used which scrolls by lines and uses the existing flow and paragraph settings, so that when a total distance equal to viewport height has been traversed, scrolling stops. This makes scrolling within complex, connected frames like multiple columns much nicer. Also, cursor moves to end of line on pagedown and beginning on pageup. 4. Improvements to scrolling to prior or next page with Control-PagUp and Control-PageDown. The cursor is now set at the top of the new page and automatically adjusts to frame transitions, so that a user can start editing the page scrolled to within the correct frameset without having to click there with the mouse, if the area is editable. This will allow "go to page number" action later. It's very fast. Please review, edit as desired and commit. It has been well tested. John PS: I still can't receive email but will have a new ISP tomorrow nite. --------------B5EBACE066B276D13EF4D325 Content-Type: text/plain; charset=us-ascii; name="kword_page.cc.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="kword_page.cc.diff" Index: kword_page.cc =================================================================== RCS file: /home/kde/koffice/kword/kword_page.cc,v retrieving revision 1.276 diff -u -3 -p -r1.276 kword_page.cc --- kword_page.cc 2000/09/23 09:57:06 1.276 +++ kword_page.cc 2000/09/25 19:44:39 @@ -1,3 +1,4 @@ + /* This file is part of the KDE project Copyright (C) 1998, 1999 Reginald Stadlbauer @@ -377,7 +378,6 @@ void KWPage::vmmEditFrameResize( int mx, p.setPen( black ); p.setBrush( NoBrush ); - if ( deleteMovingRect ){ // erase old one. int drawX, drawWidth, drawY, drawHeight; drawX=frame->left() - contentsX(); @@ -404,7 +404,7 @@ void KWPage::vmmEditFrameResize( int mx, bool move=true; if(isAFooter(frame->getFrameSet()->getFrameInfo())) move=false; if(newY2-my < minFrameHeight+5) my=newY2-minFrameHeight-5; - if(my < (int)( frame->getPageNum() * ptPaperHeight())) + if(my < (int)( frame->getPageNum() * ptPaperHeight())) my = frame->getPageNum() * ptPaperHeight(); if(move) newY1=my; @@ -412,7 +412,7 @@ void KWPage::vmmEditFrameResize( int mx, bool move=true; if(isAHeader(frame->getFrameSet()->getFrameInfo())) move=false; if(my-newY1 < minFrameHeight+5) my=newY1+minFrameHeight+5; - if(my >= (int)((frame->getPageNum()+1) * ptPaperHeight())) + if(my >= (int)((frame->getPageNum()+1) * ptPaperHeight())) my = (frame->getPageNum()+1) * ptPaperHeight(); if(move) newY2=my; @@ -431,8 +431,8 @@ void KWPage::vmmEditFrameResize( int mx, if(isAHeader(frame->getFrameSet()->getFrameInfo())) move=false; if(isAFooter(frame->getFrameSet()->getFrameInfo())) move=false; if(mx-newX1 < minFrameWidth) mx=newX1+minFrameHeight+5; - if(mx > ptPaperWidth()) - mx = ptPaperWidth(); + if(mx > static_cast(ptPaperWidth())) + mx = static_cast(ptPaperWidth()); if(move) newX2=mx; } @@ -735,7 +735,8 @@ void KWPage::vmpCreatePixmap( int mx, in void KWPage::vmpMidButton() { QClipboard *cb = QApplication::clipboard(); - + bool emptyMessage = FALSE; + if ( cb->data()->provides( MIME_TYPE ) ) { if ( cb->data()->encodedData( MIME_TYPE ).size() ) editPaste( cb->data()->encodedData( MIME_TYPE ), MIME_TYPE ); @@ -744,7 +745,42 @@ void KWPage::vmpMidButton() editPaste( cb->data()->encodedData( "text/plain" ) ); } else if ( !cb->text().isEmpty() ) - editPaste( cb->text() ); + { + // jwc - do not *paste* message about empty clipboard into document + // instead, show message that clipboard is empty. The Qt clipboard + // contents can be not empty, but still null. The + // text inserted into clipboard when clipboard is empty is a Kde + // klipper bug but until that is fixed checking for that message + // is needed to avoid improper insertion of the message text + + if( !cb->text().isNull() ) + { + QString text = cb->text(); + text.simplifyWhiteSpace(); + if(text.compare("")) + editPaste( cb->text() ); + else + emptyMessage = TRUE; + } + else + emptyMessage = TRUE; + } + else + emptyMessage = TRUE; + + if(emptyMessage) + { + maybeDrag = FALSE; + + KMessageBox::sorry(0, + i18n("KWord is unable to paste. The clipboard is empty.")); + + if ( doc->has_selection()) + { + doc->setSelection( FALSE ); + repaintScreen( FALSE ); + } + } } /*================================================================*/ @@ -780,7 +816,7 @@ void KWPage::vmpRightButton( QMouseEvent if(frame->getFrameSet() && frame->getFrameSet()->getFrameInfo() != FI_BODY) return; // enable delete frame_edit_menu->setItemEnabled(frEditDel, true); - // if text frame, + // if text frame, if(frame->getFrameSet() && frame->getFrameSet()->getFrameType() == FT_TEXT) { // if frameset 0 disable delete if(doc->getProcessingType() == KWordDocument::WP && frame->getFrameSet() == doc->getFrameSet(0)) { @@ -789,7 +825,7 @@ void KWPage::vmpRightButton( QMouseEvent } else { frame_edit_menu->setItemEnabled(frEditReconnect, true); } - } else + } else frame_edit_menu->setItemEnabled(frEditReconnect, false); frame_edit_menu->popup( pnt ); } break; @@ -830,21 +866,31 @@ void KWPage::viewportMousePressEvent( QM oldMy = e->y() + contentsY(); int mx = e->x() + contentsX(); int my = e->y() + contentsY(); - - switch ( e->button() ) { - case LeftButton: { - mousePressed = TRUE; + + /* jwc - moved block of code out of switch to provide edit focus change + for *all* mouse clicks - left, middle and right instead of just left - + fixes right click crash in edit mode and improper placement of clipboard + text where cursor was instead of where middle mouse button is clicked. + Also added vmpEdit(mx,my) for all three buttons to coordinate the + focus change by moving cursor as near as possible to where mouse + was clicked, as already happened for left click only */ - QPainter _painter; - _painter.begin( viewport() ); + QPainter _painter; + _painter.begin( viewport() ); - if ( doc->has_selection() && *doc->getSelStart() == *doc->getSelEnd() && mouseMode != MM_EDIT ) { - doc->drawSelection( _painter, contentsX(), contentsY() ); - doc->setSelection( FALSE ); - } + if ( doc->has_selection() && *doc->getSelStart() == *doc->getSelEnd() + && mouseMode != MM_EDIT ) + { + doc->drawSelection( _painter, contentsX(), contentsY() ); + doc->setSelection( FALSE ); + } - _painter.end(); + _painter.end(); + switch ( e->button() ) { + + case LeftButton: { + mousePressed = TRUE; switch ( mouseMode ) { case MM_EDIT: if ( !vmpEdit( mx, my ) ) @@ -867,9 +913,13 @@ void KWPage::viewportMousePressEvent( QM doc->setModified( TRUE ); } break; case MidButton: + if ( !vmpEdit( mx, my ) ) + return; vmpMidButton(); break; case RightButton: + if ( !vmpEdit( mx, my ) ) + return; vmpRightButton( e, mx, my ); break; default: break; @@ -906,13 +956,13 @@ void KWPage::vmrEdit() /*================================================================*/ void KWPage::vmrEditFrame( int /*mx*/, int /*my*/ ) { - int frameset=0; + int frameset=0; KWFrame *frame= doc->getFirstSelectedFrame(frameset); if(!frame) return; if ( doc->getProcessingType() == KWordDocument::DTP ) setRuler2Frame( frame ); gui->getHorzRuler()->setFrameStart( frame->x() ); - + if ( mouseMoved ) { doc->recalcFrames(); doc->updateAllFrames(); @@ -1024,7 +1074,7 @@ void KWPage::vmrCreateTable() grpMgr = new KWGroupManager( doc ); QString _name; int numGroupManagers=doc->getNumGroupManagers(); - bool found=true; + bool found=true; while(found) { // need a new name for the new groupmanager. bool same = false; _name.sprintf( "grpmgr_%d",numGroupManagers); @@ -1394,7 +1444,6 @@ void KWPage::editDeleteFrame() else doc->delFrameSet( theFrame->getFrameSet() ); - // set FC to new frameset fc->setFrameSet( 1 ); fc->init( dynamic_cast( doc->getFrameSet( 0 ) )->getFirstParag() ); @@ -2430,58 +2479,64 @@ bool KWPage::kDown( QKeyEvent *e, int, i return TRUE; } - /*============================= - kPrior - Prior key handler - same as PageUp. Move cursor up one + kPrior - Prior key handler - same as PageUp. Move cursor up one visible document area height and adjust page view accordingly - ===================================*/ + ===================================*/ bool KWPage::kPrior( QKeyEvent *e, int, int, KWParag *parag, KWTextFrameSet *fs ) { - // can't go to a negative pixel value - set new Y offset to - // zero if visible height of viewport is greater than offset - // from start of fc + top border height - - unsigned int newY = fc->getPTY(); - if(newY <= ptTopBorder()) return FALSE; - - if(fc->getPTY() >= visibleHeight()) - { - newY = fc->getPTY() - visibleHeight(); - if(newY <= ptTopBorder()) newY = ptTopBorder(); - } - else - newY = ptTopBorder(); - if ( !doc->has_selection() && e->state() & ShiftButton ) startKeySelection(); else *oldFc = *fc; bool gotoPrevTableCell = FALSE; - if ( fs->getGroupManager() && !parag->getPrev() ) - { + if ( fs->getGroupManager() && !parag->getPrev() ) + { if ( fc->isCursorInFirstLine() ) gotoPrevTableCell = TRUE; } - // move cursor up 1 visible height, keeping current x position - fc->cursorGotoPixelLine(fc->getPTPos(), newY); - - gui->getView()->setFormat( *( ( KWFormat* )fc ) ); - gui->getView()->setFlow( fc->getParag()->getParagLayout()->getFlow() ); - gui->getView()->setLineSpacing( fc->getParag()->getParagLayout()->getLineSpacing().pt() ); - gui->getView()->setParagBorders( fc->getParag()->getParagLayout()->getLeftBorder(), + unsigned int curY = fc->getPTY(); + unsigned int oldY = curY; + unsigned int newY = curY; + unsigned int travY = 0; + newY = (unsigned int)visibleHeight(); + + // scroll cursor up until the total Y distance traversed is + // equal to a viewport height. In framesets with colums it will + // go up and down columns with flow + + while(travY < newY) + { + fc->cursorGotoUp(); + travY += fc->getLineHeight(); + + gui->getView()->setFormat( *( ( KWFormat* )fc ) ); + gui->getView()->setFlow( fc->getParag()->getParagLayout()->getFlow() ); + gui->getView()->setLineSpacing( fc->getParag()->getParagLayout()->getLineSpacing().pt() ); + gui->getView()->setParagBorders( fc->getParag()->getParagLayout()->getLeftBorder(), fc->getParag()->getParagLayout()->getRightBorder(), fc->getParag()->getParagLayout()->getTopBorder(), fc->getParag()->getParagLayout()->getBottomBorder() ); + + curY = fc->getPTY(); + if(curY == oldY) + break; + else + oldY = curY; + } - if ( continueSelection || e->state() & ShiftButton ) - { + fc->cursorGotoLineStart( ); + scrollToCursor(); + + if ( continueSelection || e->state() & ShiftButton ) + { continueKeySelection(); return FALSE; - } - else if ( gotoPrevTableCell ) + } + else if ( gotoPrevTableCell ) cursorGotoPrevTableCell(); return TRUE; @@ -2495,7 +2550,7 @@ bool KWPage::kPrior( QKeyEvent *e, int, bool KWPage::kNext( QKeyEvent *e, int, int, KWParag *parag, KWTextFrameSet *fs ) { - if ( !doc->has_selection() && e->state() & ShiftButton ) + if ( !doc->has_selection() && e->state() & ShiftButton ) startKeySelection(); else *oldFc = *fc; @@ -2505,30 +2560,56 @@ bool KWPage::kNext( QKeyEvent *e, int, i if ( fc->isCursorInLastLine() ) gotoNextTableCell = TRUE; } - - // move cursor down 1 visible height, keeping current x position - fc->cursorGotoPixelLine(fc->getPTPos(), fc->getPTY() + visibleHeight()); - - gui->getView()->setFormat( *( ( KWFormat* )fc ) ); - gui->getView()->setFlow( fc->getParag()->getParagLayout()->getFlow() ); - gui->getView()->setLineSpacing( fc->getParag()->getParagLayout()->getLineSpacing().pt() ); - gui->getView()->setParagBorders( fc->getParag()->getParagLayout()->getLeftBorder(), + + unsigned int curY = fc->getPTY(); + unsigned int oldY = curY; + unsigned int newY = curY; + unsigned int travY = 0; + newY = (unsigned int)visibleHeight(); + + // move cursor down until the total Y distance traversed is + // equal to a viewport height. In framesets with colums it will + // go up and down columns with flow + + while(travY <= newY) + { + fc->cursorGotoDown(); + travY += fc->getLineHeight(); + + gui->getView()->setFormat( *( ( KWFormat* )fc ) ); + gui->getView()->setFlow( fc->getParag()->getParagLayout()->getFlow() ); + gui->getView()->setLineSpacing( fc->getParag()->getParagLayout()->getLineSpacing().pt() ); + gui->getView()->setParagBorders( fc->getParag()->getParagLayout()->getLeftBorder(), fc->getParag()->getParagLayout()->getRightBorder(), fc->getParag()->getParagLayout()->getTopBorder(), fc->getParag()->getParagLayout()->getBottomBorder() ); + + curY = fc->getPTY(); + if(curY == oldY) + break; + else + oldY = curY; + } + + fc->cursorGotoLineEnd( ); + scrollToCursor(); + + // scroll view so that cursor is in middle of view - makes editing a whole + // lot easier than leaving it at bottom, ofen partly hidden by scroll bar + + scrollToOffset( contentsX(), contentsY() + ((unsigned int)visibleHeight()) / 2 ); - if ( continueSelection || e->state() & ShiftButton ) - { + if ( continueSelection || e->state() & ShiftButton ) + { continueKeySelection(); return FALSE; - } - else if ( gotoNextTableCell ) + } + else if ( gotoNextTableCell ) cursorGotoNextTableCell(); return TRUE; } - /*================================================================*/ bool KWPage::kReturn( QKeyEvent *e, int oldPage, int oldFrame, KWParag *oldParag, KWTextFrameSet *frameSet ) { @@ -2860,77 +2941,100 @@ void KWPage::keyPressEvent( QKeyEvent *e if ( !kInsertTableRow() ) STOP; - /*============================================ + /*============================================ scroll up or down by one paper page height, aligning top of view with top of page. Uses PageUp and PageDown with CTRL. key. - + Note that pages returned from calcVisiblePages() start with 1, not 0. Note also that firstVisiblePage and lastVisiblePage are always different even when only one page is visible - first takes floor and last takes ceiling so there is always a difference of at least one! I adjust by always subtracting 1 from last visible page. if two or more pages are visible this will scroll up to the top of - higher one so such pages are not skipped, then scroll a full page + higher one so such pages are not skipped, then scroll a full page on page alignments from there on. Scrolling down does not have this problem as it always goes to the start of the next page after top page in view, even if the lower page is partially visible to start. ===========================================*/ - - if ((e->key() == Key_Prior || e->key() == Key_Next) + + if ((e->key() == Key_Prior || e->key() == Key_Next) && (e->state() & ControlButton)) { calcVisiblePages(); - int ifvPage = static_cast(firstVisiblePage); - int ilvPage = static_cast(lastVisiblePage) - 1; - - // determine whether current view is exactly aligned - // to page boundaries or is in the middle of a page somewhere + int ifvPage = static_cast(firstVisiblePage); + int ilvPage = static_cast(lastVisiblePage) - 1; + + // determine whether current view is exactly aligned + // to page boundaries or is in the middle of a page somewhere + unsigned int topY = (unsigned int)contentsY(); - unsigned int leftover = topY % ptPaperHeight(); + unsigned int leftover = topY % ptPaperHeight(); - // kdDebug() << "leftover: " << leftover << endl; - - if(e->key() == Key_Prior) + if(e->key() == Key_Prior) { - stopProcessKeyEvent(); + stopProcessKeyEvent(); int priorPage = 0; - // kdDebug() << "ifvPage: " << ifvPage << " ilvPage: " << ilvPage << endl; - - // scroll to top of next page - if((ifvPage == ilvPage) && (leftover < 2)) + // scroll to top of next page + if((ifvPage == ilvPage) && (leftover < 2)) { priorPage = ifvPage - 1; - if(priorPage > 0) priorPage -= 1; + if(priorPage > 0) priorPage -= 1; } else // scroll to top of current page - { + { priorPage = ifvPage; - if(priorPage > 0) priorPage -= 1; + if(priorPage > 0) priorPage -= 1; } - scrollToOffset( 0, (priorPage) * (ptPaperHeight()) + 1); + scrollToOffset( contentsX(), (priorPage) * (ptPaperHeight()) + 1); } else if(e->key() == Key_Next) { stopProcessKeyEvent(); int nextPage = 1; - // kdDebug() << "ifvPage: " << ifvPage << " ilvPage: " << ilvPage << endl; - if(ifvPage == ilvPage) nextPage = ifvPage + 1; else nextPage = ifvPage + 1; - - scrollToOffset( 0, (nextPage - 1) * (ptPaperHeight()) + 1); - } - // note: vmrEdit will set cursor at offset into document !!! - // risky - will test later. jwc - // vmrEdit(0, (nextPage - 1) * (ptPaperHeight()) + 1); + + scrollToOffset( contentsX(), (nextPage - 1) * (ptPaperHeight()) + 1); + } + + unsigned int mx = contentsX() + ptLeftBorder(); + unsigned int my = contentsY() + ptTopBorder(); + + int frameset = doc->getFrameSet(mx, my); + + if ( frameset != -1 + && doc->getFrameSet( frameset )->getFrameType() == FT_TEXT ) + { + fc->setFrameSet( frameset + 1 ); + fc->cursorGotoPixelLine( mx, my ); + fc->cursorGotoPixelInLine( mx, my ); + } + + gui->getVertRuler()->setOffset( 0, -getVertRulerPos() ); + + if ( fc->getParag() ) + { + gui->getView()->updateStyle( fc->getParag()->getParagLayout()->getName(), FALSE ); + gui->getView()->setFormat( *( ( KWFormat* )fc ), TRUE, FALSE ); + gui->getView()->setFlow( fc->getParag()->getParagLayout()->getFlow() ); + gui->getView()->setLineSpacing( fc->getParag()->getParagLayout()->getLineSpacing().pt() ); + gui->getView()->setParagBorders( fc->getParag()->getParagLayout()->getLeftBorder(), + fc->getParag()->getParagLayout()->getRightBorder(), + fc->getParag()->getParagLayout()->getTopBorder(), + fc->getParag()->getParagLayout()->getBottomBorder() ); + setRulerFirstIndent( gui->getHorzRuler(), fc->getParag()->getParagLayout()->getFirstLineLeftIndent() ); + setRulerLeftIndent( gui->getHorzRuler(), fc->getParag()->getParagLayout()->getLeftIndent() ); + gui->getHorzRuler()->setFrameStart( doc->getFrameSet( fc->getFrameSet() - 1 )-> + getFrame( fc->getFrame() - 1 )->x() ); + gui->getHorzRuler()->setTabList( fc->getParag()->getParagLayout()->getTabList() ); + } return; } - // other keys modified by ControlButton else if ( e->state() & ControlButton ) { if ( e->key() == Key_B ) { @@ -2948,7 +3052,6 @@ void KWPage::keyPressEvent( QKeyEvent *e } } - unsigned int oldPage = fc->getPage(); unsigned int oldFrame = fc->getFrame(); KWParag* oldParag = fc->getParag(); @@ -2961,17 +3064,17 @@ void KWPage::keyPressEvent( QKeyEvent *e switch( e->key() ) { case Key_Prior: // PageUp - { + { if ( !kPrior( e, oldPage, oldFrame, oldParag, frameSet ) ) STOP; break; - } + } case Key_Next: // PageDown - { + { if ( !kNext( e, oldPage, oldFrame, oldParag, frameSet ) ) - STOP; + STOP; break; - } + } case Key_Home: if ( !kHome( e, oldPage, oldFrame, oldParag, frameSet ) ) STOP; @@ -3405,8 +3508,8 @@ void KWPage::frameSizeChanged( KoPageLay } /*================================================================*/ -/* this method is depricated, use - void KWPage::setRuler2Frame( KWFrame *frame) instead +/* this method is depricated, use + void KWPage::setRuler2Frame( KWFrame *frame) instead */ void KWPage::setRuler2Frame( unsigned int _frameset, unsigned int _frame ) { setRuler2Frame (doc->getFrameSet( _frameset )->getFrame( _frame )); @@ -4287,7 +4390,6 @@ void KWPage::setBottomFrameBorder( KWPar doc->updateAllViews( 0L ); } - /*================================================================*/ void KWPage::setFrameBorderColor( const QColor &_color ) { @@ -4925,7 +5027,6 @@ void KWPage::showCursor( bool visible ) p.end(); } - void KWPage::keyReleaseEvent( QKeyEvent * ) { startBlinkCursor(); @@ -5512,4 +5613,3 @@ void KWResizeHandle::updateGeometry() KWPage *KWResizeHandle::getPage() { return page; } - --------------B5EBACE066B276D13EF4D325--