Kate
kateview.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2009 Michel Ludwig <michel.ludwig@kdemail.net> 00003 Copyright (C) 2007 Mirko Stocker <me@misto.ch> 00004 Copyright (C) 2003 Hamish Rodda <rodda@kde.org> 00005 Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org> 00006 Copyright (C) 2001-2004 Christoph Cullmann <cullmann@kde.org> 00007 Copyright (C) 2001-2010 Joseph Wenninger <jowenn@kde.org> 00008 Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de> 00009 00010 This library is free software; you can redistribute it and/or 00011 modify it under the terms of the GNU Library General Public 00012 License version 2 as published by the Free Software Foundation. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Library General Public License for more details. 00018 00019 You should have received a copy of the GNU Library General Public License 00020 along with this library; see the file COPYING.LIB. If not, write to 00021 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00022 Boston, MA 02110-1301, USA. 00023 */ 00024 00025 //BEGIN includes 00026 #include "kateview.h" 00027 #include "kateview.moc" 00028 00029 #include "kateviewinternal.h" 00030 #include "kateviewhelpers.h" 00031 #include "katerenderer.h" 00032 #include "katedocument.h" 00033 #include "kateundomanager.h" 00034 #include "katedocumenthelpers.h" 00035 #include "kateglobal.h" 00036 #include "kateviglobal.h" 00037 #include "katehighlight.h" 00038 #include "katehighlightmenu.h" 00039 #include "katedialogs.h" 00040 #include "katetextline.h" 00041 #include "katecodefolding.h" 00042 #include "kateschema.h" 00043 #include "katebookmarks.h" 00044 #include "kateconfig.h" 00045 #include "katemodemenu.h" 00046 #include "kateautoindent.h" 00047 #include "katecompletionwidget.h" 00048 #include "katesearchbar.h" 00049 #include "katevimodebar.h" 00050 #include "katepartpluginmanager.h" 00051 #include "katewordcompletion.h" 00052 #include "katelayoutcache.h" 00053 #include "spellcheck/spellcheck.h" 00054 #include "spellcheck/spellcheckdialog.h" 00055 #include "spellcheck/spellingmenu.h" 00056 #include "katebuffer.h" 00057 #include "script/katescriptmanager.h" 00058 #include "script/katescriptaction.h" 00059 #include "kateswapfile.h" 00060 #include "katerecoverbar.h" 00061 #include "katebrokenswapfilebar.h" 00062 00063 #include <kparts/event.h> 00064 00065 #include <kconfig.h> 00066 #include <kdebug.h> 00067 #include <kapplication.h> 00068 #include <kcursor.h> 00069 #include <kicon.h> 00070 #include <klocale.h> 00071 #include <kglobal.h> 00072 #include <kcharsets.h> 00073 #include <kmessagebox.h> 00074 #include <kaction.h> 00075 #include <kstandardaction.h> 00076 #include <kxmlguifactory.h> 00077 #include <kxmlguiclient.h> 00078 #include <kencodingfiledialog.h> 00079 #include <kstandardshortcut.h> 00080 #include <kmenu.h> 00081 #include <ktoggleaction.h> 00082 #include <kselectaction.h> 00083 #include <kactioncollection.h> 00084 #include <kdeversion.h> 00085 00086 #include <QtGui/QFont> 00087 #include <QtCore/QFileInfo> 00088 #include <QtGui/QStyle> 00089 #include <QtGui/QKeyEvent> 00090 #include <QtGui/QLayout> 00091 #include <QtCore/QMimeData> 00092 00093 //#define VIEW_RANGE_DEBUG 00094 00095 //END includes 00096 00097 void KateView::blockFix(KTextEditor::Range& range) 00098 { 00099 if (range.start().column() > range.end().column()) 00100 { 00101 int tmp = range.start().column(); 00102 range.start().setColumn(range.end().column()); 00103 range.end().setColumn(tmp); 00104 } 00105 } 00106 00107 KateView::KateView( KateDocument *doc, QWidget *parent ) 00108 : KTextEditor::View( parent ) 00109 , m_completionWidget(0) 00110 , m_annotationModel(0) 00111 , m_hasWrap( false ) 00112 , m_doc( doc ) 00113 , m_config( new KateViewConfig( this ) ) 00114 , m_renderer( new KateRenderer( doc, this ) ) 00115 , m_viewInternal( new KateViewInternal( this ) ) 00116 , m_spell( new KateSpellCheckDialog( this ) ) 00117 , m_bookmarks( new KateBookmarks( this ) ) 00118 , m_startingUp (true) 00119 , m_updatingDocumentConfig (false) 00120 , m_selection (m_doc->buffer(), KTextEditor::Range::invalid(), Kate::TextRange::ExpandRight, Kate::TextRange::AllowEmpty) 00121 , blockSelect (false) 00122 , m_bottomViewBar (0) 00123 , m_topViewBar (0) 00124 , m_recoverBar(0) 00125 , m_brokenSwapFileBar(0) 00126 , m_cmdLine (0) 00127 , m_searchBar (0) 00128 , m_viModeBar (0) 00129 , m_gotoBar (0) 00130 , m_dictionaryBar(NULL) 00131 , m_spellingMenu( new KateSpellingMenu( this ) ) 00132 , m_userContextMenuSet( false ) 00133 , m_delayedUpdateTriggered (false) 00134 , m_lineToUpdateMin (-1) 00135 , m_lineToUpdateMax (-1) 00136 { 00137 // queued connect to collapse view updates for range changes, INIT THIS EARLY ENOUGH! 00138 connect(this, SIGNAL(delayedUpdateOfView ()), this, SLOT(slotDelayedUpdateOfView ()), Qt::QueuedConnection); 00139 00140 setComponentData ( KateGlobal::self()->componentData () ); 00141 00142 // selection if for this view only and will invalidate if becoming empty 00143 m_selection.setView (this); 00144 00145 // use z depth defined in moving ranges interface 00146 m_selection.setZDepth (-100000.0); 00147 00148 KateGlobal::self()->registerView( this ); 00149 00150 KTextEditor::ViewBarContainer *viewBarContainer=qobject_cast<KTextEditor::ViewBarContainer*>( KateGlobal::self()->container() ); 00151 QWidget *bottomBarParent=viewBarContainer?viewBarContainer->getViewBarParent(this,KTextEditor::ViewBarContainer::BottomBar):0; 00152 QWidget *topBarParent=viewBarContainer?viewBarContainer->getViewBarParent(this,KTextEditor::ViewBarContainer::TopBar):0; 00153 00154 m_bottomViewBar=new KateViewBar (bottomBarParent!=0,KTextEditor::ViewBarContainer::BottomBar,bottomBarParent?bottomBarParent:this,this); 00155 m_topViewBar=new KateViewBar (topBarParent!=0,KTextEditor::ViewBarContainer::TopBar,topBarParent?topBarParent:this,this); 00156 00157 // ugly workaround: 00158 // Force the layout to be left-to-right even on RTL deskstop, as discussed 00159 // on the mailing list. This will cause the lines and icons panel to be on 00160 // the left, even for Arabic/Hebrew/Farsi/whatever users. 00161 setLayoutDirection ( Qt::LeftToRight ); 00162 00163 // layouting ;) 00164 m_vBox = new QVBoxLayout (this); 00165 m_vBox->setMargin (0); 00166 m_vBox->setSpacing (0); 00167 00168 // add top viewbar... 00169 if (topBarParent) 00170 viewBarContainer->addViewBarToLayout(this,m_topViewBar,KTextEditor::ViewBarContainer::TopBar); 00171 else 00172 m_vBox->addWidget(m_topViewBar); 00173 00174 m_bottomViewBar->installEventFilter(m_viewInternal); 00175 00176 QHBoxLayout *hbox = new QHBoxLayout (); 00177 m_vBox->addLayout (hbox, 100); 00178 hbox->setMargin (0); 00179 hbox->setSpacing (0); 00180 00181 QStyleOption option; 00182 option.initFrom(this); 00183 00184 if (style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &option, this)) { 00185 QHBoxLayout *extrahbox = new QHBoxLayout (); 00186 QFrame * frame = new QFrame(this); 00187 extrahbox->setMargin (0); 00188 extrahbox->setSpacing (0); 00189 extrahbox->addWidget (m_viewInternal->m_leftBorder); 00190 extrahbox->addWidget (m_viewInternal); 00191 frame->setLayout (extrahbox); 00192 hbox->addWidget (frame); 00193 hbox->addSpacing (style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &option, this)); 00194 frame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); 00195 } 00196 else { 00197 hbox->addWidget (m_viewInternal->m_leftBorder); 00198 hbox->addWidget (m_viewInternal); 00199 } 00200 hbox->addWidget (m_viewInternal->m_lineScroll); 00201 00202 if (style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &option, this)) { 00203 m_vBox->addSpacing (style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &option, this)); 00204 } 00205 00206 hbox = new QHBoxLayout (); 00207 m_vBox->addLayout (hbox); 00208 hbox->setMargin (0); 00209 hbox->setSpacing (0); 00210 00211 hbox->addWidget (m_viewInternal->m_columnScroll); 00212 hbox->addWidget (m_viewInternal->m_dummy); 00213 00214 // add viewbar... 00215 if (bottomBarParent) 00216 viewBarContainer->addViewBarToLayout(this,m_bottomViewBar,KTextEditor::ViewBarContainer::BottomBar); 00217 else 00218 m_vBox->addWidget(m_bottomViewBar); 00219 00220 // this really is needed :) 00221 m_viewInternal->updateView (); 00222 00223 doc->addView( this ); 00224 00225 setFocusProxy( m_viewInternal ); 00226 setFocusPolicy( Qt::StrongFocus ); 00227 00228 // default ui file with all features 00229 QString uifile = "katepartui.rc"; 00230 00231 // simple mode 00232 if (doc->simpleMode ()) 00233 uifile = "katepartsimpleui.rc"; 00234 00235 setXMLFile( uifile ); 00236 00237 setupConnections(); 00238 setupActions(); 00239 00240 // auto word completion 00241 new KateWordCompletionView (this, actionCollection ()); 00242 00243 // enable the plugins of this view 00244 KatePartPluginManager::self()->addView(this); 00245 00246 // update the enabled state of the undo/redo actions... 00247 slotUpdateUndo(); 00248 00249 m_startingUp = false; 00250 updateConfig (); 00251 00252 slotHlChanged(); 00253 KCursor::setAutoHideCursor( m_viewInternal, true ); 00254 00255 if ( viInputMode() && !config()->viInputModeHideStatusBar() ) { 00256 deactivateEditActions(); 00257 showViModeBar(); 00258 } 00259 00260 // swap file handling 00261 connect (doc->swapFile(), SIGNAL(swapFileBroken()), this, SLOT(showBrokenSwapFileBar())); 00262 connect (doc->swapFile(), SIGNAL(swapFileFound()), this, SLOT(showRecoverBar())); 00263 connect (doc->swapFile(), SIGNAL(swapFileHandled()), this, SLOT(hideRecoverBar())); 00264 if (doc->swapFile()->shouldRecover()) 00265 showRecoverBar(); 00266 00267 } 00268 00269 KateView::~KateView() 00270 { 00271 // invalidate update signal 00272 m_delayedUpdateTriggered = false; 00273 00274 KTextEditor::ViewBarContainer *viewBarContainer=qobject_cast<KTextEditor::ViewBarContainer*>( KateGlobal::self()->container() ); 00275 if (viewBarContainer) { 00276 viewBarContainer->deleteViewBarForView(this,KTextEditor::ViewBarContainer::BottomBar); 00277 m_bottomViewBar=0; 00278 viewBarContainer->deleteViewBarForView(this,KTextEditor::ViewBarContainer::TopBar); 00279 m_topViewBar=0; 00280 } 00281 00282 KatePartPluginManager::self()->removeView(this); 00283 00284 m_doc->removeView( this ); 00285 00286 delete m_viewInternal; 00287 00288 delete m_renderer; 00289 00290 delete m_config; 00291 00292 KateGlobal::self()->deregisterView (this); 00293 } 00294 00295 void KateView::setupConnections() 00296 { 00297 connect( m_doc, SIGNAL(undoChanged()), 00298 this, SLOT(slotUpdateUndo()) ); 00299 connect( m_doc, SIGNAL(highlightingModeChanged(KTextEditor::Document *)), 00300 this, SLOT(slotHlChanged()) ); 00301 connect( m_doc, SIGNAL(canceled(const QString&)), 00302 this, SLOT(slotSaveCanceled(const QString&)) ); 00303 connect( m_viewInternal, SIGNAL(dropEventPass(QDropEvent*)), 00304 this, SIGNAL(dropEventPass(QDropEvent*)) ); 00305 00306 connect( m_doc, SIGNAL(annotationModelChanged( KTextEditor::AnnotationModel*, KTextEditor::AnnotationModel* )), 00307 m_viewInternal->m_leftBorder, SLOT(annotationModelChanged( KTextEditor::AnnotationModel*, KTextEditor::AnnotationModel* )) ); 00308 00309 if ( m_doc->browserView() ) 00310 { 00311 connect( this, SIGNAL(dropEventPass(QDropEvent*)), 00312 this, SLOT(slotDropEventPass(QDropEvent*)) ); 00313 } 00314 } 00315 00316 void KateView::setupActions() 00317 { 00318 KActionCollection *ac = actionCollection (); 00319 KAction *a; 00320 00321 m_toggleWriteLock = 0; 00322 00323 m_cut = a = ac->addAction(KStandardAction::Cut, this, SLOT(cut())); 00324 a->setWhatsThis(i18n("Cut the selected text and move it to the clipboard")); 00325 00326 m_paste = a = ac->addAction(KStandardAction::PasteText, this, SLOT(paste())); 00327 a->setWhatsThis(i18n("Paste previously copied or cut clipboard contents")); 00328 00329 m_copy = a = ac->addAction(KStandardAction::Copy, this, SLOT(copy())); 00330 a->setWhatsThis(i18n( "Use this command to copy the currently selected text to the system clipboard.")); 00331 00332 if (!m_doc->readOnly()) 00333 { 00334 a = ac->addAction(KStandardAction::Save, m_doc, SLOT(documentSave())); 00335 a->setWhatsThis(i18n("Save the current document")); 00336 00337 a = m_editUndo = ac->addAction(KStandardAction::Undo, m_doc, SLOT(undo())); 00338 a->setWhatsThis(i18n("Revert the most recent editing actions")); 00339 00340 a = m_editRedo = ac->addAction(KStandardAction::Redo, m_doc, SLOT(redo())); 00341 a->setWhatsThis(i18n("Revert the most recent undo operation")); 00342 00343 // Tools > Scripts 00344 KateScriptActionMenu* scriptActionMenu = new KateScriptActionMenu(this, i18n("&Scripts")); 00345 ac->addAction("tools_scripts", scriptActionMenu); 00346 00347 00348 a = ac->addAction("tools_apply_wordwrap"); 00349 a->setText(i18n("Apply &Word Wrap")); 00350 a->setWhatsThis(i18n("Use this command to wrap all lines of the current document which are longer than the width of the" 00351 " current view, to fit into this view.<br /><br /> This is a static word wrap, meaning it is not updated" 00352 " when the view is resized.")); 00353 connect(a, SIGNAL(triggered(bool)), SLOT(applyWordWrap())); 00354 00355 a = ac->addAction("tools_cleanIndent"); 00356 a->setText(i18n("&Clean Indentation")); 00357 a->setWhatsThis(i18n("Use this to clean the indentation of a selected block of text (only tabs/only spaces).<br /><br />" 00358 "You can configure whether tabs should be honored and used or replaced with spaces, in the configuration dialog.")); 00359 connect(a, SIGNAL(triggered(bool)), SLOT(cleanIndent())); 00360 00361 a = ac->addAction("tools_align"); 00362 a->setText(i18n("&Align")); 00363 a->setWhatsThis(i18n("Use this to align the current line or block of text to its proper indent level.")); 00364 connect(a, SIGNAL(triggered(bool)), SLOT(align())); 00365 00366 a = ac->addAction("tools_comment"); 00367 a->setText(i18n("C&omment")); 00368 a->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_D)); 00369 a->setWhatsThis(i18n("This command comments out the current line or a selected block of text.<br /><br />" 00370 "The characters for single/multiple line comments are defined within the language's highlighting.")); 00371 connect(a, SIGNAL(triggered(bool)), SLOT(comment())); 00372 00373 a = ac->addAction("tools_uncomment"); 00374 a->setText(i18n("Unco&mment")); 00375 a->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_D)); 00376 a->setWhatsThis(i18n("This command removes comments from the current line or a selected block of text.<br /><br />" 00377 "The characters for single/multiple line comments are defined within the language's highlighting.")); 00378 connect(a, SIGNAL(triggered(bool)), SLOT(uncomment())); 00379 00380 a = ac->addAction("tools_toggle_comment"); 00381 a->setText(i18n("Toggle Comment")); 00382 connect(a, SIGNAL(triggered(bool)), SLOT(toggleComment())); 00383 00384 a = m_toggleWriteLock = new KToggleAction(i18n("&Read Only Mode"), this); 00385 a->setWhatsThis( i18n("Lock/unlock the document for writing") ); 00386 a->setChecked( !m_doc->isReadWrite() ); 00387 connect(a, SIGNAL(triggered(bool)), SLOT( toggleWriteLock() )); 00388 ac->addAction("tools_toggle_write_lock", a); 00389 00390 a = ac->addAction("tools_uppercase"); 00391 a->setText(i18n("Uppercase")); 00392 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U)); 00393 a->setWhatsThis( i18n("Convert the selection to uppercase, or the character to the " 00394 "right of the cursor if no text is selected.") ); 00395 connect(a, SIGNAL(triggered(bool)), SLOT(uppercase())); 00396 00397 a = ac->addAction( "tools_lowercase" ); 00398 a->setText( i18n("Lowercase") ); 00399 a->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_U)); 00400 a->setWhatsThis( i18n("Convert the selection to lowercase, or the character to the " 00401 "right of the cursor if no text is selected.") ); 00402 connect(a, SIGNAL(triggered(bool)), SLOT(lowercase())); 00403 00404 a = ac->addAction( "tools_capitalize" ); 00405 a->setText( i18n("Capitalize") ); 00406 a->setShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_U)); 00407 a->setWhatsThis( i18n("Capitalize the selection, or the word under the " 00408 "cursor if no text is selected.") ); 00409 connect(a, SIGNAL(triggered(bool)), SLOT(capitalize())); 00410 00411 a = ac->addAction( "tools_join_lines" ); 00412 a->setText( i18n("Join Lines") ); 00413 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_J)); 00414 connect(a, SIGNAL(triggered(bool)), SLOT( joinLines() )); 00415 00416 a = ac->addAction( "tools_invoke_code_completion" ); 00417 a->setText( i18n("Invoke Code Completion") ); 00418 a->setWhatsThis(i18n("Manually invoke command completion, usually by using a shortcut bound to this action.")); 00419 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Space)); 00420 connect(a, SIGNAL(triggered(bool)), SLOT(userInvokedCompletion())); 00421 } 00422 else 00423 { 00424 m_cut->setEnabled (false); 00425 m_paste->setEnabled (false); 00426 m_editUndo = 0; 00427 m_editRedo = 0; 00428 } 00429 00430 a = ac->addAction( KStandardAction::Print, m_doc, SLOT(print()) ); 00431 a->setWhatsThis(i18n("Print the current document.")); 00432 00433 a = ac->addAction( "file_reload" ); 00434 a->setIcon(KIcon("view-refresh")); 00435 a->setText(i18n("Reloa&d")); 00436 a->setShortcuts(KStandardShortcut::reload()); 00437 a->setWhatsThis(i18n("Reload the current document from disk.")); 00438 connect(a, SIGNAL(triggered(bool)), SLOT(reloadFile())); 00439 00440 a = ac->addAction( KStandardAction::SaveAs, m_doc, SLOT(documentSaveAs()) ); 00441 a->setWhatsThis(i18n("Save the current document to disk, with a name of your choice.")); 00442 00443 a = ac->addAction( KStandardAction::GotoLine, this, SLOT(gotoLine()) ); 00444 a->setWhatsThis(i18n("This command opens a dialog and lets you choose a line that you want the cursor to move to.")); 00445 00446 a = ac->addAction("set_confdlg"); 00447 a->setText(i18n("&Configure Editor...")); 00448 a->setWhatsThis(i18n("Configure various aspects of this editor.")); 00449 connect(a, SIGNAL(triggered(bool)), SLOT(slotConfigDialog())); 00450 00451 KateModeMenu *ftm = new KateModeMenu (i18n("&Mode"), this); 00452 ac->addAction("tools_mode", ftm); 00453 ftm->setWhatsThis(i18n("Here you can choose which mode should be used for the current document. This will influence the highlighting and folding being used, for example.")); 00454 ftm->updateMenu (m_doc); 00455 00456 KateHighlightingMenu *menu = new KateHighlightingMenu (i18n("&Highlighting"), this); 00457 ac->addAction("tools_highlighting", menu); 00458 menu->setWhatsThis(i18n("Here you can choose how the current document should be highlighted.")); 00459 menu->updateMenu (m_doc); 00460 00461 KateViewSchemaAction *schemaMenu = new KateViewSchemaAction (i18n("&Schema"), this); 00462 ac->addAction("view_schemas", schemaMenu); 00463 schemaMenu->updateMenu (this); 00464 00465 // indentation menu 00466 KateViewIndentationAction *indentMenu = new KateViewIndentationAction(m_doc, i18n("&Indentation"), this); 00467 ac->addAction("tools_indentation", indentMenu); 00468 00469 m_selectAll = a= ac->addAction( KStandardAction::SelectAll, this, SLOT(selectAll()) ); 00470 a->setWhatsThis(i18n("Select the entire text of the current document.")); 00471 00472 m_deSelect = a= ac->addAction( KStandardAction::Deselect, this, SLOT(clearSelection()) ); 00473 a->setWhatsThis(i18n("If you have selected something within the current document, this will no longer be selected.")); 00474 00475 a = ac->addAction("view_inc_font_sizes"); 00476 a->setIcon(KIcon("zoom-in")); 00477 a->setText(i18n("Enlarge Font")); 00478 a->setWhatsThis(i18n("This increases the display font size.")); 00479 connect(a, SIGNAL(triggered(bool)), m_viewInternal, SLOT(slotIncFontSizes())); 00480 00481 a = ac->addAction("view_dec_font_sizes"); 00482 a->setIcon(KIcon("zoom-out")); 00483 a->setText(i18n("Shrink Font")); 00484 a->setWhatsThis(i18n("This decreases the display font size.")); 00485 connect(a, SIGNAL(triggered(bool)), m_viewInternal, SLOT(slotDecFontSizes())); 00486 00487 a = m_toggleBlockSelection = new KToggleAction(i18n("Bl&ock Selection Mode"), this); 00488 ac->addAction("set_verticalSelect", a); 00489 a->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B)); 00490 a->setWhatsThis(i18n("This command allows switching between the normal (line based) selection mode and the block selection mode.")); 00491 connect(a, SIGNAL(triggered(bool)), SLOT(toggleBlockSelectionMode())); 00492 00493 a = m_toggleInsert = new KToggleAction(i18n("Overwr&ite Mode"), this); 00494 ac->addAction("set_insert", a); 00495 a->setShortcut(QKeySequence(Qt::Key_Insert)); 00496 a->setWhatsThis(i18n("Choose whether you want the text you type to be inserted or to overwrite existing text.")); 00497 connect(a, SIGNAL(triggered(bool)), SLOT(toggleInsert())); 00498 00499 KToggleAction *toggleAction; 00500 a = m_toggleDynWrap = toggleAction = new KToggleAction(i18n("&Dynamic Word Wrap"), this); 00501 ac->addAction("view_dynamic_word_wrap", a); 00502 a->setShortcut(QKeySequence(Qt::Key_F10)); 00503 a->setWhatsThis(i18n("If this option is checked, the text lines will be wrapped at the view border on the screen.")); 00504 connect(a, SIGNAL(triggered(bool)), SLOT(toggleDynWordWrap())); 00505 00506 a = m_setDynWrapIndicators = new KSelectAction(i18n("Dynamic Word Wrap Indicators"), this); 00507 ac->addAction("dynamic_word_wrap_indicators", a); 00508 a->setWhatsThis(i18n("Choose when the Dynamic Word Wrap Indicators should be displayed")); 00509 00510 connect(m_setDynWrapIndicators, SIGNAL(triggered(int)), this, SLOT(setDynWrapIndicators(int))); 00511 QStringList list2; 00512 list2.append(i18n("&Off")); 00513 list2.append(i18n("Follow &Line Numbers")); 00514 list2.append(i18n("&Always On")); 00515 m_setDynWrapIndicators->setItems(list2); 00516 m_setDynWrapIndicators->setEnabled(m_toggleDynWrap->isChecked()); // only synced on real change, later 00517 00518 a = toggleAction = m_toggleFoldingMarkers = new KToggleAction(i18n("Show Folding &Markers"), this); 00519 ac->addAction("view_folding_markers", a); 00520 a->setShortcut(QKeySequence(Qt::Key_F9)); 00521 a->setWhatsThis(i18n("You can choose if the codefolding marks should be shown, if codefolding is possible.")); 00522 connect(a, SIGNAL(triggered(bool)), SLOT(toggleFoldingMarkers())); 00523 00524 a = m_toggleIconBar = toggleAction = new KToggleAction(i18n("Show &Icon Border"), this); 00525 ac->addAction("view_border", a); 00526 a->setShortcut(QKeySequence(Qt::Key_F6)); 00527 a->setWhatsThis(i18n("Show/hide the icon border.<br /><br />The icon border shows bookmark symbols, for instance.")); 00528 connect(a, SIGNAL(triggered(bool)), SLOT(toggleIconBorder())); 00529 00530 a = toggleAction = m_toggleLineNumbers = new KToggleAction(i18n("Show &Line Numbers"), this); 00531 ac->addAction("view_line_numbers", a); 00532 a->setShortcut(QKeySequence(Qt::Key_F11)); 00533 a->setWhatsThis(i18n("Show/hide the line numbers on the left hand side of the view.")); 00534 connect(a, SIGNAL(triggered(bool)), SLOT(toggleLineNumbersOn())); 00535 00536 a = m_toggleScrollBarMarks = toggleAction = new KToggleAction(i18n("Show Scroll&bar Marks"), this); 00537 ac->addAction("view_scrollbar_marks", a); 00538 a->setWhatsThis(i18n("Show/hide the marks on the vertical scrollbar.<br /><br />The marks show bookmarks, for instance.")); 00539 connect(a, SIGNAL(triggered(bool)), SLOT(toggleScrollBarMarks())); 00540 00541 a = toggleAction = m_toggleWWMarker = new KToggleAction(i18n("Show Static &Word Wrap Marker"), this); 00542 ac->addAction("view_word_wrap_marker", a); 00543 a->setWhatsThis( i18n( 00544 "Show/hide the Word Wrap Marker, a vertical line drawn at the word " 00545 "wrap column as defined in the editing properties" )); 00546 connect(a, SIGNAL(triggered(bool)), SLOT( toggleWWMarker() )); 00547 00548 a = m_switchCmdLine = ac->addAction("switch_to_cmd_line"); 00549 a->setText(i18n("Switch to Command Line")); 00550 a->setShortcut(QKeySequence(Qt::Key_F7)); 00551 a->setWhatsThis(i18n("Show/hide the command line on the bottom of the view.")); 00552 connect(a, SIGNAL(triggered(bool)), SLOT(switchToCmdLine())); 00553 00554 a = m_viInputModeAction = new KToggleAction(i18n("&VI Input Mode"), this); 00555 ac->addAction("view_vi_input_mode", a); 00556 a->setShortcut(QKeySequence(Qt::CTRL + Qt::META + Qt::Key_V)); 00557 a->setWhatsThis( i18n("Activate/deactivate VI input mode" )); 00558 connect(a, SIGNAL(triggered(bool)), SLOT( toggleViInputMode() )); 00559 00560 a = m_setEndOfLine = new KSelectAction(i18n("&End of Line"), this); 00561 ac->addAction("set_eol", a); 00562 a->setWhatsThis(i18n("Choose which line endings should be used, when you save the document")); 00563 QStringList list; 00564 list.append("&UNIX"); 00565 list.append("&Windows/DOS"); 00566 list.append("&Macintosh"); 00567 m_setEndOfLine->setItems(list); 00568 m_setEndOfLine->setCurrentItem (m_doc->config()->eol()); 00569 connect(m_setEndOfLine, SIGNAL(triggered(int)), this, SLOT(setEol(int))); 00570 00571 a=m_addBom=new KToggleAction(i18n("Add &Byte Order Mark (BOM)"),this); 00572 ac->addAction("add_bom",a); 00573 a->setWhatsThis(i18n("Enable/disable adding of byte order markers for UTF-8/UTF-16 encoded files while saving")); 00574 connect(m_addBom,SIGNAL(triggered(bool)),this,SLOT(setAddBom(bool))); 00575 // encoding menu 00576 KateViewEncodingAction *encodingAction = new KateViewEncodingAction(m_doc, this, i18n("E&ncoding"), this); 00577 ac->addAction("set_encoding", encodingAction); 00578 00579 a = ac->addAction( KStandardAction::Find, this, SLOT(find()) ); 00580 a->setWhatsThis(i18n("Look up the first occurrence of a piece of text or regular expression.")); 00581 addAction(a); 00582 00583 a = ac->addAction("edit_find_selected"); 00584 a->setText(i18n("Find Selected")); 00585 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_H)); 00586 a->setWhatsThis(i18n("Finds next occurrence of selected text.")); 00587 connect(a, SIGNAL(triggered(bool)), SLOT(findSelectedForwards())); 00588 00589 a = ac->addAction("edit_find_selected_backwards"); 00590 a->setText(i18n("Find Selected Backwards")); 00591 a->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_H)); 00592 a->setWhatsThis(i18n("Finds previous occurrence of selected text.")); 00593 connect(a, SIGNAL(triggered(bool)), SLOT(findSelectedBackwards())); 00594 00595 a = ac->addAction( KStandardAction::FindNext, this, SLOT(findNext()) ); 00596 a->setWhatsThis(i18n("Look up the next occurrence of the search phrase.")); 00597 addAction(a); 00598 00599 a = ac->addAction( KStandardAction::FindPrev, "edit_find_prev", this, SLOT(findPrevious()) ); 00600 a->setWhatsThis(i18n("Look up the previous occurrence of the search phrase.")); 00601 addAction(a); 00602 00603 a = ac->addAction( KStandardAction::Replace, this, SLOT(replace()) ); 00604 a->setWhatsThis(i18n("Look up a piece of text or regular expression and replace the result with some given text.")); 00605 00606 m_spell->createActions( ac ); 00607 m_toggleOnTheFlySpellCheck = new KToggleAction(i18n("Automatic Spell Checking"), this); 00608 m_toggleOnTheFlySpellCheck->setWhatsThis(i18n("Enable/disable automatic spell checking")); 00609 m_toggleOnTheFlySpellCheck->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_O)); 00610 connect(m_toggleOnTheFlySpellCheck, SIGNAL(triggered(bool)), SLOT(toggleOnTheFlySpellCheck(bool))); 00611 ac->addAction("tools_toggle_automatic_spell_checking", m_toggleOnTheFlySpellCheck); 00612 00613 a = ac->addAction("tools_change_dictionary"); 00614 a->setText(i18n("Change Dictionary...")); 00615 a->setWhatsThis(i18n("Change the dictionary that is used for spell checking.")); 00616 connect(a, SIGNAL(triggered()), SLOT(changeDictionary())); 00617 00618 a = ac->addAction("tools_clear_dictionary_ranges"); 00619 a->setText(i18n("Clear Dictionary Ranges")); 00620 a->setVisible(false); 00621 a->setWhatsThis(i18n("Remove all the separate dictionary ranges that were set for spell checking.")); 00622 connect(a, SIGNAL(triggered()), m_doc, SLOT(clearDictionaryRanges())); 00623 connect(m_doc, SIGNAL(dictionaryRangesPresent(bool)), a, SLOT(setVisible(bool))); 00624 00625 m_spellingMenu->createActions( ac ); 00626 00627 if (!m_doc->simpleMode ()) 00628 m_bookmarks->createActions( ac ); 00629 00630 slotSelectionChanged (); 00631 00632 //Now setup the editing actions before adding the associated 00633 //widget and setting the shortcut context 00634 setupEditActions(); 00635 setupCodeFolding(); 00636 00637 ac->addAssociatedWidget(m_viewInternal); 00638 00639 foreach (QAction* action, ac->actions()) 00640 action->setShortcutContext(Qt::WidgetWithChildrenShortcut); 00641 00642 connect (this, SIGNAL(selectionChanged(KTextEditor::View*)), this, SLOT(slotSelectionChanged())); 00643 } 00644 00645 void KateView::slotConfigDialog () 00646 { 00647 KateGlobal::self ()->configDialog (this); 00648 } 00649 00650 void KateView::setupEditActions() 00651 { 00652 //If you add an editing action to this 00653 //function make sure to include the line 00654 //m_editActions << a after creating the action 00655 KActionCollection* ac = actionCollection(); 00656 00657 KAction* a = ac->addAction("word_left"); 00658 a->setText(i18n("Move Word Left")); 00659 a->setShortcuts(KStandardShortcut::backwardWord()); 00660 connect(a, SIGNAL(triggered(bool)), SLOT(wordLeft())); 00661 m_editActions << a; 00662 00663 a = ac->addAction("select_char_left"); 00664 a->setText(i18n("Select Character Left")); 00665 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Left)); 00666 connect(a, SIGNAL(triggered(bool)), SLOT(shiftCursorLeft())); 00667 m_editActions << a; 00668 00669 a = ac->addAction("select_word_left"); 00670 a->setText(i18n("Select Word Left")); 00671 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::CTRL + Qt::Key_Left)); 00672 connect(a, SIGNAL(triggered(bool)), SLOT(shiftWordLeft())); 00673 m_editActions << a; 00674 00675 00676 a = ac->addAction("word_right"); 00677 a->setText(i18n("Move Word Right")); 00678 a->setShortcuts(KStandardShortcut::forwardWord()); 00679 connect(a, SIGNAL(triggered(bool)), SLOT(wordRight())); 00680 m_editActions << a; 00681 00682 a = ac->addAction("select_char_right"); 00683 a->setText(i18n("Select Character Right")); 00684 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Right)); 00685 connect(a, SIGNAL(triggered(bool)), SLOT(shiftCursorRight())); 00686 m_editActions << a; 00687 00688 a = ac->addAction("select_word_right"); 00689 a->setText(i18n("Select Word Right")); 00690 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::CTRL + Qt::Key_Right)); 00691 connect(a, SIGNAL(triggered(bool)), SLOT(shiftWordRight())); 00692 m_editActions << a; 00693 00694 00695 a = ac->addAction("beginning_of_line"); 00696 a->setText(i18n("Move to Beginning of Line")); 00697 a->setShortcuts(KStandardShortcut::beginningOfLine()); 00698 connect(a, SIGNAL(triggered(bool)), SLOT(home())); 00699 m_editActions << a; 00700 00701 a = ac->addAction("beginning_of_document"); 00702 a->setText(i18n("Move to Beginning of Document")); 00703 a->setShortcuts(KStandardShortcut::begin()); 00704 connect(a, SIGNAL(triggered(bool)), SLOT(top())); 00705 m_editActions << a; 00706 00707 a = ac->addAction("select_beginning_of_line"); 00708 a->setText(i18n("Select to Beginning of Line")); 00709 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Home)); 00710 connect(a, SIGNAL(triggered(bool)), SLOT(shiftHome())); 00711 m_editActions << a; 00712 00713 a = ac->addAction("select_beginning_of_document"); 00714 a->setText(i18n("Select to Beginning of Document")); 00715 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::CTRL + Qt::Key_Home)); 00716 connect(a, SIGNAL(triggered(bool)), SLOT(shiftTop())); 00717 m_editActions << a; 00718 00719 00720 a = ac->addAction("end_of_line"); 00721 a->setText(i18n("Move to End of Line")); 00722 a->setShortcuts(KStandardShortcut::endOfLine()); 00723 connect(a, SIGNAL(triggered(bool)), SLOT(end())); 00724 m_editActions << a; 00725 00726 a = ac->addAction("end_of_document"); 00727 a->setText(i18n("Move to End of Document")); 00728 a->setShortcuts(KStandardShortcut::end()); 00729 connect(a, SIGNAL(triggered(bool)), SLOT(bottom())); 00730 m_editActions << a; 00731 00732 a = ac->addAction("select_end_of_line"); 00733 a->setText(i18n("Select to End of Line")); 00734 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_End)); 00735 connect(a, SIGNAL(triggered(bool)), SLOT(shiftEnd())); 00736 m_editActions << a; 00737 00738 a = ac->addAction("select_end_of_document"); 00739 a->setText(i18n("Select to End of Document")); 00740 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::CTRL + Qt::Key_End)); 00741 connect(a, SIGNAL(triggered(bool)), SLOT(shiftBottom())); 00742 m_editActions << a; 00743 00744 00745 a = ac->addAction("select_line_up"); 00746 a->setText(i18n("Select to Previous Line")); 00747 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Up)); 00748 connect(a, SIGNAL(triggered(bool)), SLOT(shiftUp())); 00749 m_editActions << a; 00750 00751 a = ac->addAction("scroll_line_up"); 00752 a->setText(i18n("Scroll Line Up")); 00753 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up)); 00754 connect(a, SIGNAL(triggered(bool)), SLOT(scrollUp())); 00755 m_editActions << a; 00756 00757 00758 a = ac->addAction("move_line_down"); 00759 a->setText(i18n("Move to Next Line")); 00760 a->setShortcut(QKeySequence(Qt::Key_Down)); 00761 connect(a, SIGNAL(triggered(bool)), SLOT(down())); 00762 m_editActions << a; 00763 00764 00765 a = ac->addAction("move_line_up"); 00766 a->setText(i18n("Move to Previous Line")); 00767 a->setShortcut(QKeySequence(Qt::Key_Up)); 00768 connect(a, SIGNAL(triggered(bool)), SLOT(up())); 00769 m_editActions << a; 00770 00771 00772 a = ac->addAction("move_cursor_right"); 00773 a->setText(i18n("Move Cursor Right")); 00774 a->setShortcut(QKeySequence(Qt::Key_Right)); 00775 connect(a, SIGNAL(triggered(bool)), SLOT(cursorRight())); 00776 m_editActions << a; 00777 00778 00779 a = ac->addAction("move_cusor_left"); 00780 a->setText(i18n("Move Cursor Left")); 00781 a->setShortcut(QKeySequence(Qt::Key_Left)); 00782 connect(a, SIGNAL(triggered(bool)), SLOT(cursorLeft())); 00783 m_editActions << a; 00784 00785 00786 a = ac->addAction("select_line_down"); 00787 a->setText(i18n("Select to Next Line")); 00788 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Down)); 00789 connect(a, SIGNAL(triggered(bool)), SLOT(shiftDown())); 00790 m_editActions << a; 00791 00792 a = ac->addAction("scroll_line_down"); 00793 a->setText(i18n("Scroll Line Down")); 00794 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down)); 00795 connect(a, SIGNAL(triggered(bool)), SLOT(scrollDown())); 00796 m_editActions << a; 00797 00798 00799 a = ac->addAction("scroll_page_up"); 00800 a->setText(i18n("Scroll Page Up")); 00801 a->setShortcuts(KStandardShortcut::prior()); 00802 connect(a, SIGNAL(triggered(bool)), SLOT(pageUp())); 00803 m_editActions << a; 00804 00805 a = ac->addAction("select_page_up"); 00806 a->setText(i18n("Select Page Up")); 00807 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_PageUp)); 00808 connect(a, SIGNAL(triggered(bool)), SLOT(shiftPageUp())); 00809 m_editActions << a; 00810 00811 a = ac->addAction("move_top_of_view"); 00812 a->setText(i18n("Move to Top of View")); 00813 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageUp)); 00814 connect(a, SIGNAL(triggered(bool)), SLOT(topOfView())); 00815 m_editActions << a; 00816 00817 a = ac->addAction("select_top_of_view"); 00818 a->setText(i18n("Select to Top of View")); 00819 a->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_PageUp)); 00820 connect(a, SIGNAL(triggered(bool)), SLOT(shiftTopOfView())); 00821 m_editActions << a; 00822 00823 00824 a = ac->addAction("scroll_page_down"); 00825 a->setText(i18n("Scroll Page Down")); 00826 a->setShortcuts(KStandardShortcut::next()); 00827 connect(a, SIGNAL(triggered(bool)), SLOT(pageDown())); 00828 m_editActions << a; 00829 00830 a = ac->addAction("select_page_down"); 00831 a->setText(i18n("Select Page Down")); 00832 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::Key_PageDown)); 00833 connect(a, SIGNAL(triggered(bool)), SLOT(shiftPageDown())); 00834 m_editActions << a; 00835 00836 a = ac->addAction("move_bottom_of_view"); 00837 a->setText(i18n("Move to Bottom of View")); 00838 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageDown)); 00839 connect(a, SIGNAL(triggered(bool)), SLOT(bottomOfView())); 00840 m_editActions << a; 00841 00842 a = ac->addAction("select_bottom_of_view"); 00843 a->setText(i18n("Select to Bottom of View")); 00844 a->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_PageDown)); 00845 connect(a, SIGNAL(triggered(bool)), SLOT(shiftBottomOfView())); 00846 m_editActions << a; 00847 00848 a = ac->addAction("to_matching_bracket"); 00849 a->setText(i18n("Move to Matching Bracket")); 00850 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_6)); 00851 connect(a, SIGNAL(triggered(bool)), SLOT(toMatchingBracket())); 00852 m_editActions << a; 00853 00854 a = ac->addAction("select_matching_bracket"); 00855 a->setText(i18n("Select to Matching Bracket")); 00856 a->setShortcut(QKeySequence(Qt::SHIFT + Qt::CTRL + Qt::Key_6)); 00857 connect(a, SIGNAL(triggered(bool)), SLOT(shiftToMatchingBracket())); 00858 m_editActions << a; 00859 00860 00861 // anders: shortcuts doing any changes should not be created in browserextension 00862 if ( !m_doc->readOnly() ) 00863 { 00864 a = ac->addAction("transpose_char"); 00865 a->setText(i18n("Transpose Characters")); 00866 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T)); 00867 connect(a, SIGNAL(triggered(bool)), SLOT(transpose())); 00868 m_editActions << a; 00869 00870 a = ac->addAction("delete_line"); 00871 a->setText(i18n("Delete Line")); 00872 a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_K)); 00873 connect(a, SIGNAL(triggered(bool)), SLOT(killLine())); 00874 m_editActions << a; 00875 00876 a = ac->addAction("delete_word_left"); 00877 a->setText(i18n("Delete Word Left")); 00878 a->setShortcuts(KStandardShortcut::deleteWordBack()); 00879 connect(a, SIGNAL(triggered(bool)), SLOT(deleteWordLeft())); 00880 m_editActions << a; 00881 00882 a = ac->addAction("delete_word_right"); 00883 a->setText(i18n("Delete Word Right")); 00884 a->setShortcuts(KStandardShortcut::deleteWordForward()); 00885 connect(a, SIGNAL(triggered(bool)), SLOT(deleteWordRight())); 00886 m_editActions << a; 00887 00888 a = ac->addAction("delete_next_character"); 00889 a->setText(i18n("Delete Next Character")); 00890 a->setShortcut(QKeySequence(Qt::Key_Delete)); 00891 connect(a, SIGNAL(triggered(bool)), SLOT(keyDelete())); 00892 m_editActions << a; 00893 00894 a = ac->addAction("backspace"); 00895 a->setText(i18n("Backspace")); 00896 QList<QKeySequence> scuts; 00897 scuts << QKeySequence(Qt::Key_Backspace) 00898 << QKeySequence(Qt::SHIFT + Qt::Key_Backspace); 00899 a->setShortcuts(scuts); 00900 connect(a, SIGNAL(triggered(bool)), SLOT(backspace())); 00901 m_editActions << a; 00902 00903 a = ac->addAction("insert_tabulator"); 00904 a->setText(i18n("Insert Tab")); 00905 connect(a, SIGNAL(triggered(bool)), SLOT(insertTab())); 00906 m_editActions << a; 00907 00908 a = ac->addAction("smart_newline"); 00909 a->setText(i18n("Insert Smart Newline")); 00910 a->setWhatsThis(i18n("Insert newline including leading characters of the current line which are not letters or numbers.")); 00911 scuts.clear(); 00912 scuts << QKeySequence(Qt::SHIFT + Qt::Key_Return) 00913 << QKeySequence(Qt::SHIFT + Qt::Key_Enter); 00914 a->setShortcuts(scuts); 00915 connect(a, SIGNAL(triggered(bool)), SLOT(smartNewline())); 00916 m_editActions << a; 00917 00918 a = ac->addAction("tools_indent"); 00919 a->setIcon(KIcon("format-indent-more")); 00920 a->setText(i18n("&Indent")); 00921 a->setWhatsThis(i18n("Use this to indent a selected block of text.<br /><br />" 00922 "You can configure whether tabs should be honored and used or replaced with spaces, in the configuration dialog.")); 00923 a->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_I)); 00924 connect(a, SIGNAL(triggered(bool)), SLOT(indent())); 00925 00926 a = ac->addAction("tools_unindent"); 00927 a->setIcon(KIcon("format-indent-less")); 00928 a->setText(i18n("&Unindent")); 00929 a->setWhatsThis(i18n("Use this to unindent a selected block of text.")); 00930 a->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_I)); 00931 connect(a, SIGNAL(triggered(bool)), SLOT(unIndent())); 00932 } 00933 00934 if( hasFocus() ) 00935 slotGotFocus(); 00936 else 00937 slotLostFocus(); 00938 } 00939 00940 void KateView::setupCodeFolding() 00941 { 00942 KActionCollection *ac=this->actionCollection(); 00943 00944 KAction* a = ac->addAction("folding_toplevel"); 00945 a->setText(i18n("Collapse Toplevel")); 00946 a->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_Minus)); 00947 connect(a, SIGNAL(triggered(bool)), m_doc->foldingTree(), SLOT(collapseToplevelNodes())); 00948 00949 a = ac->addAction("folding_expandtoplevel"); 00950 a->setText(i18n("Expand Toplevel")); 00951 a->setShortcut(QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_Plus)); 00952 connect(a, SIGNAL(triggered(bool)), SLOT(slotExpandToplevel())); 00953 00954 a = ac->addAction("folding_collapselocal"); 00955 a->setText(i18n("Collapse One Local Level")); 00956 a->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_Minus)); 00957 connect(a, SIGNAL(triggered(bool)), SLOT(slotCollapseLocal())); 00958 00959 a = ac->addAction("folding_expandlocal"); 00960 a->setText(i18n("Expand One Local Level")); 00961 a->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_Plus)); 00962 connect(a, SIGNAL(triggered(bool)), SLOT(slotExpandLocal())); 00963 } 00964 00965 void KateView::slotExpandToplevel() 00966 { 00967 m_doc->foldingTree()->expandToplevelNodes(m_doc->lines()); 00968 } 00969 00970 void KateView::slotCollapseLocal() 00971 { 00972 int realLine = m_doc->foldingTree()->collapseOne(cursorPosition().line()); 00973 if (realLine != -1) { 00974 // TODO rodda: fix this to only set line and allow internal view to chose column 00975 // Explicitly call internal because we want this to be registered as an internal call 00976 00977 // (dh) current solution: use current virtual cursor column and map it to 00978 // the real column of the new cursor line 00979 Kate::TextLine textLine = m_doc->plainKateTextLine(realLine); 00980 if (!textLine) return; 00981 KTextEditor::Cursor cc = KTextEditor::Cursor(realLine, textLine->fromVirtualColumn(virtualCursorColumn(), m_doc->config()->tabWidth())); 00982 setCursorPositionInternal(cc, 1); 00983 } 00984 } 00985 00986 void KateView::slotExpandLocal() 00987 { 00988 m_doc->foldingTree()->expandOne(cursorPosition().line(), m_doc->lines()); 00989 } 00990 00991 QString KateView::viewMode () const 00992 { 00993 if (!m_doc->isReadWrite()) 00994 return i18n ("R/O"); 00995 00996 if (viInputMode()) { 00997 // vi mode has different notion of OVR/INS. 00998 // vi mode's status is showin in viModeBar() instead 00999 return QString(); 01000 } 01001 01002 return isOverwriteMode() ? i18n("OVR") : i18n ("INS"); 01003 } 01004 01005 void KateView::slotGotFocus() 01006 { 01007 //kDebug(13020) << "KateView::slotGotFocus"; 01008 01009 if ( !viInputMode() ) { 01010 activateEditActions(); 01011 } 01012 emit focusIn ( this ); 01013 } 01014 01015 void KateView::slotLostFocus() 01016 { 01017 //kDebug(13020) << "KateView::slotLostFocus"; 01018 01019 if ( !viInputMode() ) { 01020 deactivateEditActions(); 01021 } 01022 01023 emit focusOut ( this ); 01024 } 01025 01026 void KateView::setDynWrapIndicators(int mode) 01027 { 01028 config()->setDynWordWrapIndicators (mode); 01029 } 01030 01031 bool KateView::isOverwriteMode() const 01032 { 01033 return m_doc->config()->ovr(); 01034 } 01035 01036 void KateView::reloadFile() 01037 { 01038 // bookmarks and cursor positions are temporarily saved by the document 01039 m_doc->documentReload(); 01040 } 01041 01042 void KateView::slotReadWriteChanged () 01043 { 01044 if ( m_toggleWriteLock ) 01045 m_toggleWriteLock->setChecked( ! m_doc->isReadWrite() ); 01046 01047 m_cut->setEnabled (m_doc->isReadWrite() && (selection() || m_config->smartCopyCut())); 01048 m_paste->setEnabled (m_doc->isReadWrite()); 01049 01050 QStringList l; 01051 01052 l << "edit_replace" << "set_insert" << "tools_spelling" << "tools_indent" 01053 << "tools_unindent" << "tools_cleanIndent" << "tools_align" << "tools_comment" 01054 << "tools_uncomment" << "tools_toggle_comment" << "tools_uppercase" << "tools_lowercase" 01055 << "tools_capitalize" << "tools_join_lines" << "tools_apply_wordwrap" 01056 << "tools_spelling_from_cursor" 01057 << "tools_spelling_selection"; 01058 01059 QAction *a = 0; 01060 for (int z = 0; z < l.size(); z++) 01061 if ((a = actionCollection()->action( l[z].toAscii().constData() ))) 01062 a->setEnabled (m_doc->isReadWrite()); 01063 slotUpdateUndo(); 01064 } 01065 01066 void KateView::slotUpdateUndo() 01067 { 01068 if (m_doc->readOnly()) 01069 return; 01070 01071 m_editUndo->setEnabled(m_doc->isReadWrite() && m_doc->undoCount() > 0); 01072 m_editRedo->setEnabled(m_doc->isReadWrite() && m_doc->redoCount() > 0); 01073 } 01074 01075 void KateView::slotDropEventPass( QDropEvent * ev ) 01076 { 01077 const KUrl::List lstDragURLs=KUrl::List::fromMimeData(ev->mimeData()); 01078 bool ok = !lstDragURLs.isEmpty(); 01079 01080 KParts::BrowserExtension * ext = KParts::BrowserExtension::childObject( doc() ); 01081 if ( ok && ext ) 01082 emit ext->openUrlRequest( lstDragURLs.first() ); 01083 } 01084 01085 void KateView::contextMenuEvent( QContextMenuEvent *ev ) 01086 { 01087 if ( !m_doc || !m_doc->browserExtension() ) 01088 return; 01089 KParts::OpenUrlArguments args; 01090 args.setMimeType( QLatin1String("text/plain") ); 01091 emit m_doc->browserExtension()->popupMenu( ev->globalPos(), m_doc->url(), S_IFREG, args ); 01092 ev->accept(); 01093 } 01094 01095 bool KateView::setCursorPositionInternal( const KTextEditor::Cursor& position, uint tabwidth, bool calledExternally ) 01096 { 01097 Kate::TextLine l = m_doc->kateTextLine( position.line() ); 01098 01099 if (!l) 01100 return false; 01101 01102 QString line_str = m_doc->line( position.line() ); 01103 01104 int x = 0; 01105 int z = 0; 01106 for (; z < line_str.length() && z < position.column(); z++) { 01107 if (line_str[z] == QChar('\t')) x += tabwidth - (x % tabwidth); else x++; 01108 } 01109 01110 if (blockSelectionMode()) 01111 if (z < position.column()) 01112 x += position.column() - z; 01113 01114 m_viewInternal->updateCursor( KTextEditor::Cursor(position.line(), x), false, true, calledExternally ); 01115 01116 return true; 01117 } 01118 01119 void KateView::toggleInsert() 01120 { 01121 m_doc->config()->setOvr(!m_doc->config()->ovr()); 01122 m_toggleInsert->setChecked (isOverwriteMode ()); 01123 01124 emit viewModeChanged(this); 01125 emit viewEditModeChanged(this,viewEditMode()); 01126 } 01127 01128 void KateView::slotSaveCanceled( const QString& error ) 01129 { 01130 if ( !error.isEmpty() ) // happens when canceling a job 01131 KMessageBox::error( this, error ); 01132 } 01133 01134 void KateView::gotoLine() 01135 { 01136 gotoBar()->updateData(); 01137 bottomViewBar()->showBarWidget(gotoBar()); 01138 } 01139 01140 void KateView::changeDictionary() 01141 { 01142 dictionaryBar()->updateData(); 01143 bottomViewBar()->showBarWidget(dictionaryBar()); 01144 } 01145 01146 void KateView::joinLines() 01147 { 01148 int first = selectionRange().start().line(); 01149 int last = selectionRange().end().line(); 01150 //int left = m_doc->line( last ).length() - m_doc->selEndCol(); 01151 if ( first == last ) 01152 { 01153 first = cursorPosition().line(); 01154 last = first + 1; 01155 } 01156 m_doc->joinLines( first, last ); 01157 } 01158 01159 void KateView::readSessionConfig(const KConfigGroup& config) 01160 { 01161 setCursorPositionInternal(KTextEditor::Cursor(config.readEntry("CursorLine",0), config.readEntry("CursorColumn",0))); 01162 01163 // save vi registers if there are registers with contents 01164 if ( KateGlobal::self()->viInputModeGlobal()->getRegisters()->size() > 0 ) { 01165 getViInputModeManager()->readSessionConfig( config ); 01166 } 01167 } 01168 01169 void KateView::writeSessionConfig(KConfigGroup& config) 01170 { 01171 config.writeEntry("CursorLine",m_viewInternal->m_cursor.line()); 01172 config.writeEntry("CursorColumn",m_viewInternal->m_cursor.column()); 01173 01174 // save vi registers if there are registers with contents 01175 if ( KateGlobal::self()->viInputModeGlobal()->getRegisters()->size() > 0 ) { 01176 getViInputModeManager()->writeSessionConfig( config ); 01177 } 01178 } 01179 01180 int KateView::getEol() const 01181 { 01182 return m_doc->config()->eol(); 01183 } 01184 01185 void KateView::setEol(int eol) 01186 { 01187 if (!doc()->isReadWrite()) 01188 return; 01189 01190 if (m_updatingDocumentConfig) 01191 return; 01192 01193 m_doc->config()->setEol (eol); 01194 } 01195 01196 void KateView::setAddBom(bool enabled) 01197 { 01198 if (!doc()->isReadWrite()) 01199 return; 01200 01201 if (m_updatingDocumentConfig) 01202 return; 01203 01204 m_doc->config()->setBom (enabled); 01205 m_doc->bomSetByUser(); 01206 } 01207 01208 void KateView::setIconBorder( bool enable ) 01209 { 01210 config()->setIconBar (enable); 01211 } 01212 01213 void KateView::toggleIconBorder() 01214 { 01215 config()->setIconBar (!config()->iconBar()); 01216 } 01217 01218 void KateView::setLineNumbersOn( bool enable ) 01219 { 01220 config()->setLineNumbers (enable); 01221 } 01222 01223 void KateView::toggleLineNumbersOn() 01224 { 01225 config()->setLineNumbers (!config()->lineNumbers()); 01226 } 01227 01228 void KateView::setScrollBarMarks( bool enable ) 01229 { 01230 config()->setScrollBarMarks (enable); 01231 } 01232 01233 void KateView::toggleScrollBarMarks() 01234 { 01235 config()->setScrollBarMarks (!config()->scrollBarMarks()); 01236 } 01237 01238 void KateView::toggleDynWordWrap() 01239 { 01240 config()->setDynWordWrap( !config()->dynWordWrap() ); 01241 } 01242 01243 void KateView::toggleWWMarker() 01244 { 01245 m_renderer->config()->setWordWrapMarker (!m_renderer->config()->wordWrapMarker()); 01246 } 01247 01248 void KateView::setFoldingMarkersOn( bool enable ) 01249 { 01250 config()->setFoldingBar ( enable ); 01251 } 01252 01253 void KateView::toggleFoldingMarkers() 01254 { 01255 config()->setFoldingBar ( !config()->foldingBar() ); 01256 } 01257 01258 bool KateView::iconBorder() { 01259 return m_viewInternal->m_leftBorder->iconBorderOn(); 01260 } 01261 01262 bool KateView::lineNumbersOn() { 01263 return m_viewInternal->m_leftBorder->lineNumbersOn(); 01264 } 01265 01266 bool KateView::scrollBarMarks() { 01267 return m_viewInternal->m_lineScroll->showMarks(); 01268 } 01269 01270 int KateView::dynWrapIndicators() { 01271 return m_viewInternal->m_leftBorder->dynWrapIndicators(); 01272 } 01273 01274 bool KateView::foldingMarkersOn() { 01275 return m_viewInternal->m_leftBorder->foldingMarkersOn(); 01276 } 01277 01278 void KateView::toggleWriteLock() 01279 { 01280 m_doc->setReadWrite( ! m_doc->isReadWrite() ); 01281 } 01282 01283 void KateView::enableTextHints(int timeout) 01284 { 01285 m_viewInternal->enableTextHints(timeout); 01286 } 01287 01288 void KateView::disableTextHints() 01289 { 01290 m_viewInternal->disableTextHints(); 01291 } 01292 01293 bool KateView::viInputMode() const 01294 { 01295 return m_viewInternal->m_viInputMode; 01296 } 01297 01298 bool KateView::viInputModeStealKeys() const 01299 { 01300 return m_viewInternal->m_viInputModeStealKeys; 01301 } 01302 01303 void KateView::toggleViInputMode() 01304 { 01305 config()->setViInputMode (!config()->viInputMode()); 01306 01307 if ( viInputMode() ) { 01308 m_viewInternal->getViInputModeManager()->viEnterNormalMode(); 01309 01310 if ( !config()->viInputModeHideStatusBar() ) { 01311 showViModeBar(); 01312 } 01313 01314 deactivateEditActions(); 01315 } else { // disabling the vi input mode 01316 hideViModeBar(); 01317 activateEditActions(); 01318 } 01319 01320 emit viewModeChanged(this); 01321 emit viewEditModeChanged(this,viewEditMode()); 01322 } 01323 01324 void KateView::showViModeBar() 01325 { 01326 if (viInputMode() && !config()->viInputModeHideStatusBar()) { 01327 bottomViewBar()->addPermanentBarWidget(viModeBar()); 01328 updateViModeBarMode(); 01329 } 01330 } 01331 01332 void KateView::hideViModeBar() 01333 { 01334 if (bottomViewBar() && m_viModeBar) { 01335 bottomViewBar()->removePermanentBarWidget(viModeBar()); 01336 } 01337 } 01338 01339 void KateView::updateViModeBarMode() 01340 { 01341 if (config()->viInputModeHideStatusBar()) 01342 return; 01343 01344 viModeBar()->updateViMode(getCurrentViMode()); 01345 } 01346 01347 void KateView::updateViModeBarCmd() 01348 { 01349 if (config()->viInputModeHideStatusBar()) 01350 return; 01351 01352 QString cmd = m_viewInternal->getViInputModeManager()->getVerbatimKeys(); 01353 viModeBar()->updatePartialCommand(cmd); 01354 } 01355 01356 ViMode KateView::getCurrentViMode() const 01357 { 01358 return m_viewInternal->getCurrentViMode(); 01359 } 01360 01361 KateViInputModeManager* KateView::getViInputModeManager() 01362 { 01363 return m_viewInternal->getViInputModeManager(); 01364 } 01365 01366 void KateView::find() 01367 { 01368 const bool INIT_HINT_AS_INCREMENTAL = false; 01369 KateSearchBar * const bar = searchBar(INIT_HINT_AS_INCREMENTAL); 01370 bar->enterIncrementalMode(); 01371 bottomViewBar()->showBarWidget(bar); 01372 bar->setFocus(); 01373 } 01374 01375 void KateView::findSelectedForwards() 01376 { 01377 KateSearchBar::nextMatchForSelection(this, KateSearchBar::SearchForward); 01378 } 01379 01380 void KateView::findSelectedBackwards() 01381 { 01382 KateSearchBar::nextMatchForSelection(this, KateSearchBar::SearchBackward); 01383 } 01384 01385 void KateView::replace() 01386 { 01387 const bool INIT_HINT_AS_POWER = true; 01388 KateSearchBar * const bar = searchBar(INIT_HINT_AS_POWER); 01389 bar->enterPowerMode(); 01390 bottomViewBar()->showBarWidget(bar); 01391 bar->setFocus(); 01392 } 01393 01394 void KateView::findNext() 01395 { 01396 searchBar()->findNext(); 01397 } 01398 01399 void KateView::findPrevious() 01400 { 01401 searchBar()->findPrevious(); 01402 } 01403 01404 void KateView::slotSelectionChanged () 01405 { 01406 m_copy->setEnabled (selection() || m_config->smartCopyCut()); 01407 m_deSelect->setEnabled (selection()); 01408 01409 if (m_doc->readOnly()) 01410 return; 01411 01412 m_cut->setEnabled (selection() || m_config->smartCopyCut() ); 01413 01414 m_spell->updateActions (); 01415 } 01416 01417 void KateView::switchToCmdLine () 01418 { 01419 // if the user has selected text, insert the selection's range (start line to end line) in the 01420 // command line when opened 01421 if (selectionRange().start().line() != -1 && selectionRange().end().line() != -1) { 01422 cmdLineBar()->setText(QString::number(selectionRange().start().line()+1)+',' 01423 +QString::number(selectionRange().end().line()+1)); 01424 } 01425 bottomViewBar()->showBarWidget(cmdLineBar()); 01426 cmdLineBar()->setFocus (); 01427 hideViModeBar(); 01428 } 01429 01430 KateRenderer *KateView::renderer () 01431 { 01432 return m_renderer; 01433 } 01434 01435 void KateView::updateConfig () 01436 { 01437 if (m_startingUp) 01438 return; 01439 01440 // dyn. word wrap & markers 01441 if (m_hasWrap != config()->dynWordWrap()) { 01442 m_viewInternal->prepareForDynWrapChange(); 01443 01444 m_hasWrap = config()->dynWordWrap(); 01445 01446 m_viewInternal->dynWrapChanged(); 01447 01448 m_setDynWrapIndicators->setEnabled(config()->dynWordWrap()); 01449 m_toggleDynWrap->setChecked( config()->dynWordWrap() ); 01450 } 01451 01452 m_viewInternal->m_leftBorder->setDynWrapIndicators( config()->dynWordWrapIndicators() ); 01453 m_setDynWrapIndicators->setCurrentItem( config()->dynWordWrapIndicators() ); 01454 01455 // line numbers 01456 m_viewInternal->m_leftBorder->setLineNumbersOn( config()->lineNumbers() ); 01457 m_toggleLineNumbers->setChecked( config()->lineNumbers() ); 01458 01459 // icon bar 01460 m_viewInternal->m_leftBorder->setIconBorderOn( config()->iconBar() ); 01461 m_toggleIconBar->setChecked( config()->iconBar() ); 01462 01463 // scrollbar marks 01464 m_viewInternal->m_lineScroll->setShowMarks( config()->scrollBarMarks() ); 01465 m_toggleScrollBarMarks->setChecked( config()->scrollBarMarks() ); 01466 01467 // misc edit 01468 m_toggleBlockSelection->setChecked( blockSelectionMode() ); 01469 m_toggleInsert->setChecked( isOverwriteMode() ); 01470 01471 // vi modes 01472 m_viInputModeAction->setChecked( config()->viInputMode() ); 01473 01474 updateFoldingConfig (); 01475 01476 // bookmark 01477 m_bookmarks->setSorting( (KateBookmarks::Sorting) config()->bookmarkSort() ); 01478 01479 m_viewInternal->setAutoCenterLines(config()->autoCenterLines ()); 01480 01481 // vi input mode 01482 m_viewInternal->m_viInputMode = config()->viInputMode(); 01483 01484 // whether vi input mode should override actions or not 01485 m_viewInternal->m_viInputModeStealKeys = config()->viInputModeStealKeys(); 01486 01487 reflectOnTheFlySpellCheckStatus(m_doc->isOnTheFlySpellCheckingEnabled()); 01488 01489 // register/unregister word completion... 01490 unregisterCompletionModel (KateGlobal::self()->wordCompletionModel()); 01491 if (config()->wordCompletion ()) 01492 registerCompletionModel (KateGlobal::self()->wordCompletionModel()); 01493 01494 m_cut->setEnabled(m_doc->isReadWrite() && (selection() || m_config->smartCopyCut())); 01495 m_copy->setEnabled(selection() || m_config->smartCopyCut()); 01496 01497 // now redraw... 01498 m_viewInternal->cache()->clear(); 01499 tagAll (); 01500 updateView (true); 01501 01502 emit configChanged(); 01503 } 01504 01505 void KateView::updateDocumentConfig() 01506 { 01507 if (m_startingUp) 01508 return; 01509 01510 m_updatingDocumentConfig = true; 01511 01512 m_setEndOfLine->setCurrentItem (m_doc->config()->eol()); 01513 01514 m_addBom->setChecked(m_doc->config()->bom()); 01515 01516 m_updatingDocumentConfig = false; 01517 01518 // maybe block selection or wrap-cursor mode changed 01519 ensureCursorColumnValid(); 01520 01521 // first change this 01522 m_renderer->setTabWidth (m_doc->config()->tabWidth()); 01523 m_renderer->setIndentWidth (m_doc->config()->indentationWidth()); 01524 01525 // now redraw... 01526 m_viewInternal->cache()->clear(); 01527 tagAll (); 01528 updateView (true); 01529 } 01530 01531 void KateView::updateRendererConfig() 01532 { 01533 if (m_startingUp) 01534 return; 01535 01536 m_toggleWWMarker->setChecked( m_renderer->config()->wordWrapMarker() ); 01537 01538 m_viewInternal->updateBracketMarkAttributes(); 01539 m_viewInternal->updateBracketMarks(); 01540 01541 // now redraw... 01542 m_viewInternal->cache()->clear(); 01543 tagAll (); 01544 m_viewInternal->updateView (true); 01545 01546 // update the left border right, for example linenumbers 01547 m_viewInternal->m_leftBorder->updateFont(); 01548 m_viewInternal->m_leftBorder->repaint (); 01549 01550 // @@ showIndentLines is not cached anymore. 01551 // m_renderer->setShowIndentLines (m_renderer->config()->showIndentationLines()); 01552 } 01553 01554 void KateView::updateFoldingConfig () 01555 { 01556 // folding bar 01557 bool doit = config()->foldingBar() && m_doc->highlight() && m_doc->highlight()->allowsFolding(); 01558 m_viewInternal->m_leftBorder->setFoldingMarkersOn(doit); 01559 m_toggleFoldingMarkers->setChecked( doit ); 01560 m_toggleFoldingMarkers->setEnabled( m_doc->highlight() && m_doc->highlight()->allowsFolding() ); 01561 01562 QStringList l; 01563 01564 l << "folding_toplevel" << "folding_expandtoplevel" 01565 << "folding_collapselocal" << "folding_expandlocal"; 01566 01567 QAction *a = 0; 01568 for (int z = 0; z < l.size(); z++) 01569 if ((a = actionCollection()->action( l[z].toAscii().constData() ))) 01570 a->setEnabled (m_doc->highlight() && m_doc->highlight()->allowsFolding()); 01571 } 01572 01573 void KateView::ensureCursorColumnValid() 01574 { 01575 KTextEditor::Cursor c = m_viewInternal->getCursor(); 01576 01577 // make sure the cursor is valid: 01578 // - in block selection mode or if wrap cursor is off, the column is arbitrary 01579 // - otherwise: it's bounded by the line length 01580 if (!blockSelectionMode() && wrapCursor() 01581 && (!c.isValid() || c.column() > m_doc->lineLength(c.line()))) 01582 { 01583 c.setColumn(m_doc->kateTextLine(cursorPosition().line())->length()); 01584 setCursorPosition(c); 01585 } 01586 } 01587 01588 //BEGIN EDIT STUFF 01589 void KateView::editStart () 01590 { 01591 m_viewInternal->editStart (); 01592 } 01593 01594 void KateView::editEnd (int editTagLineStart, int editTagLineEnd, bool tagFrom) 01595 { 01596 m_viewInternal->editEnd (editTagLineStart, editTagLineEnd, tagFrom); 01597 } 01598 01599 void KateView::editSetCursor (const KTextEditor::Cursor &cursor) 01600 { 01601 m_viewInternal->editSetCursor (cursor); 01602 } 01603 //END 01604 01605 //BEGIN TAG & CLEAR 01606 bool KateView::tagLine (const KTextEditor::Cursor& virtualCursor) 01607 { 01608 return m_viewInternal->tagLine (virtualCursor); 01609 } 01610 01611 bool KateView::tagRange(const KTextEditor::Range& range, bool realLines) 01612 { 01613 return m_viewInternal->tagRange(range, realLines); 01614 } 01615 01616 bool KateView::tagLines (int start, int end, bool realLines) 01617 { 01618 return m_viewInternal->tagLines (start, end, realLines); 01619 } 01620 01621 bool KateView::tagLines (KTextEditor::Cursor start, KTextEditor::Cursor end, bool realCursors) 01622 { 01623 return m_viewInternal->tagLines (start, end, realCursors); 01624 } 01625 01626 void KateView::tagAll () 01627 { 01628 m_viewInternal->tagAll (); 01629 } 01630 01631 void KateView::clear () 01632 { 01633 m_viewInternal->clear (); 01634 } 01635 01636 void KateView::repaintText (bool paintOnlyDirty) 01637 { 01638 if (paintOnlyDirty) 01639 m_viewInternal->updateDirty(); 01640 else 01641 m_viewInternal->update(); 01642 } 01643 01644 void KateView::updateView (bool changed) 01645 { 01646 //kDebug(13020) << "KateView::updateView"; 01647 01648 m_viewInternal->updateView (changed); 01649 m_viewInternal->m_leftBorder->update(); 01650 } 01651 01652 //END 01653 01654 void KateView::slotHlChanged() 01655 { 01656 KateHighlighting *hl = m_doc->highlight(); 01657 bool ok ( !hl->getCommentStart(0).isEmpty() || !hl->getCommentSingleLineStart(0).isEmpty() ); 01658 01659 if (actionCollection()->action("tools_comment")) 01660 actionCollection()->action("tools_comment")->setEnabled( ok ); 01661 01662 if (actionCollection()->action("tools_uncomment")) 01663 actionCollection()->action("tools_uncomment")->setEnabled( ok ); 01664 01665 if (actionCollection()->action("tools_toggle_comment")) 01666 actionCollection()->action("tools_toggle_comment")->setEnabled( ok ); 01667 01668 // show folding bar if "view defaults" says so, otherwise enable/disable only the menu entry 01669 updateFoldingConfig (); 01670 } 01671 01672 int KateView::virtualCursorColumn() const 01673 { 01674 int r = m_doc->toVirtualColumn(m_viewInternal->getCursor()); 01675 if ( !( m_doc->config()->wrapCursor() ) && 01676 m_viewInternal->getCursor().column() > m_doc->line( m_viewInternal->getCursor().line() ).length() ) 01677 r += m_viewInternal->getCursor().column() - m_doc->line( m_viewInternal->getCursor().line() ).length(); 01678 01679 return r; 01680 } 01681 01682 void KateView::notifyMousePositionChanged(const KTextEditor::Cursor& newPosition) 01683 { 01684 emit mousePositionChanged(this, newPosition); 01685 } 01686 01687 //BEGIN KTextEditor::SelectionInterface stuff 01688 01689 bool KateView::setSelection( const KTextEditor::Range &selection ) 01690 { 01694 if (selection == m_selection) 01695 return true; 01696 01700 KTextEditor::Range oldSelection = m_selection; 01701 01705 m_selection.setRange (selection.isEmpty() ? KTextEditor::Range::invalid() : selection); 01706 01710 tagSelection(oldSelection); 01711 repaintText(true); 01712 01716 emit selectionChanged (this); 01717 01721 return true; 01722 } 01723 01724 bool KateView::clearSelection() 01725 { 01726 return clearSelection (true); 01727 } 01728 01729 bool KateView::clearSelection(bool redraw, bool finishedChangingSelection) 01730 { 01734 if( !selection() ) 01735 return false; 01736 01740 KTextEditor::Range oldSelection = m_selection; 01741 01745 m_selection.setRange (KTextEditor::Range::invalid()); 01746 01750 tagSelection(oldSelection); 01751 if (redraw) 01752 repaintText(true); 01753 01757 if (finishedChangingSelection) 01758 emit selectionChanged (this); 01759 01763 return true; 01764 } 01765 01766 bool KateView::selection() const 01767 { 01768 if (!wrapCursor()) 01769 return m_selection != KTextEditor::Range::invalid(); 01770 else 01771 return m_selection.toRange().isValid(); 01772 } 01773 01774 QString KateView::selectionText() const 01775 { 01776 return m_doc->text(m_selection, blockSelect); 01777 } 01778 01779 bool KateView::removeSelectedText() 01780 { 01781 if (!selection()) 01782 return false; 01783 01784 m_doc->editStart(); 01785 01786 // Optimization: clear selection before removing text 01787 KTextEditor::Range selection = m_selection; 01788 01789 // don't redraw the cleared selection - that's done in editEnd(). 01790 clearSelection(false); 01791 01792 m_doc->removeText(selection, blockSelect); 01793 01794 m_doc->editEnd(); 01795 01796 return true; 01797 } 01798 01799 bool KateView::selectAll() 01800 { 01801 setBlockSelectionMode (false); 01802 top(); 01803 shiftBottom(); 01804 return true; 01805 } 01806 01807 bool KateView::cursorSelected(const KTextEditor::Cursor& cursor) 01808 { 01809 KTextEditor::Cursor ret = cursor; 01810 if ( (!blockSelect) && (ret.column() < 0) ) 01811 ret.setColumn(0); 01812 01813 if (blockSelect) 01814 return cursor.line() >= m_selection.start().line() && ret.line() <= m_selection.end().line() 01815 && ret.column() >= m_selection.start().column() && ret.column() <= m_selection.end().column(); 01816 else 01817 return m_selection.toRange().contains(cursor) || m_selection.end() == cursor; 01818 } 01819 01820 bool KateView::lineSelected (int line) 01821 { 01822 return !blockSelect && m_selection.toRange().containsLine(line); 01823 } 01824 01825 bool KateView::lineEndSelected (const KTextEditor::Cursor& lineEndPos) 01826 { 01827 return (!blockSelect) 01828 && (lineEndPos.line() > m_selection.start().line() || (lineEndPos.line() == m_selection.start().line() && (m_selection.start().column() < lineEndPos.column() || lineEndPos.column() == -1))) 01829 && (lineEndPos.line() < m_selection.end().line() || (lineEndPos.line() == m_selection.end().line() && (lineEndPos.column() <= m_selection.end().column() && lineEndPos.column() != -1))); 01830 } 01831 01832 bool KateView::lineHasSelected (int line) 01833 { 01834 return selection() && m_selection.toRange().containsLine(line); 01835 } 01836 01837 bool KateView::lineIsSelection (int line) 01838 { 01839 return (line == m_selection.start().line() && line == m_selection.end().line()); 01840 } 01841 01842 void KateView::tagSelection(const KTextEditor::Range &oldSelection) 01843 { 01844 if (selection()) { 01845 if (oldSelection.start().line() == -1) { 01846 // We have to tag the whole lot if 01847 // 1) we have a selection, and: 01848 // a) it's new; or 01849 tagLines(m_selection, true); 01850 01851 } else if (blockSelectionMode() && (oldSelection.start().column() != m_selection.start().column() || oldSelection.end().column() != m_selection.end().column())) { 01852 // b) we're in block selection mode and the columns have changed 01853 tagLines(m_selection, true); 01854 tagLines(oldSelection, true); 01855 01856 } else { 01857 if (oldSelection.start() != m_selection.start()) { 01858 if (oldSelection.start() < m_selection.start()) 01859 tagLines(oldSelection.start(), m_selection.start(), true); 01860 else 01861 tagLines(m_selection.start(), oldSelection.start(), true); 01862 } 01863 01864 if (oldSelection.end() != m_selection.end()) { 01865 if (oldSelection.end() < m_selection.end()) 01866 tagLines(oldSelection.end(), m_selection.end(), true); 01867 else 01868 tagLines(m_selection.end(), oldSelection.end(), true); 01869 } 01870 } 01871 01872 } else { 01873 // No more selection, clean up 01874 tagLines(oldSelection, true); 01875 } 01876 } 01877 01878 void KateView::selectWord( const KTextEditor::Cursor& cursor ) 01879 { 01880 int start, end, len; 01881 01882 Kate::TextLine textLine = m_doc->plainKateTextLine(cursor.line()); 01883 01884 if (!textLine) 01885 return; 01886 01887 len = textLine->length(); 01888 start = end = cursor.column(); 01889 while (start > 0 && m_doc->highlight()->isInWord(textLine->at(start - 1), textLine->attribute(start - 1))) start--; 01890 while (end < len && m_doc->highlight()->isInWord(textLine->at(end), textLine->attribute(start - 1))) end++; 01891 if (end <= start) return; 01892 01893 setSelection (KTextEditor::Range(cursor.line(), start, cursor.line(), end)); 01894 } 01895 01896 void KateView::selectLine( const KTextEditor::Cursor& cursor ) 01897 { 01898 int line = cursor.line(); 01899 if ( line+1 >= m_doc->lines() ) 01900 setSelection (KTextEditor::Range(line, 0, line, m_doc->lineLength(line))); 01901 else 01902 setSelection (KTextEditor::Range(line, 0, line+1, 0)); 01903 } 01904 01905 void KateView::cut() 01906 { 01907 if (!selection() && !m_config->smartCopyCut()) 01908 return; 01909 01910 copy(); 01911 if (!selection()) 01912 selectLine(m_viewInternal->m_cursor); 01913 removeSelectedText(); 01914 } 01915 01916 void KateView::copy() const 01917 { 01918 QString text = selectionText(); 01919 01920 if (!selection()) { 01921 if (!m_config->smartCopyCut()) 01922 return; 01923 text = m_doc->line(m_viewInternal->m_cursor.line()) + '\n'; 01924 m_viewInternal->moveEdge(KateViewInternal::left, false); 01925 } 01926 01927 QApplication::clipboard()->setText(text); 01928 } 01929 01930 void KateView::applyWordWrap () 01931 { 01932 if (selection()) 01933 m_doc->wrapText (selectionRange().start().line(), selectionRange().end().line()); 01934 else 01935 m_doc->wrapText (0, m_doc->lastLine()); 01936 } 01937 01938 //END 01939 01940 //BEGIN KTextEditor::BlockSelectionInterface stuff 01941 01942 bool KateView::blockSelectionMode () const 01943 { 01944 return blockSelect; 01945 } 01946 01947 bool KateView::setBlockSelectionMode (bool on) 01948 { 01949 if (on != blockSelect) 01950 { 01951 blockSelect = on; 01952 01953 KTextEditor::Range oldSelection = m_selection; 01954 01955 const bool hadSelection = clearSelection(false, false); 01956 01957 setSelection(oldSelection); 01958 01959 m_toggleBlockSelection->setChecked( blockSelectionMode() ); 01960 01961 // when leaving block selection mode, if cursor is at an invalid position or past the end of the 01962 // line, move the cursor to the last column of the current line unless cursor wrapping is off 01963 ensureCursorColumnValid(); 01964 01965 if (!hadSelection) { 01966 // emit selectionChanged() according to the KTextEditor::View api 01967 // documentation also if there is no selection around. This is needed, 01968 // as e.g. the Kate App status bar uses this signal to update the state 01969 // of the selection mode (block selection, line based selection) 01970 emit selectionChanged(this); 01971 } 01972 } 01973 01974 return true; 01975 } 01976 01977 bool KateView::toggleBlockSelectionMode () 01978 { 01979 m_toggleBlockSelection->setChecked (!blockSelect); 01980 return setBlockSelectionMode (!blockSelect); 01981 } 01982 01983 bool KateView::wrapCursor () const 01984 { 01985 return !blockSelectionMode() && (m_doc->config()->wrapCursor()); 01986 } 01987 01988 //END 01989 01990 01991 void KateView::slotTextInserted ( KTextEditor::View *view, const KTextEditor::Cursor &position, const QString &text) 01992 { 01993 emit textInserted ( view, position, text); 01994 } 01995 01996 bool KateView::insertTemplateTextImplementation ( const KTextEditor::Cursor& c, 01997 const QString &templateString, 01998 const QMap<QString,QString> &initialValues) 01999 { 02000 return m_doc->insertTemplateTextImplementation(c, templateString, initialValues, 0, this); 02001 } 02002 02003 bool KateView::insertTemplateTextImplementation ( const KTextEditor::Cursor& c, 02004 const QString &templateString, 02005 const QMap<QString,QString> &initialValues, 02006 KTextEditor::TemplateScript* templateScript) 02007 { 02008 /* if (!scriptToken.isEmpty()) { 02009 KateGlobal::self()->scriptManager()->callTestIt(this,scriptToken); 02010 }*/ 02011 return m_doc->insertTemplateTextImplementation(c, templateString, initialValues, templateScript, this); 02012 } 02013 02014 02015 bool KateView::tagLines( KTextEditor::Range range, bool realRange ) 02016 { 02017 return tagLines(range.start(), range.end(), realRange); 02018 } 02019 02020 void KateView::deactivateEditActions() 02021 { 02022 foreach(QAction *action, m_editActions) 02023 action->setEnabled(false); 02024 } 02025 02026 void KateView::activateEditActions() 02027 { 02028 foreach(QAction *action, m_editActions) 02029 action->setEnabled(true); 02030 } 02031 02032 bool KateView::mouseTrackingEnabled( ) const 02033 { 02034 // FIXME support 02035 return true; 02036 } 02037 02038 bool KateView::setMouseTrackingEnabled( bool ) 02039 { 02040 // FIXME support 02041 return true; 02042 } 02043 02044 bool KateView::isCompletionActive( ) const 02045 { 02046 return completionWidget()->isCompletionActive(); 02047 } 02048 02049 KateCompletionWidget* KateView::completionWidget() const 02050 { 02051 if (!m_completionWidget) 02052 m_completionWidget = new KateCompletionWidget(const_cast<KateView*>(this)); 02053 02054 return m_completionWidget; 02055 } 02056 02057 void KateView::startCompletion( const KTextEditor::Range & word, KTextEditor::CodeCompletionModel * model ) 02058 { 02059 completionWidget()->startCompletion(word, model); 02060 } 02061 02062 void KateView::abortCompletion( ) 02063 { 02064 completionWidget()->abortCompletion(); 02065 } 02066 02067 void KateView::forceCompletion( ) 02068 { 02069 completionWidget()->execute(); 02070 } 02071 02072 void KateView::registerCompletionModel(KTextEditor::CodeCompletionModel* model) 02073 { 02074 completionWidget()->registerCompletionModel(model); 02075 } 02076 02077 void KateView::unregisterCompletionModel(KTextEditor::CodeCompletionModel* model) 02078 { 02079 completionWidget()->unregisterCompletionModel(model); 02080 } 02081 02082 bool KateView::isAutomaticInvocationEnabled() const 02083 { 02084 return m_config->automaticCompletionInvocation(); 02085 } 02086 02087 void KateView::setAutomaticInvocationEnabled(bool enabled) 02088 { 02089 config()->setAutomaticCompletionInvocation(enabled); 02090 } 02091 02092 void KateView::sendCompletionExecuted(const KTextEditor::Cursor& position, KTextEditor::CodeCompletionModel* model, const QModelIndex& index) 02093 { 02094 emit completionExecuted(this, position, model, index); 02095 } 02096 02097 void KateView::sendCompletionAborted() 02098 { 02099 emit completionAborted(this); 02100 } 02101 02102 void KateView::paste( ) 02103 { 02104 m_doc->paste( this ); 02105 emit selectionChanged (this); 02106 m_viewInternal->repaint(); 02107 } 02108 02109 bool KateView::setCursorPosition( KTextEditor::Cursor position ) 02110 { 02111 return setCursorPositionInternal( position, 1, true ); 02112 } 02113 02114 KTextEditor::Cursor KateView::cursorPosition( ) const 02115 { 02116 return m_viewInternal->getCursor(); 02117 } 02118 02119 KTextEditor::Cursor KateView::cursorPositionVirtual( ) const 02120 { 02121 return KTextEditor::Cursor (m_viewInternal->getCursor().line(), virtualCursorColumn()); 02122 } 02123 02124 QPoint KateView::cursorToCoordinate( const KTextEditor::Cursor & cursor ) const 02125 { 02126 return m_viewInternal->cursorToCoordinate(cursor); 02127 } 02128 02129 KTextEditor::Cursor KateView::coordinatesToCursor(const QPoint& coords) const 02130 { 02131 return m_viewInternal->coordinatesToCursor(coords); 02132 } 02133 02134 QPoint KateView::cursorPositionCoordinates( ) const 02135 { 02136 return m_viewInternal->cursorCoordinates(); 02137 } 02138 02139 bool KateView::setCursorPositionVisual( const KTextEditor::Cursor & position ) 02140 { 02141 return setCursorPositionInternal( position, m_doc->config()->tabWidth(), true ); 02142 } 02143 02144 QString KateView::currentTextLine( ) 02145 { 02146 return m_doc->line( cursorPosition().line() ); 02147 } 02148 02149 void KateView::indent( ) 02150 { 02151 KTextEditor::Cursor c(cursorPosition().line(), 0); 02152 KTextEditor::Range r = selection() ? selectionRange() : KTextEditor::Range(c, c); 02153 m_doc->indent( r, 1 ); 02154 } 02155 02156 void KateView::unIndent( ) 02157 { 02158 KTextEditor::Cursor c(cursorPosition().line(), 0); 02159 KTextEditor::Range r = selection() ? selectionRange() : KTextEditor::Range(c, c); 02160 m_doc->indent( r, -1 ); 02161 } 02162 02163 void KateView::cleanIndent( ) 02164 { 02165 KTextEditor::Cursor c(cursorPosition().line(), 0); 02166 KTextEditor::Range r = selection() ? selectionRange() : KTextEditor::Range(c, c); 02167 m_doc->indent( r, 0 ); 02168 } 02169 02170 void KateView::align( ) 02171 { 02172 // no selection: align current line; selection: use selection range 02173 const int line = cursorPosition().line(); 02174 KTextEditor::Range alignRange(KTextEditor::Cursor (line,0), KTextEditor::Cursor (line,0)); 02175 if (selection()) { 02176 alignRange = selectionRange(); 02177 } 02178 02179 m_doc->align( this, alignRange ); 02180 } 02181 02182 void KateView::comment( ) 02183 { 02184 m_selection.setInsertBehaviors(Kate::TextRange::ExpandLeft | Kate::TextRange::ExpandRight); 02185 m_doc->comment( this, cursorPosition().line(), cursorPosition().column(), 1 ); 02186 m_selection.setInsertBehaviors(Kate::TextRange::ExpandRight); 02187 } 02188 02189 void KateView::uncomment( ) 02190 { 02191 m_doc->comment( this, cursorPosition().line(), cursorPosition().column(),-1 ); 02192 } 02193 02194 void KateView::toggleComment( ) 02195 { 02196 m_selection.setInsertBehaviors(Kate::TextRange::ExpandLeft | Kate::TextRange::ExpandRight); 02197 m_doc->comment( this, cursorPosition().line(), cursorPosition().column(), 0 ); 02198 m_selection.setInsertBehaviors(Kate::TextRange::ExpandRight); 02199 } 02200 02201 void KateView::uppercase( ) 02202 { 02203 m_doc->transform( this, m_viewInternal->m_cursor, KateDocument::Uppercase ); 02204 } 02205 02206 void KateView::killLine( ) 02207 { 02208 m_doc->removeLine( cursorPosition().line() ); 02209 } 02210 02211 void KateView::lowercase( ) 02212 { 02213 m_doc->transform( this, m_viewInternal->m_cursor, KateDocument::Lowercase ); 02214 } 02215 02216 void KateView::capitalize( ) 02217 { 02218 m_doc->editStart(); 02219 m_doc->transform( this, m_viewInternal->m_cursor, KateDocument::Lowercase ); 02220 m_doc->transform( this, m_viewInternal->m_cursor, KateDocument::Capitalize ); 02221 m_doc->editEnd(); 02222 } 02223 02224 void KateView::keyReturn( ) 02225 { 02226 m_viewInternal->doReturn(); 02227 } 02228 02229 void KateView::smartNewline( ) 02230 { 02231 m_viewInternal->doSmartNewline(); 02232 } 02233 02234 void KateView::backspace( ) 02235 { 02236 m_viewInternal->doBackspace(); 02237 } 02238 02239 void KateView::insertTab( ) 02240 { 02241 m_viewInternal->doTabulator(); 02242 } 02243 02244 void KateView::deleteWordLeft( ) 02245 { 02246 m_viewInternal->doDeleteWordLeft(); 02247 } 02248 02249 void KateView::keyDelete( ) 02250 { 02251 m_viewInternal->doDelete(); 02252 } 02253 02254 void KateView::deleteWordRight( ) 02255 { 02256 m_viewInternal->doDeleteWordRight(); 02257 } 02258 02259 void KateView::transpose( ) 02260 { 02261 m_viewInternal->doTranspose(); 02262 } 02263 02264 void KateView::cursorLeft( ) 02265 { 02266 m_viewInternal->cursorLeft(); 02267 } 02268 02269 void KateView::shiftCursorLeft( ) 02270 { 02271 m_viewInternal->cursorLeft(true); 02272 } 02273 02274 void KateView::cursorRight( ) 02275 { 02276 m_viewInternal->cursorRight(); 02277 } 02278 02279 void KateView::shiftCursorRight( ) 02280 { 02281 m_viewInternal->cursorRight(true); 02282 } 02283 02284 void KateView::wordLeft( ) 02285 { 02286 m_viewInternal->wordLeft(); 02287 } 02288 02289 void KateView::shiftWordLeft( ) 02290 { 02291 m_viewInternal->wordLeft(true); 02292 } 02293 02294 void KateView::wordRight( ) 02295 { 02296 m_viewInternal->wordRight(); 02297 } 02298 02299 void KateView::shiftWordRight( ) 02300 { 02301 m_viewInternal->wordRight(true); 02302 } 02303 02304 void KateView::home( ) 02305 { 02306 m_viewInternal->home(); 02307 } 02308 02309 void KateView::shiftHome( ) 02310 { 02311 m_viewInternal->home(true); 02312 } 02313 02314 void KateView::end( ) 02315 { 02316 m_viewInternal->end(); 02317 } 02318 02319 void KateView::shiftEnd( ) 02320 { 02321 m_viewInternal->end(true); 02322 } 02323 02324 void KateView::up( ) 02325 { 02326 m_viewInternal->cursorUp(); 02327 } 02328 02329 void KateView::shiftUp( ) 02330 { 02331 m_viewInternal->cursorUp(true); 02332 } 02333 02334 void KateView::down( ) 02335 { 02336 m_viewInternal->cursorDown(); 02337 } 02338 02339 void KateView::shiftDown( ) 02340 { 02341 m_viewInternal->cursorDown(true); 02342 } 02343 02344 void KateView::scrollUp( ) 02345 { 02346 m_viewInternal->scrollUp(); 02347 } 02348 02349 void KateView::scrollDown( ) 02350 { 02351 m_viewInternal->scrollDown(); 02352 } 02353 02354 void KateView::topOfView( ) 02355 { 02356 m_viewInternal->topOfView(); 02357 } 02358 02359 void KateView::shiftTopOfView( ) 02360 { 02361 m_viewInternal->topOfView(true); 02362 } 02363 02364 void KateView::bottomOfView( ) 02365 { 02366 m_viewInternal->bottomOfView(); 02367 } 02368 02369 void KateView::shiftBottomOfView( ) 02370 { 02371 m_viewInternal->bottomOfView(true); 02372 } 02373 02374 void KateView::pageUp( ) 02375 { 02376 m_viewInternal->pageUp(); 02377 } 02378 02379 void KateView::shiftPageUp( ) 02380 { 02381 m_viewInternal->pageUp(true); 02382 } 02383 02384 void KateView::pageDown( ) 02385 { 02386 m_viewInternal->pageDown(); 02387 } 02388 02389 void KateView::shiftPageDown( ) 02390 { 02391 m_viewInternal->pageDown(true); 02392 } 02393 02394 void KateView::top( ) 02395 { 02396 m_viewInternal->top_home(); 02397 } 02398 02399 void KateView::shiftTop( ) 02400 { 02401 m_viewInternal->top_home(true); 02402 } 02403 02404 void KateView::bottom( ) 02405 { 02406 m_viewInternal->bottom_end(); 02407 } 02408 02409 void KateView::shiftBottom( ) 02410 { 02411 m_viewInternal->bottom_end(true); 02412 } 02413 02414 void KateView::toMatchingBracket( ) 02415 { 02416 m_viewInternal->cursorToMatchingBracket(); 02417 } 02418 02419 void KateView::shiftToMatchingBracket( ) 02420 { 02421 m_viewInternal->cursorToMatchingBracket(true); 02422 } 02423 02424 const KTextEditor::Range & KateView::selectionRange( ) const 02425 { 02426 // update the cache 02427 m_holdSelectionRangeForAPI = m_selection; 02428 02429 // return cached value, has right type! 02430 return m_holdSelectionRangeForAPI; 02431 } 02432 02433 KTextEditor::Document * KateView::document( ) const 02434 { 02435 return m_doc; 02436 } 02437 02438 void KateView::setContextMenu( QMenu * menu ) 02439 { 02440 if (m_contextMenu) { 02441 disconnect(m_contextMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowContextMenu())); 02442 disconnect(m_contextMenu, SIGNAL(aboutToHide()), this, SLOT(aboutToHideContextMenu())); 02443 } 02444 m_contextMenu = menu; 02445 m_userContextMenuSet=true; 02446 02447 if (m_contextMenu) { 02448 connect(m_contextMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowContextMenu())); 02449 connect(m_contextMenu, SIGNAL(aboutToHide()), this, SLOT(aboutToHideContextMenu())); 02450 } 02451 } 02452 02453 QMenu *KateView::contextMenu( ) const 02454 { 02455 if (m_userContextMenuSet) 02456 return m_contextMenu; 02457 else 02458 { 02459 KXMLGUIClient* client = const_cast<KateView*>(this); 02460 while (client->parentClient()) 02461 client = client->parentClient(); 02462 02463 //kDebug() << "looking up all menu containers"; 02464 if (client->factory()){ 02465 QList<QWidget*> conts = client->factory()->containers("menu"); 02466 foreach (QWidget *w, conts) 02467 { 02468 if (w->objectName() == "ktexteditor_popup") 02469 {//perhaps optimize this block 02470 QMenu* menu=(QMenu*)w; 02471 disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowContextMenu())); 02472 disconnect(menu, SIGNAL(aboutToHide()), this, SLOT(aboutToHideContextMenu())); 02473 connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowContextMenu())); 02474 connect(menu, SIGNAL(aboutToHide()), this, SLOT(aboutToHideContextMenu())); 02475 return menu; 02476 } 02477 } 02478 } 02479 } 02480 return 0; 02481 } 02482 02483 QMenu * KateView::defaultContextMenu(QMenu* menu) const 02484 { 02485 if (!menu) 02486 menu = new KMenu(const_cast<KateView*>(this)); 02487 02488 menu->addAction(m_editUndo); 02489 menu->addAction(m_editRedo); 02490 menu->addSeparator(); 02491 menu->addAction(m_cut); 02492 menu->addAction(m_copy); 02493 menu->addAction(m_paste); 02494 menu->addSeparator(); 02495 menu->addAction(m_selectAll); 02496 menu->addAction(m_deSelect); 02497 if (QAction *spellingSuggestions = actionCollection()->action("spelling_suggestions")) { 02498 menu->addSeparator(); 02499 menu->addAction(spellingSuggestions); 02500 } 02501 if (QAction* bookmark = actionCollection()->action("bookmarks")) { 02502 menu->addSeparator(); 02503 menu->addAction(bookmark); 02504 } 02505 return menu; 02506 } 02507 02508 void KateView::aboutToShowContextMenu( ) 02509 { 02510 QMenu* menu = qobject_cast<QMenu*>(sender()); 02511 02512 if (menu) { 02513 emit contextMenuAboutToShow(this, menu); 02514 } 02515 } 02516 02517 void KateView::aboutToHideContextMenu( ) 02518 { 02519 m_spellingMenu->setUseMouseForMisspelledRange(false); 02520 } 02521 02522 // BEGIN ConfigInterface stff 02523 QStringList KateView::configKeys() const 02524 { 02525 return QStringList() << "icon-bar" << "line-numbers" << "dynamic-word-wrap" 02526 << "background-color" << "selection-color"; 02527 } 02528 02529 QVariant KateView::configValue(const QString &key) 02530 { 02531 if (key == "icon-bar") 02532 return config()->iconBar(); 02533 else if (key == "line-numbers") 02534 return config()->lineNumbers(); 02535 else if (key == "dynamic-word-wrap") 02536 return config()->dynWordWrap(); 02537 else if (key == "background-color") 02538 return renderer()->config()->backgroundColor(); 02539 else if (key == "selection-color") 02540 return renderer()->config()->selectionColor(); 02541 else if (key == "default-mark-type") 02542 return config()->defaultMarkType(); 02543 else if (key == "allow-mark-menu") 02544 return config()->allowMarkMenu(); 02545 02546 // return invalid variant 02547 return QVariant(); 02548 } 02549 02550 void KateView::setConfigValue(const QString &key, const QVariant &value) 02551 { 02552 if ( value.canConvert(QVariant::Color) ) { 02553 if (key == "background-color") 02554 renderer()->config()->setBackgroundColor(value.value<QColor>()); 02555 else if (key == "selection-color") 02556 renderer()->config()->setSelectionColor(value.value<QColor>()); 02557 } else if ( value.type() == QVariant::Bool ) { 02558 // Note explicit type check above. If we used canConvert, then 02559 // values of type UInt will be trapped here. 02560 if (key == "icon-bar") 02561 config()->setIconBar(value.toBool()); 02562 else if (key == "line-numbers") 02563 config()->setLineNumbers(value.toBool()); 02564 else if (key == "dynamic-word-wrap") 02565 config()->setDynWordWrap(value.toBool()); 02566 else if (key == "allow-mark-menu") 02567 config()->setAllowMarkMenu(value.toBool()); 02568 } else if ( value.canConvert(QVariant::UInt) ) { 02569 if (key == "default-mark-type") 02570 config()->setDefaultMarkType(value.toUInt()); 02571 } 02572 } 02573 02574 // END ConfigInterface 02575 02576 void KateView::userInvokedCompletion() 02577 { 02578 completionWidget()->userInvokedCompletion(); 02579 } 02580 02581 KateViewBar *KateView::topViewBar() const 02582 { 02583 return m_topViewBar; 02584 } 02585 02586 KateViewBar *KateView::bottomViewBar() const 02587 { 02588 return m_bottomViewBar; 02589 } 02590 02591 KateCommandLineBar *KateView::cmdLineBar () 02592 { 02593 if (!m_cmdLine) { 02594 m_cmdLine = new KateCommandLineBar (this, bottomViewBar()); 02595 bottomViewBar()->addBarWidget(m_cmdLine); 02596 } 02597 02598 return m_cmdLine; 02599 } 02600 02601 KateSearchBar *KateView::searchBar (bool initHintAsPower) 02602 { 02603 if (!m_searchBar) { 02604 m_searchBar = new KateSearchBar(initHintAsPower, this, KateViewConfig::global()); 02605 bottomViewBar()->addBarWidget(m_searchBar); 02606 } 02607 return m_searchBar; 02608 } 02609 02610 KateViModeBar *KateView::viModeBar() 02611 { 02612 if (!m_viModeBar) { 02613 m_viModeBar = new KateViModeBar(this); 02614 } 02615 02616 return m_viModeBar; 02617 } 02618 02619 KateGotoBar *KateView::gotoBar () 02620 { 02621 if (!m_gotoBar) { 02622 m_gotoBar = new KateGotoBar (this); 02623 bottomViewBar()->addBarWidget(m_gotoBar); 02624 } 02625 02626 return m_gotoBar; 02627 } 02628 02629 KateDictionaryBar *KateView::dictionaryBar () 02630 { 02631 if(!m_dictionaryBar) { 02632 m_dictionaryBar = new KateDictionaryBar(this); 02633 bottomViewBar()->addBarWidget(m_dictionaryBar); 02634 } 02635 02636 return m_dictionaryBar; 02637 } 02638 02639 void KateView::setAnnotationModel( KTextEditor::AnnotationModel* model ) 02640 { 02641 KTextEditor::AnnotationModel* oldmodel = m_annotationModel; 02642 m_annotationModel = model; 02643 m_viewInternal->m_leftBorder->annotationModelChanged(oldmodel, m_annotationModel); 02644 } 02645 02646 KTextEditor::AnnotationModel* KateView::annotationModel() const 02647 { 02648 return m_annotationModel; 02649 } 02650 02651 void KateView::setAnnotationBorderVisible( bool visible ) 02652 { 02653 m_viewInternal->m_leftBorder->setAnnotationBorderOn( visible ); 02654 } 02655 02656 bool KateView::isAnnotationBorderVisible() const 02657 { 02658 return m_viewInternal->m_leftBorder->annotationBorderOn(); 02659 } 02660 02661 KTextEditor::Range KateView::visibleRange() 02662 { 02663 //ensure that the view is up-to-date, otherwise 'endPos()' might fail! 02664 m_viewInternal->updateView(); 02665 return KTextEditor::Range(m_viewInternal->toRealCursor(m_viewInternal->startPos()), 02666 m_viewInternal->toRealCursor(m_viewInternal->endPos())); 02667 } 02668 02669 void KateView::toggleOnTheFlySpellCheck(bool b) 02670 { 02671 m_doc->onTheFlySpellCheckingEnabled(b); 02672 } 02673 02674 void KateView::reflectOnTheFlySpellCheckStatus(bool enabled) 02675 { 02676 m_spellingMenu->setVisible(enabled); 02677 m_toggleOnTheFlySpellCheck->setChecked(enabled); 02678 } 02679 02680 KateSpellingMenu* KateView::spellingMenu() 02681 { 02682 return m_spellingMenu; 02683 } 02684 02685 void KateView::notifyAboutRangeChange (int startLine, int endLine, bool rangeWithAttribute) 02686 { 02687 #ifdef VIEW_RANGE_DEBUG 02688 // output args 02689 kDebug() << "trigger attribute changed from" << startLine << "to" << endLine << "rangeWithAttribute" << rangeWithAttribute; 02690 #endif 02691 02692 // first call: 02693 if (!m_delayedUpdateTriggered) { 02694 m_delayedUpdateTriggered = true; 02695 m_lineToUpdateMin = -1; 02696 m_lineToUpdateMax = -1; 02697 02698 // only set initial line range, if range with attribute! 02699 if (rangeWithAttribute) { 02700 m_lineToUpdateMin = startLine; 02701 m_lineToUpdateMax = endLine; 02702 } 02703 02704 // emit queued signal and be done 02705 emit delayedUpdateOfView (); 02706 return; 02707 } 02708 02709 // ignore lines if no attribute 02710 if (!rangeWithAttribute) 02711 return; 02712 02713 // update line range 02714 if (startLine != -1 && (m_lineToUpdateMin == -1 || startLine < m_lineToUpdateMin)) 02715 m_lineToUpdateMin = startLine; 02716 02717 if (endLine != -1 && endLine > m_lineToUpdateMax) 02718 m_lineToUpdateMax = endLine; 02719 } 02720 02721 void KateView::slotDelayedUpdateOfView () 02722 { 02723 if (!m_delayedUpdateTriggered) 02724 return; 02725 02726 #ifdef VIEW_RANGE_DEBUG 02727 // output args 02728 kDebug() << "delayed attribute changed from" << m_lineToUpdateMin << "to" << m_lineToUpdateMax; 02729 #endif 02730 02731 // update ranges in 02732 updateRangesIn (KTextEditor::Attribute::ActivateMouseIn); 02733 updateRangesIn (KTextEditor::Attribute::ActivateCaretIn); 02734 02735 // update view, if valid line range, else only feedback update wanted anyway 02736 if (m_lineToUpdateMin != -1 && m_lineToUpdateMax != -1) { 02737 tagLines (m_lineToUpdateMin, m_lineToUpdateMax, true); 02738 updateView (true); 02739 } 02740 02741 // reset flags 02742 m_delayedUpdateTriggered = false; 02743 m_lineToUpdateMin = -1; 02744 m_lineToUpdateMax = -1; 02745 } 02746 02747 void KateView::updateRangesIn (KTextEditor::Attribute::ActivationType activationType) 02748 { 02749 // new ranges with cursor in, default none 02750 QSet<Kate::TextRange *> newRangesIn; 02751 02752 // on which range set we work? 02753 QSet<Kate::TextRange *> &oldSet = (activationType == KTextEditor::Attribute::ActivateMouseIn) ? m_rangesMouseIn : m_rangesCaretIn; 02754 02755 // which cursor position to honor? 02756 KTextEditor::Cursor currentCursor = (activationType == KTextEditor::Attribute::ActivateMouseIn) ? m_viewInternal->getMouse() : m_viewInternal->getCursor (); 02757 02758 // first: validate the remembered ranges 02759 QSet<Kate::TextRange *> validRanges; 02760 foreach (Kate::TextRange *range, oldSet) 02761 if (m_doc->buffer().rangePointerValid(range)) 02762 validRanges.insert (range); 02763 02764 // cursor valid? else no new ranges can be found 02765 if (currentCursor.isValid () && currentCursor.line() < m_doc->buffer().lines()) { 02766 // now: get current ranges for the line of cursor with an attribute 02767 QList<Kate::TextRange *> rangesForCurrentCursor = m_doc->buffer().rangesForLine (currentCursor.line(), this, false); 02768 02769 // match which ranges really fit the given cursor 02770 foreach (Kate::TextRange *range, rangesForCurrentCursor) { 02771 // range has no dynamic attribute of right type and no feedback object 02772 if ((!range->attribute() || !range->attribute()->dynamicAttribute (activationType)) && !range->feedback()) 02773 continue; 02774 02775 // range doesn't contain cursor, not interesting 02776 if ((range->start().insertBehavior() == KTextEditor::MovingCursor::StayOnInsert) 02777 ? (currentCursor < range->start().toCursor ()) : (currentCursor <= range->start().toCursor ())) 02778 continue; 02779 02780 if ((range->end().insertBehavior() == KTextEditor::MovingCursor::StayOnInsert) 02781 ? (range->end().toCursor () <= currentCursor) : (range->end().toCursor () < currentCursor)) 02782 continue; 02783 02784 // range contains cursor, was it already in old set? 02785 if (validRanges.contains (range)) { 02786 // insert in new, remove from old, be done with it 02787 newRangesIn.insert (range); 02788 validRanges.remove (range); 02789 continue; 02790 } 02791 02792 // oh, new range, trigger update and insert into new set 02793 newRangesIn.insert (range); 02794 02795 if (range->attribute() && range->attribute()->dynamicAttribute (activationType)) 02796 notifyAboutRangeChange (range->start().line(), range->end().line(), true); 02797 02798 // feedback 02799 if (range->feedback ()) { 02800 if (activationType == KTextEditor::Attribute::ActivateMouseIn) 02801 range->feedback ()->mouseEnteredRange (range, this); 02802 else 02803 range->feedback ()->caretEnteredRange (range, this); 02804 } 02805 02806 #ifdef VIEW_RANGE_DEBUG 02807 // found new range for activation 02808 kDebug() << "activated new range" << range << "by" << activationType; 02809 #endif 02810 } 02811 } 02812 02813 // now: notify for left ranges! 02814 foreach (Kate::TextRange *range, validRanges) { 02815 // range valid + right dynamic attribute, trigger update 02816 if (range->toRange().isValid() && range->attribute() && range->attribute()->dynamicAttribute (activationType)) 02817 notifyAboutRangeChange (range->start().line(), range->end().line(), true); 02818 02819 // feedback 02820 if (range->feedback ()) { 02821 if (activationType == KTextEditor::Attribute::ActivateMouseIn) 02822 range->feedback ()->mouseExitedRange (range, this); 02823 else 02824 range->feedback ()->caretExitedRange (range, this); 02825 } 02826 } 02827 02828 // set new ranges 02829 oldSet = newRangesIn; 02830 } 02831 02832 void KateView::showRecoverBar() 02833 { 02834 hideBrokenSwapFileBar(); 02835 02836 topViewBar()->showBarWidget(recoverBar()); 02837 } 02838 02839 KateRecoverBar* KateView::recoverBar() 02840 { 02841 if (!m_recoverBar) { 02842 m_recoverBar = new KateRecoverBar(this); 02843 topViewBar()->addBarWidget(m_recoverBar); 02844 } 02845 return m_recoverBar; 02846 } 02847 02848 void KateView::hideRecoverBar() 02849 { 02850 if (m_recoverBar) 02851 { 02852 topViewBar()->removeBarWidget(m_recoverBar); 02853 delete m_recoverBar; 02854 m_recoverBar = 0; 02855 } 02856 } 02857 02858 void KateView::showBrokenSwapFileBar() 02859 { 02860 hideRecoverBar(); 02861 02862 topViewBar()->showBarWidget(brokenSwapFileBar()); 02863 } 02864 02865 KateBrokenSwapFileBar* KateView::brokenSwapFileBar() 02866 { 02867 if (!m_brokenSwapFileBar) { 02868 m_brokenSwapFileBar = new KateBrokenSwapFileBar(this); 02869 topViewBar()->addBarWidget(m_brokenSwapFileBar); 02870 } 02871 return m_brokenSwapFileBar; 02872 } 02873 02874 void KateView::hideBrokenSwapFileBar() 02875 { 02876 if (m_brokenSwapFileBar) 02877 { 02878 topViewBar()->removeBarWidget(m_brokenSwapFileBar); 02879 delete m_brokenSwapFileBar; 02880 m_brokenSwapFileBar = 0; 02881 } 02882 } 02883 02884 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE 4.6 API Reference