00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "katedocument.h"
00023
#include "katedocument.moc"
00024
00025
#include "katefactory.h"
00026
#include "katedialogs.h"
00027
#include "katehighlight.h"
00028
#include "kateview.h"
00029
#include "kateviewinternal.h"
00030
#include "katesearch.h"
00031
#include "kateautoindent.h"
00032
#include "katetextline.h"
00033
#include "katedocumenthelpers.h"
00034
#include "katebuffer.h"
00035
#include "katecodefoldinghelpers.h"
00036
#include "kateundo.h"
00037
#include "kateprinter.h"
00038
#include "katelinerange.h"
00039
#include "katesupercursor.h"
00040
#include "katearbitraryhighlight.h"
00041
#include "katerenderer.h"
00042
#include "kateattribute.h"
00043
#include "kateconfig.h"
00044
#include "katefiletype.h"
00045
#include "kateschema.h"
00046
00047
#include <ktexteditor/plugin.h>
00048
00049
#include <kio/job.h>
00050
#include <kio/netaccess.h>
00051
00052
#include <kparts/event.h>
00053
00054
#include <klocale.h>
00055
#include <kglobal.h>
00056
#include <kapplication.h>
00057
#include <kpopupmenu.h>
00058
#include <kconfig.h>
00059
#include <kfiledialog.h>
00060
#include <kmessagebox.h>
00061
#include <kspell.h>
00062
#include <kstdaction.h>
00063
#include <kiconloader.h>
00064
#include <kxmlguifactory.h>
00065
#include <kdialogbase.h>
00066
#include <kdebug.h>
00067
#include <kglobalsettings.h>
00068
#include <ksavefile.h>
00069
#include <klibloader.h>
00070
#include <kdirwatch.h>
00071
#include <kwin.h>
00072
#include <kencodingfiledialog.h>
00073
#include <ktempfile.h>
00074
#include <kmdcodec.h>
00075
#include <kmimetype.h>
00076
00077
#include <qtimer.h>
00078
#include <qfile.h>
00079
#include <qclipboard.h>
00080
#include <qtextstream.h>
00081
#include <qtextcodec.h>
00082
#include <qmap.h>
00083
00084
00085
00086
class KatePartPluginItem
00087 {
00088
public:
00089 KTextEditor::Plugin *plugin;
00090 };
00091
00092
00093
00094
00095
00096
00097 KateDocument::KateDocument (
bool bSingleViewMode,
bool bBrowserView,
00098
bool bReadOnly,
QWidget *parentWidget,
00099
const char *widgetName,
QObject *parent,
const char *name)
00100 : Kate::Document(parent,
name),
00101 m_plugins (KateFactory::self()->plugins().count()),
00102 selectStart(this, true),
00103 selectEnd(this, true),
00104 m_undoDontMerge(false),
00105 m_undoIgnoreCancel(false),
00106 lastUndoGroupWhenSaved( 0 ),
00107 docWasSavedWhenUndoWasEmpty( true ),
00108 m_modOnHd (false),
00109 m_modOnHdReason (0),
00110 m_job (0),
00111 m_tempFile (0),
00112 m_imStartLine( 0 ),
00113 m_imStart( 0 ),
00114 m_imEnd( 0 ),
00115 m_imSelStart( 0 ),
00116 m_imSelEnd( 0 ),
00117 m_imComposeEvent( false )
00118 {
00119
00120 setObjId (
"KateDocument#"+documentDCOPSuffix());
00121
00122
00123 setBlockSelectionInterfaceDCOPSuffix (documentDCOPSuffix());
00124 setConfigInterfaceDCOPSuffix (documentDCOPSuffix());
00125 setConfigInterfaceExtensionDCOPSuffix (documentDCOPSuffix());
00126 setCursorInterfaceDCOPSuffix (documentDCOPSuffix());
00127 setEditInterfaceDCOPSuffix (documentDCOPSuffix());
00128 setEncodingInterfaceDCOPSuffix (documentDCOPSuffix());
00129 setHighlightingInterfaceDCOPSuffix (documentDCOPSuffix());
00130 setMarkInterfaceDCOPSuffix (documentDCOPSuffix());
00131 setMarkInterfaceExtensionDCOPSuffix (documentDCOPSuffix());
00132 setPrintInterfaceDCOPSuffix (documentDCOPSuffix());
00133 setSearchInterfaceDCOPSuffix (documentDCOPSuffix());
00134 setSelectionInterfaceDCOPSuffix (documentDCOPSuffix());
00135 setSelectionInterfaceExtDCOPSuffix (documentDCOPSuffix());
00136 setSessionConfigInterfaceDCOPSuffix (documentDCOPSuffix());
00137 setUndoInterfaceDCOPSuffix (documentDCOPSuffix());
00138 setWordWrapInterfaceDCOPSuffix (documentDCOPSuffix());
00139
00140
00141 m_plugins.fill (0);
00142
00143
00144 KateFactory::self()->registerDocument (
this);
00145
00146 m_reloading =
false;
00147
00148 buffer =
new KateBuffer (
this);
00149
00150
00151
00152 m_config =
new KateDocumentConfig (
this);
00153
00154
00155 m_activeView = 0L;
00156
00157 hlSetByUser =
false;
00158 m_fileType = -1;
00159 m_fileTypeSetByUser =
false;
00160 setInstance( KateFactory::self()->
instance() );
00161
00162 editSessionNumber = 0;
00163 editIsRunning =
false;
00164 noViewUpdates =
false;
00165 m_editCurrentUndo = 0L;
00166 editWithUndo =
false;
00167 editTagFrom =
false;
00168
00169 m_docNameNumber = 0;
00170
00171 m_kspell = 0;
00172 m_mispellCount = 0;
00173 m_replaceCount = 0;
00174
00175 blockSelect =
false;
00176
00177 m_bSingleViewMode = bSingleViewMode;
00178 m_bBrowserView = bBrowserView;
00179 m_bReadOnly = bReadOnly;
00180
00181 m_marks.setAutoDelete(
true );
00182 m_markPixmaps.setAutoDelete(
true );
00183 m_markDescriptions.setAutoDelete(
true );
00184 setMarksUserChangable( markType01 );
00185
00186 m_highlight = 0L;
00187
00188 m_undoMergeTimer =
new QTimer(
this);
00189 connect(m_undoMergeTimer, SIGNAL(timeout()), SLOT(undoCancel()));
00190
00191 clearMarks ();
00192 clearUndo ();
00193 clearRedo ();
00194 setModified (
false);
00195 internalSetHlMode (0);
00196 docWasSavedWhenUndoWasEmpty =
true;
00197
00198 m_extension =
new KateBrowserExtension(
this );
00199 m_arbitraryHL =
new KateArbitraryHighlight();
00200 m_indenter = KateAutoIndent::createIndenter (
this, 0 );
00201
00202 m_indenter->updateConfig ();
00203
00204
00205 connect(buffer, SIGNAL(linesChanged(
int)),
this, SLOT(slotBufferChanged()));
00206 connect(buffer, SIGNAL(tagLines(
int,
int)),
this, SLOT(tagLines(
int,
int)));
00207 connect(buffer, SIGNAL(codeFoldingUpdated()),
this,SIGNAL(codeFoldingUpdated()));
00208
00209
00210 connect(HlManager::self(),SIGNAL(changed()),SLOT(internalHlChanged()));
00211
00212
00213 connect(m_arbitraryHL, SIGNAL(tagLines(KateView*,
KateSuperRange*)), SLOT(tagArbitraryLines(KateView*,
KateSuperRange*)));
00214
00215
00216 connect( KateFactory::self()->dirWatch(), SIGNAL(dirty (
const QString &)),
00217
this, SLOT(slotModOnHdDirty (
const QString &)) );
00218
00219 connect( KateFactory::self()->dirWatch(), SIGNAL(created (
const QString &)),
00220
this, SLOT(slotModOnHdCreated (
const QString &)) );
00221
00222 connect( KateFactory::self()->dirWatch(), SIGNAL(deleted (
const QString &)),
00223
this, SLOT(slotModOnHdDeleted (
const QString &)) );
00224
00225
00226 setDocName (
"");
00227
00228
00229
if ( m_bSingleViewMode )
00230 {
00231 KTextEditor::View *view = createView( parentWidget, widgetName );
00232 insertChildClient( view );
00233 view->show();
00234 setWidget( view );
00235 }
00236
00237 connect(
this,SIGNAL(sigQueryClose(
bool *,
bool*)),
this,SLOT(slotQueryClose_save(
bool *,
bool*)));
00238 }
00239
00240
00241
00242
00243 KateDocument::~KateDocument()
00244 {
00245
00246 deactivateDirWatch ();
00247
00248
if (!singleViewMode())
00249 {
00250
00251 m_views.setAutoDelete(
true );
00252 m_views.clear();
00253 }
00254
00255 m_highlight->release();
00256
00257
delete m_editCurrentUndo;
00258
00259
delete m_arbitraryHL;
00260
00261
00262 undoItems.setAutoDelete(
true);
00263 undoItems.clear();
00264
00265
00266 unloadAllPlugins ();
00267
00268
00269
if( m_kspell )
00270 {
00271 m_kspell->setAutoDelete(
true);
00272 m_kspell->cleanUp();
00273
delete m_kspell;
00274 }
00275
00276
delete m_config;
00277
delete m_indenter;
00278 KateFactory::self()->deregisterDocument (
this);
00279 }
00280
00281
00282
00283
void KateDocument::unloadAllPlugins ()
00284 {
00285
for (uint i=0; i<m_plugins.count(); i++)
00286 unloadPlugin (i);
00287 }
00288
00289
void KateDocument::enableAllPluginsGUI (KateView *view)
00290 {
00291
for (uint i=0; i<m_plugins.count(); i++)
00292 enablePluginGUI (m_plugins[i], view);
00293 }
00294
00295
void KateDocument::disableAllPluginsGUI (KateView *view)
00296 {
00297
for (uint i=0; i<m_plugins.count(); i++)
00298 disablePluginGUI (m_plugins[i], view);
00299 }
00300
00301
void KateDocument::loadPlugin (uint pluginIndex)
00302 {
00303
if (m_plugins[pluginIndex])
return;
00304
00305 m_plugins[pluginIndex] = KTextEditor::createPlugin (QFile::encodeName((KateFactory::self()->plugins())[pluginIndex]->library()),
this);
00306
00307 enablePluginGUI (m_plugins[pluginIndex]);
00308 }
00309
00310
void KateDocument::unloadPlugin (uint pluginIndex)
00311 {
00312
if (!m_plugins[pluginIndex])
return;
00313
00314 disablePluginGUI (m_plugins[pluginIndex]);
00315
00316
delete m_plugins[pluginIndex];
00317 m_plugins[pluginIndex] = 0L;
00318 }
00319
00320
void KateDocument::enablePluginGUI (KTextEditor::Plugin *plugin, KateView *view)
00321 {
00322
if (!plugin)
return;
00323
if (!KTextEditor::pluginViewInterface(plugin))
return;
00324
00325
KXMLGUIFactory *factory = view->factory();
00326
if ( factory )
00327 factory->
removeClient( view );
00328
00329 KTextEditor::pluginViewInterface(plugin)->addView(view);
00330
00331
if ( factory )
00332 factory->
addClient( view );
00333 }
00334
00335
void KateDocument::enablePluginGUI (KTextEditor::Plugin *plugin)
00336 {
00337
if (!plugin)
return;
00338
if (!KTextEditor::pluginViewInterface(plugin))
return;
00339
00340
for (uint i=0; i< m_views.count(); i++)
00341 enablePluginGUI (plugin, m_views.at(i));
00342 }
00343
00344
void KateDocument::disablePluginGUI (KTextEditor::Plugin *plugin, KateView *view)
00345 {
00346
if (!plugin)
return;
00347
if (!KTextEditor::pluginViewInterface(plugin))
return;
00348
00349
KXMLGUIFactory *factory = view->factory();
00350
if ( factory )
00351 factory->
removeClient( view );
00352
00353 KTextEditor::pluginViewInterface( plugin )->removeView( view );
00354
00355
if ( factory )
00356 factory->
addClient( view );
00357 }
00358
00359
void KateDocument::disablePluginGUI (KTextEditor::Plugin *plugin)
00360 {
00361
if (!plugin)
return;
00362
if (!KTextEditor::pluginViewInterface(plugin))
return;
00363
00364
for (uint i=0; i< m_views.count(); i++)
00365 disablePluginGUI (plugin, m_views.at(i));
00366 }
00367
00368
00369
00370
00371 KTextEditor::View *KateDocument::createView(
QWidget *parent,
const char *name )
00372 {
00373 KateView* newView =
new KateView(
this, parent, name);
00374 connect(newView, SIGNAL(cursorPositionChanged()), SLOT(undoCancel()));
00375
return newView;
00376 }
00377
00378
QPtrList<KTextEditor::View> KateDocument::views ()
const
00379
{
00380
return m_textEditViews;
00381 }
00382
00383
00384
00385
00386 uint KateDocument::configPages ()
const
00387
{
00388
return 11;
00389 }
00390
00391 KTextEditor::ConfigPage *KateDocument::configPage (uint number,
QWidget *parent,
const char * )
00392 {
00393
switch(
number )
00394 {
00395
case 0:
00396
return colorConfigPage (parent);
00397
00398
case 1:
00399
return editConfigPage (parent);
00400
00401
case 2:
00402
return keysConfigPage (parent);
00403
00404
case 3:
00405
return indentConfigPage(parent);
00406
00407
case 4:
00408
return selectConfigPage(parent);
00409
00410
case 5:
00411
return saveConfigPage( parent );
00412
00413
case 6:
00414
return viewDefaultsConfigPage(parent);
00415
00416
case 7:
00417
return hlConfigPage (parent);
00418
00419
case 9:
00420
return new SpellConfigPage (parent);
00421
00422
case 10:
00423
return new PluginConfigPage (parent);
00424
00425
case 8:
00426
return new KateFileTypeConfigTab (parent);
00427
00428
default:
00429
return 0;
00430 }
00431 }
00432
00433 QString KateDocument::configPageName (uint number)
const
00434
{
00435
switch(
number )
00436 {
00437
case 0:
00438
return i18n (
"Schemas");
00439
00440
case 3:
00441
return i18n (
"Indentation");
00442
00443
case 4:
00444
return i18n (
"Selection");
00445
00446
case 1:
00447
return i18n (
"Editing");
00448
00449
case 2:
00450
return i18n (
"Shortcuts");
00451
00452
case 7:
00453
return i18n (
"Highlighting");
00454
00455
case 6:
00456
return i18n (
"View Defaults");
00457
00458
case 10:
00459
return i18n (
"Plugins");
00460
00461
case 5:
00462
return i18n(
"Open/Save");
00463
00464
case 9:
00465
return i18n(
"Spelling");
00466
00467
case 8:
00468
return i18n(
"Filetypes");
00469
00470
default:
00471
return 0;
00472 }
00473 }
00474
00475 QString KateDocument::configPageFullName (uint number)
const
00476
{
00477
switch(
number )
00478 {
00479
case 0:
00480
return i18n (
"Color & Font Schemas");
00481
00482
case 3:
00483
return i18n (
"Indentation Rules");
00484
00485
case 4:
00486
return i18n (
"Selection Behavior");
00487
00488
case 1:
00489
return i18n (
"Editing Options");
00490
00491
case 2:
00492
return i18n (
"Shortcuts Configuration");
00493
00494
case 7:
00495
return i18n (
"Highlighting Rules");
00496
00497
case 6:
00498
return i18n(
"View Defaults");
00499
00500
case 10:
00501
return i18n (
"Plugin Manager");
00502
00503
case 5:
00504
return i18n(
"File Opening & Saving");
00505
00506
case 9:
00507
return i18n(
"Spell Checker Behavior");
00508
00509
case 8:
00510
return i18n(
"Filetype Specific Settings");
00511
00512
default:
00513
return 0;
00514 }
00515 }
00516
00517
QPixmap KateDocument::configPagePixmap (uint number,
int size)
const
00518
{
00519
switch(
number )
00520 {
00521
case 0:
00522
return BarIcon(
"colorize", size);
00523
00524
case 3:
00525
return BarIcon(
"rightjust", size);
00526
00527
case 4:
00528
return BarIcon(
"frame_edit", size);
00529
00530
case 1:
00531
return BarIcon(
"edit", size);
00532
00533
case 2:
00534
return BarIcon(
"key_enter", size);
00535
00536
case 7:
00537
return BarIcon(
"source", size);
00538
00539
case 6:
00540
return BarIcon(
"view_text",size);
00541
00542
case 10:
00543
return BarIcon(
"connect_established", size);
00544
00545
case 5:
00546
return BarIcon(
"filesave", size);
00547
00548
case 9:
00549
return BarIcon(
"spellcheck", size);
00550
00551
case 8:
00552
return BarIcon(
"edit", size);
00553
00554
default:
00555
return 0;
00556 }
00557 }
00558
00559
00560
00561
00562 QString KateDocument::text()
const
00563
{
00564
return buffer->text();
00565 }
00566
00567 QString KateDocument::text ( uint startLine, uint startCol, uint endLine, uint endCol )
const
00568
{
00569
return text(startLine, startCol, endLine, endCol,
false);
00570 }
00571
00572 QString KateDocument::text ( uint startLine, uint startCol, uint endLine, uint endCol,
bool blockwise)
const
00573
{
00574
return buffer->text(startLine, startCol, endLine, endCol, blockwise);
00575 }
00576
00577 QString KateDocument::textLine( uint line )
const
00578
{
00579
return buffer->textLine(line);
00580 }
00581
00582
bool KateDocument::setText(
const QString &s)
00583 {
00584
if (!isReadWrite())
00585
return false;
00586
00587
QPtrList<KTextEditor::Mark> m = marks ();
00588
QValueList<KTextEditor::Mark> msave;
00589
00590
for (uint i=0; i < m.
count(); i++)
00591 msave.
append (*m.
at(i));
00592
00593 editStart ();
00594
00595
00596
clear();
00597
00598
00599 insertText (0, 0, s);
00600
00601 editEnd ();
00602
00603
for (uint i=0; i < msave.
count(); i++)
00604 setMark (msave[i].line, msave[i].type);
00605
00606
return true;
00607 }
00608
00609
bool KateDocument::clear()
00610 {
00611
if (!isReadWrite())
00612
return false;
00613
00614
for (KateView * view = m_views.first(); view != 0L; view = m_views.next() ) {
00615 view->clear();
00616 view->tagAll();
00617 view->update();
00618 }
00619
00620 clearMarks ();
00621
00622
return removeText (0,0,lastLine()+1, 0);
00623 }
00624
00625
bool KateDocument::insertText( uint line, uint col,
const QString &s)
00626 {
00627
return insertText (line, col, s,
false);
00628 }
00629
00630
bool KateDocument::insertText( uint line, uint col,
const QString &s,
bool blockwise )
00631 {
00632
if (!isReadWrite())
00633
return false;
00634
00635
if (s.
isEmpty())
00636
return true;
00637
00638
if (line == numLines())
00639 editInsertLine(line,
"");
00640
else if (line > lastLine())
00641
return false;
00642
00643 editStart ();
00644
00645 uint insertPos = col;
00646 uint len = s.
length();
00647 QString buf;
00648
00649
for (uint pos = 0; pos < len; pos++)
00650 {
00651
QChar ch = s[pos];
00652
00653
if (ch ==
'\n')
00654 {
00655
if ( !blockwise )
00656 {
00657 editInsertText (line, insertPos, buf);
00658 editWrapLine (line, insertPos + buf.
length());
00659 }
00660
else
00661 {
00662 editInsertText (line, col, buf);
00663
00664
if ( line == lastLine() )
00665 editWrapLine (line, col + buf.
length());
00666 }
00667
00668 line++;
00669 insertPos = 0;
00670 buf.
truncate(0);
00671 }
00672
else
00673 buf += ch;
00674 }
00675
00676
if ( !blockwise )
00677 editInsertText (line, insertPos, buf);
00678
else
00679 editInsertText (line, col, buf);
00680
00681 editEnd ();
00682
00683
return true;
00684 }
00685
00686
bool KateDocument::removeText ( uint startLine, uint startCol, uint endLine, uint endCol )
00687 {
00688
return removeText (startLine, startCol, endLine, endCol,
false);
00689 }
00690
00691
bool KateDocument::removeText ( uint startLine, uint startCol, uint endLine, uint endCol,
bool blockwise )
00692 {
00693
if (!isReadWrite())
00694
return false;
00695
00696
if ( blockwise && (startCol > endCol) )
00697
return false;
00698
00699
if ( startLine > endLine )
00700
return false;
00701
00702
if ( startLine > lastLine() )
00703
return false;
00704
00705 editStart ();
00706
00707
if ( !blockwise )
00708 {
00709
if ( endLine > lastLine() )
00710 {
00711 endLine = lastLine()+1;
00712 endCol = 0;
00713 }
00714
00715
if (startLine == endLine)
00716 {
00717 editRemoveText (startLine, startCol, endCol-startCol);
00718 }
00719
else if ((startLine+1) == endLine)
00720 {
00721
if ( (buffer->plainLine(startLine)->length()-startCol) > 0 )
00722 editRemoveText (startLine, startCol, buffer->plainLine(startLine)->length()-startCol);
00723
00724 editRemoveText (startLine+1, 0, endCol);
00725 editUnWrapLine (startLine);
00726 }
00727
else
00728 {
00729
for (uint line = endLine; line >= startLine; line--)
00730 {
00731
if ((line > startLine) && (line < endLine))
00732 {
00733 editRemoveLine (line);
00734 }
00735
else
00736 {
00737
if (line == endLine)
00738 {
00739
if ( endLine <= lastLine() )
00740 editRemoveText (line, 0, endCol);
00741 }
00742
else
00743 {
00744
if ( (buffer->plainLine(line)->length()-startCol) > 0 )
00745 editRemoveText (line, startCol, buffer->plainLine(line)->length()-startCol);
00746
00747 editUnWrapLine (startLine);
00748 }
00749 }
00750
00751
if ( line == 0 )
00752
break;
00753 }
00754 }
00755 }
00756
else
00757 {
00758
if ( endLine > lastLine() )
00759 endLine = lastLine ();
00760
00761
for (uint line = endLine; line >= startLine; line--)
00762 {
00763 editRemoveText (line, startCol, endCol-startCol);
00764
00765
if ( line == 0 )
00766
break;
00767 }
00768 }
00769
00770 editEnd ();
00771
00772
return true;
00773 }
00774
00775
bool KateDocument::insertLine( uint l,
const QString &str )
00776 {
00777
if (!isReadWrite())
00778
return false;
00779
00780
if (l > numLines())
00781
return false;
00782
00783
return editInsertLine (l, str);
00784 }
00785
00786
bool KateDocument::removeLine( uint line )
00787 {
00788
if (!isReadWrite())
00789
return false;
00790
00791
if (line > lastLine())
00792
return false;
00793
00794
return editRemoveLine (line);
00795 }
00796
00797 uint KateDocument::length()
const
00798
{
00799
return buffer->length();
00800 }
00801
00802 uint KateDocument::numLines()
const
00803
{
00804
return buffer->count();
00805 }
00806
00807 uint KateDocument::numVisLines()
const
00808
{
00809
return buffer->countVisible ();
00810 }
00811
00812
int KateDocument::lineLength ( uint line )
const
00813
{
00814
return buffer->lineLength(line);
00815 }
00816
00817
00818
00819
00820
00821
00822
void KateDocument::editStart (
bool withUndo)
00823 {
00824 editSessionNumber++;
00825
00826
if (editSessionNumber > 1)
00827
return;
00828
00829 buffer->setHlUpdate (
false);
00830
00831 editIsRunning =
true;
00832 noViewUpdates =
true;
00833 editWithUndo = withUndo;
00834
00835 editTagLineStart = 0xffffff;
00836 editTagLineEnd = 0;
00837 editTagFrom =
false;
00838
00839
if (editWithUndo)
00840 undoStart();
00841
else
00842 undoCancel();
00843
00844
for (uint z = 0; z < m_views.count(); z++)
00845 {
00846 m_views.at(z)->editStart ();
00847 }
00848 }
00849
00850
void KateDocument::undoStart()
00851 {
00852
if (m_editCurrentUndo || m_imComposeEvent)
return;
00853
00854
00855
if ((config()->undoSteps() > 0) && (undoItems.count() > config()->undoSteps()))
00856 {
00857 undoItems.setAutoDelete(
true);
00858 undoItems.removeFirst();
00859 undoItems.setAutoDelete(
false);
00860 docWasSavedWhenUndoWasEmpty =
false;
00861 }
00862
00863
00864 m_editCurrentUndo =
new KateUndoGroup(
this);
00865 }
00866
00867
void KateDocument::undoEnd()
00868 {
00869
if (m_imComposeEvent)
00870
return;
00871
00872
if (m_editCurrentUndo)
00873 {
00874
if (!m_undoDontMerge && undoItems.last() && undoItems.last()->merge(m_editCurrentUndo))
00875
delete m_editCurrentUndo;
00876
else
00877 undoItems.append(m_editCurrentUndo);
00878
00879 m_undoDontMerge =
false;
00880 m_undoIgnoreCancel =
true;
00881
00882 m_editCurrentUndo = 0L;
00883
00884
00885
00886 m_undoMergeTimer->start(5000,
true);
00887
00888 emit undoChanged();
00889 }
00890 }
00891
00892
void KateDocument::undoCancel()
00893 {
00894
if (m_undoIgnoreCancel) {
00895 m_undoIgnoreCancel =
false;
00896
return;
00897 }
00898
00899 m_undoDontMerge =
true;
00900
00901 Q_ASSERT(!m_editCurrentUndo);
00902
00903
00904
delete m_editCurrentUndo;
00905 m_editCurrentUndo = 0L;
00906 }
00907
00908
00909
00910
00911
void KateDocument::editEnd ()
00912 {
00913
if (editSessionNumber == 0)
00914
return;
00915
00916
00917
if (editSessionNumber == 1)
00918
if (editWithUndo && config()->wordWrap())
00919 wrapText (editTagLineStart, editTagLineEnd);
00920
00921 editSessionNumber--;
00922
00923
if (editSessionNumber > 0)
00924
return;
00925
00926 buffer->setHlUpdate (
true);
00927
00928
00929
00930
if (editTagLineStart <= editTagLineEnd)
00931 buffer->updateHighlighting ((editTagLineStart == 0) ? 0 : (editTagLineStart-1), editTagLineEnd+1,
true);
00932
00933
if (editWithUndo)
00934 undoEnd();
00935
00936
for (uint z = 0; z < m_views.count(); z++)
00937 {
00938 m_views.at(z)->editEnd (editTagLineStart, editTagLineEnd, editTagFrom);
00939 }
00940
00941 setModified(
true);
00942 emit textChanged ();
00943
00944 noViewUpdates =
false;
00945 editIsRunning =
false;
00946 }
00947
00948
bool KateDocument::wrapText (uint startLine, uint endLine)
00949 {
00950 uint col = config()->wordWrapAt();
00951
00952
if (col == 0)
00953
return false;
00954
00955 editStart ();
00956
00957
for (uint line = startLine; (line <= endLine) && (line < numLines()); line++)
00958 {
00959 TextLine::Ptr l = buffer->line(line);
00960
00961
if (!l)
00962
return false;
00963
00964
if (l->length() > col)
00965 {
00966 TextLine::Ptr nextl = buffer->line(line+1);
00967
00968
const QChar *text = l->text();
00969 uint eolPosition = l->length()-1;
00970 uint searchStart = col;
00971
00972
00973
00974
if (col == eolPosition && text[col].
isSpace())
00975 searchStart--;
00976
00977
00978
00979
00980
int z = 0;
00981
for (z=searchStart; z > 0; z--)
00982
if (text[z].isSpace())
break;
00983
00984
if (z > 0)
00985 {
00986
00987 editRemoveText (line, z, 1);
00988 }
00989
else
00990 {
00991
00992
00993 z = col;
00994 }
00995
00996
if (nextl && !nextl->isAutoWrapped())
00997 {
00998 editWrapLine (line, z,
true);
00999 editMarkLineAutoWrapped (line+1,
true);
01000
01001 endLine++;
01002 }
01003
else
01004 {
01005
if (nextl && (nextl->length() > 0) && !nextl->getChar(0).isSpace() && ((l->length() < 1) || !l->getChar(l->length()-1).isSpace()))
01006 editInsertText (line+1, 0, QString (
" "));
01007
01008
bool newLineAdded =
false;
01009 editWrapLine (line, z,
false, &newLineAdded);
01010
01011 editMarkLineAutoWrapped (line+1,
true);
01012
01013
if (newLineAdded)
01014 endLine++;
01015 }
01016 }
01017 }
01018
01019 editEnd ();
01020
01021
return true;
01022 }
01023
01024
void KateDocument::editAddUndo (uint type, uint line, uint col, uint len,
const QString &text)
01025 {
01026
if (editIsRunning && editWithUndo && m_editCurrentUndo) {
01027 m_editCurrentUndo->addItem(type, line, col, len, text);
01028
01029
01030
if (redoItems.count()) {
01031 redoItems.setAutoDelete(
true);
01032 redoItems.clear();
01033 redoItems.setAutoDelete(
false);
01034 }
01035 }
01036 }
01037
01038
void KateDocument::editTagLine (uint line)
01039 {
01040
if (line < editTagLineStart)
01041 editTagLineStart = line;
01042
01043
if (line > editTagLineEnd)
01044 editTagLineEnd = line;
01045 }
01046
01047
void KateDocument::editInsertTagLine (uint line)
01048 {
01049
if (line < editTagLineStart)
01050 editTagLineStart = line;
01051
01052
if (line <= editTagLineEnd)
01053 editTagLineEnd++;
01054
01055
if (line > editTagLineEnd)
01056 editTagLineEnd = line;
01057
01058 editTagFrom =
true;
01059 }
01060
01061
void KateDocument::editRemoveTagLine (uint line)
01062 {
01063
if (line < editTagLineStart)
01064 editTagLineStart = line;
01065
01066
if (line < editTagLineEnd)
01067 editTagLineEnd--;
01068
01069
if (line > editTagLineEnd)
01070 editTagLineEnd = line;
01071
01072 editTagFrom =
true;
01073 }
01074
01075
bool KateDocument::editInsertText ( uint line, uint col,
const QString &s )
01076 {
01077
if (!isReadWrite())
01078
return false;
01079
01080 TextLine::Ptr l = buffer->line(line);
01081
01082
if (!l)
01083
return false;
01084
01085 editStart ();
01086
01087 editAddUndo (KateUndoGroup::editInsertText, line, col, s.
length(), s);
01088
01089 l->insertText (col, s.
length(), s.
unicode());
01090
01091 buffer->changeLine(line);
01092 editTagLine (line);
01093
01094
for(
QPtrListIterator<KateSuperCursor> it (m_superCursors); it.
current(); ++it )
01095 it.
current()->editTextInserted (line, col, s.
length());
01096
01097 editEnd ();
01098
01099
return true;
01100 }
01101
01102
bool KateDocument::editRemoveText ( uint line, uint col, uint len )
01103 {
01104
if (!isReadWrite())
01105
return false;
01106
01107 TextLine::Ptr l = buffer->line(line);
01108
01109
if (!l)
01110
return false;
01111
01112 editStart ();
01113
01114 editAddUndo (KateUndoGroup::editRemoveText, line, col, len, l->string().mid(col, len));
01115
01116 l->removeText (col, len);
01117
01118 buffer->changeLine(line);
01119
01120 editTagLine(line);
01121
01122
for(
QPtrListIterator<KateSuperCursor> it (m_superCursors); it.
current(); ++it )
01123 it.
current()->editTextRemoved (line, col, len);
01124
01125 editEnd ();
01126
01127
return true;
01128 }
01129
01130
bool KateDocument::editMarkLineAutoWrapped ( uint line,
bool autowrapped )
01131 {
01132
if (!isReadWrite())
01133
return false;
01134
01135 TextLine::Ptr l = buffer->line(line);
01136
01137
if (!l)
01138
return false;
01139
01140 editStart ();
01141
01142 editAddUndo (KateUndoGroup::editMarkLineAutoWrapped, line, autowrapped ? 1 : 0, 0, QString::null);
01143
01144 l->setAutoWrapped (autowrapped);
01145
01146 buffer->changeLine(line);
01147
01148 editEnd ();
01149
01150
return true;
01151 }
01152
01153
bool KateDocument::editWrapLine ( uint line, uint col,
bool newLine,
bool *newLineAdded)
01154 {
01155
if (!isReadWrite())
01156
return false;
01157
01158 TextLine::Ptr l = buffer->line(line);
01159
01160
if (!l)
01161
return false;
01162
01163 editStart ();
01164
01165 TextLine::Ptr nl = buffer->line(line+1);
01166
01167
int pos = l->length() - col;
01168
01169
if (pos < 0)
01170 pos = 0;
01171
01172 editAddUndo (KateUndoGroup::editWrapLine, line, col, pos, (!nl || newLine) ?
"1" :
"0");
01173
01174
if (!nl || newLine)
01175 {
01176 TextLine::Ptr tl =
new TextLine();
01177
01178 tl->insertText (0, pos, l->text()+col, l->attributes()+col);
01179 l->truncate(col);
01180
01181 buffer->insertLine (line+1, tl);
01182 buffer->changeLine(line);
01183
01184
QPtrList<KTextEditor::Mark> list;
01185
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks ); it.
current(); ++it )
01186 {
01187
if( it.
current()->line >= line )
01188 {
01189
if ((col == 0) || (it.
current()->line > line))
01190 list.
append( it.
current() );
01191 }
01192 }
01193
01194
for(
QPtrListIterator<KTextEditor::Mark> it( list ); it.
current(); ++it )
01195 {
01196 KTextEditor::Mark* mark = m_marks.take( it.
current()->line );
01197 mark->line++;
01198 m_marks.insert( mark->line, mark );
01199 }
01200
01201
if( !list.
isEmpty() )
01202 emit marksChanged();
01203
01204 editInsertTagLine (line);
01205
01206
01207
if (newLineAdded)
01208 (*newLineAdded) =
true;
01209 }
01210
else
01211 {
01212 nl->insertText (0, pos, l->text()+col, l->attributes()+col);
01213 l->truncate(col);
01214
01215 buffer->changeLine(line);
01216 buffer->changeLine(line+1);
01217
01218
01219
if (newLineAdded)
01220 (*newLineAdded) =
false;
01221 }
01222
01223 editTagLine(line);
01224 editTagLine(line+1);
01225
01226
for(
QPtrListIterator<KateSuperCursor> it (m_superCursors); it.
current(); ++it )
01227 it.
current()->editLineWrapped (line, col, !nl || newLine);
01228
01229 editEnd ();
01230
01231
return true;
01232 }
01233
01234
bool KateDocument::editUnWrapLine ( uint line,
bool removeLine, uint length )
01235 {
01236
if (!isReadWrite())
01237
return false;
01238
01239 TextLine::Ptr l = buffer->line(line);
01240 TextLine::Ptr tl = buffer->line(line+1);
01241
01242
if (!l || !tl)
01243
return false;
01244
01245 editStart ();
01246
01247 uint col = l->length ();
01248
01249 editAddUndo (KateUndoGroup::editUnWrapLine, line, col, length, removeLine ?
"1" :
"0");
01250
01251
if (removeLine)
01252 {
01253 l->insertText (col, tl->length(), tl->text(), tl->attributes());
01254
01255 buffer->changeLine(line);
01256 buffer->removeLine(line+1);
01257 }
01258
else
01259 {
01260 l->insertText (col, (tl->length() < length) ? tl->length() : length, tl->text(), tl->attributes());
01261 tl->removeText (0, (tl->length() < length) ? tl->length() : length);
01262
01263 buffer->changeLine(line);
01264 buffer->changeLine(line+1);
01265 }
01266
01267
QPtrList<KTextEditor::Mark> list;
01268
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks ); it.
current(); ++it )
01269 {
01270
if( it.
current()->line >= line+1 )
01271 list.
append( it.
current() );
01272
01273
if ( it.
current()->line == line+1 )
01274 {
01275 KTextEditor::Mark* mark = m_marks.take( line );
01276
01277
if (mark)
01278 {
01279 it.
current()->type |= mark->type;
01280 }
01281 }
01282 }
01283
01284
for(
QPtrListIterator<KTextEditor::Mark> it( list ); it.
current(); ++it )
01285 {
01286 KTextEditor::Mark* mark = m_marks.take( it.
current()->line );
01287 mark->line--;
01288 m_marks.insert( mark->line, mark );
01289 }
01290
01291
if( !list.
isEmpty() )
01292 emit marksChanged();
01293
01294
if (removeLine)
01295 editRemoveTagLine(line);
01296
01297 editTagLine(line);
01298 editTagLine(line+1);
01299
01300
for(
QPtrListIterator<KateSuperCursor> it (m_superCursors); it.
current(); ++it )
01301 it.
current()->editLineUnWrapped (line, col, removeLine, length);
01302
01303 editEnd ();
01304
01305
return true;
01306 }
01307
01308
bool KateDocument::editInsertLine ( uint line,
const QString &s )
01309 {
01310
if (!isReadWrite())
01311
return false;
01312
01313
if ( line > numLines() )
01314
return false;
01315
01316 editStart ();
01317
01318 editAddUndo (KateUndoGroup::editInsertLine, line, 0, s.
length(), s);
01319
01320 TextLine::Ptr tl =
new TextLine();
01321 tl->append(s.
unicode(),s.
length());
01322 buffer->insertLine(line, tl);
01323 buffer->changeLine(line);
01324
01325 editInsertTagLine (line);
01326 editTagLine(line);
01327
01328
QPtrList<KTextEditor::Mark> list;
01329
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks ); it.
current(); ++it )
01330 {
01331
if( it.
current()->line >= line )
01332 list.
append( it.
current() );
01333 }
01334
01335
for(
QPtrListIterator<KTextEditor::Mark> it( list ); it.
current(); ++it )
01336 {
01337 KTextEditor::Mark* mark = m_marks.take( it.
current()->line );
01338 mark->line++;
01339 m_marks.insert( mark->line, mark );
01340 }
01341
01342
if( !list.
isEmpty() )
01343 emit marksChanged();
01344
01345
for(
QPtrListIterator<KateSuperCursor> it (m_superCursors); it.
current(); ++it )
01346 it.
current()->editLineInserted (line);
01347
01348 editEnd ();
01349
01350
return true;
01351 }
01352
01353
bool KateDocument::editRemoveLine ( uint line )
01354 {
01355
if (!isReadWrite())
01356
return false;
01357
01358
if ( line > lastLine() )
01359
return false;
01360
01361
if ( numLines() == 1 )
01362
return editRemoveText (0, 0, buffer->line(0)->length());
01363
01364 editStart ();
01365
01366 editAddUndo (KateUndoGroup::editRemoveLine, line, 0, lineLength(line), textLine(line));
01367
01368 buffer->removeLine(line);
01369
01370 editRemoveTagLine (line);
01371
01372
QPtrList<KTextEditor::Mark> list;
01373 KTextEditor::Mark* rmark = 0;
01374
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks ); it.
current(); ++it )
01375 {
01376
if ( (it.
current()->line > line) )
01377 list.
append( it.
current() );
01378
else if ( (it.
current()->line == line) )
01379 rmark = it.
current();
01380 }
01381
01382
if (rmark)
01383
delete (m_marks.take (rmark->line));
01384
01385
for(
QPtrListIterator<KTextEditor::Mark> it( list ); it.
current(); ++it )
01386 {
01387 KTextEditor::Mark* mark = m_marks.take( it.
current()->line );
01388 mark->line--;
01389 m_marks.insert( mark->line, mark );
01390 }
01391
01392
if( !list.
isEmpty() )
01393 emit marksChanged();
01394
01395
for(
QPtrListIterator<KateSuperCursor> it (m_superCursors); it.
current(); ++it )
01396 it.
current()->editLineRemoved (line);
01397
01398 editEnd();
01399
01400
return true;
01401 }
01402
01403
01404
01405
01406
bool KateDocument::setSelection(
const KateTextCursor& start,
const KateTextCursor& end )
01407 {
01408
KateTextCursor oldSelectStart = selectStart;
01409
KateTextCursor oldSelectEnd = selectEnd;
01410
01411
if (start <=
end) {
01412 selectStart.
setPos(start);
01413 selectEnd.
setPos(end);
01414 }
else {
01415 selectStart.
setPos(end);
01416 selectEnd.
setPos(start);
01417 }
01418
01419 tagSelection(oldSelectStart, oldSelectEnd);
01420
01421 repaintViews();
01422
01423 emit selectionChanged ();
01424
01425
return true;
01426 }
01427
01428
bool KateDocument::setSelection( uint startLine, uint startCol, uint endLine, uint endCol )
01429 {
01430
if (hasSelection())
01431 clearSelection(
false,
false);
01432
01433
return setSelection(
KateTextCursor(startLine, startCol),
KateTextCursor(endLine, endCol) );
01434 }
01435
01436
bool KateDocument::clearSelection()
01437 {
01438
return clearSelection(
true);
01439 }
01440
01441
bool KateDocument::clearSelection(
bool redraw,
bool finishedChangingSelection)
01442 {
01443
if( !hasSelection() )
01444
return false;
01445
01446
KateTextCursor oldSelectStart = selectStart;
01447
KateTextCursor oldSelectEnd = selectEnd;
01448
01449 selectStart.
setPos(-1, -1);
01450 selectEnd.
setPos(-1, -1);
01451
01452 tagSelection(oldSelectStart, oldSelectEnd);
01453
01454 oldSelectStart = selectStart;
01455 oldSelectEnd = selectEnd;
01456
01457
if (redraw)
01458 repaintViews();
01459
01460
if (finishedChangingSelection)
01461 emit selectionChanged();
01462
01463
return true;
01464 }
01465
01466
bool KateDocument::hasSelection()
const
01467
{
01468
return selectStart != selectEnd;
01469 }
01470
01471 QString KateDocument::selection()
const
01472
{
01473
int sc = selectStart.col();
01474
int ec = selectEnd.col();
01475
01476
if ( blockSelect )
01477 {
01478
if (sc > ec)
01479 {
01480 uint tmp = sc;
01481 sc = ec;
01482 ec = tmp;
01483 }
01484 }
01485
01486
return text (selectStart.line(), sc, selectEnd.line(), ec, blockSelect);
01487 }
01488
01489
bool KateDocument::removeSelectedText ()
01490 {
01491
if (!hasSelection())
01492
return false;
01493
01494 editStart ();
01495
01496
int sc = selectStart.col();
01497
int ec = selectEnd.col();
01498
01499
if ( blockSelect )
01500 {
01501
if (sc > ec)
01502 {
01503 uint tmp = sc;
01504 sc = ec;
01505 ec = tmp;
01506 }
01507 }
01508
01509 removeText (selectStart.line(), sc, selectEnd.line(), ec, blockSelect);
01510
01511
01512 clearSelection(
false);
01513
01514 editEnd ();
01515
01516
return true;
01517 }
01518
01519
bool KateDocument::selectAll()
01520 {
01521 setBlockSelectionMode (
false);
01522
01523
return setSelection (0, 0, lastLine(), lineLength(lastLine()));
01524 }
01525
01526
01527
01528
01529
bool KateDocument::blockSelectionMode ()
01530 {
01531
return blockSelect;
01532 }
01533
01534
bool KateDocument::setBlockSelectionMode (
bool on)
01535 {
01536
if (on != blockSelect)
01537 {
01538 blockSelect = on;
01539
01540
KateTextCursor oldSelectStart = selectStart;
01541
KateTextCursor oldSelectEnd = selectEnd;
01542
01543 clearSelection(
false,
false);
01544
01545 setSelection(oldSelectStart, oldSelectEnd);
01546
01547
for (KateView * view = m_views.first(); view; view = m_views.next())
01548 {
01549 view->slotSelectionTypeChanged();
01550 }
01551 }
01552
01553
return true;
01554 }
01555
01556
bool KateDocument::toggleBlockSelectionMode ()
01557 {
01558
return setBlockSelectionMode (!blockSelect);
01559 }
01560
01561
01562
01563
01564 uint KateDocument::undoCount ()
const
01565
{
01566
return undoItems.count ();
01567 }
01568
01569 uint KateDocument::redoCount ()
const
01570
{
01571
return redoItems.count ();
01572 }
01573
01574 uint KateDocument::undoSteps ()
const
01575
{
01576
return m_config->undoSteps();
01577 }
01578
01579
void KateDocument::setUndoSteps(uint steps)
01580 {
01581 m_config->setUndoSteps (steps);
01582 }
01583
01584
void KateDocument::undo()
01585 {
01586
if ((undoItems.count() > 0) && undoItems.last())
01587 {
01588 clearSelection ();
01589
01590 undoItems.last()->undo();
01591 redoItems.append (undoItems.last());
01592 undoItems.removeLast ();
01593 updateModified();
01594
01595 emit undoChanged ();
01596 }
01597 }
01598
01599
void KateDocument::redo()
01600 {
01601
if ((redoItems.count() > 0) && redoItems.last())
01602 {
01603 clearSelection ();
01604
01605 redoItems.last()->redo();
01606 undoItems.append (redoItems.last());
01607 redoItems.removeLast ();
01608 updateModified();
01609
01610 emit undoChanged ();
01611 }
01612 }
01613
01614
void KateDocument::updateModified()
01615 {
01616
if ( ( lastUndoGroupWhenSaved &&
01617 !undoItems.isEmpty() &&
01618 undoItems.last() == lastUndoGroupWhenSaved )
01619 || ( undoItems.isEmpty() && docWasSavedWhenUndoWasEmpty ) )
01620 {
01621 setModified(
false );
01622
kdDebug() <<
k_funcinfo <<
"setting modified to false!" <<
endl;
01623 };
01624 }
01625
01626
void KateDocument::clearUndo()
01627 {
01628 undoItems.setAutoDelete (
true);
01629 undoItems.clear ();
01630 undoItems.setAutoDelete (
false);
01631
01632 lastUndoGroupWhenSaved = 0;
01633 docWasSavedWhenUndoWasEmpty =
false;
01634
01635 emit undoChanged ();
01636 }
01637
01638
void KateDocument::clearRedo()
01639 {
01640 redoItems.setAutoDelete (
true);
01641 redoItems.clear ();
01642 redoItems.setAutoDelete (
false);
01643
01644 emit undoChanged ();
01645 }
01646
01647
QPtrList<KTextEditor::Cursor> KateDocument::cursors ()
const
01648
{
01649
return myCursors;
01650 }
01651
01652
01653
01654
01655
bool KateDocument::searchText (
unsigned int startLine,
unsigned int startCol,
const QString &text,
unsigned int *foundAtLine,
unsigned int *foundAtCol,
unsigned int *matchLen,
bool casesensitive,
bool backwards)
01656 {
01657
if (text.
isEmpty())
01658
return false;
01659
01660
int line = startLine;
01661
int col = startCol;
01662
01663
if (!backwards)
01664 {
01665
int searchEnd = lastLine();
01666
01667
while (line <= searchEnd)
01668 {
01669 TextLine::Ptr textLine = buffer->plainLine(line);
01670
01671
if (!textLine)
01672
return false;
01673
01674 uint foundAt, myMatchLen;
01675
bool found = textLine->searchText (col, text, &foundAt, &myMatchLen, casesensitive,
false);
01676
01677
if (found)
01678 {
01679 (*foundAtLine) = line;
01680 (*foundAtCol) = foundAt;
01681 (*matchLen) = myMatchLen;
01682
return true;
01683 }
01684
01685 col = 0;
01686 line++;
01687 }
01688 }
01689
else
01690 {
01691
01692
int searchEnd = 0;
01693
01694
while (line >= searchEnd)
01695 {
01696 TextLine::Ptr textLine = buffer->plainLine(line);
01697
01698
if (!textLine)
01699
return false;
01700
01701 uint foundAt, myMatchLen;
01702
bool found = textLine->searchText (col, text, &foundAt, &myMatchLen, casesensitive,
true);
01703
01704
if (found)
01705 {
01706
if ((uint) line == startLine && foundAt + myMatchLen >= (uint) col
01707 && line == selectStart.line() && foundAt == (uint) selectStart.col()
01708 && line == selectEnd.line() && foundAt + myMatchLen == (uint) selectEnd.col())
01709 {
01710
01711
01712
if (foundAt > 0)
01713 col = foundAt - 1;
01714
else {
01715
if (--line >= 0)
01716 col = lineLength(line);
01717 }
01718
continue;
01719 }
01720
01721 (*foundAtLine) = line;
01722 (*foundAtCol) = foundAt;
01723 (*matchLen) = myMatchLen;
01724
return true;
01725 }
01726
01727
if (line >= 1)
01728 col = lineLength(line-1);
01729
01730 line--;
01731 }
01732 }
01733
01734
return false;
01735 }
01736
01737
bool KateDocument::searchText (
unsigned int startLine,
unsigned int startCol,
const QRegExp ®exp,
unsigned int *foundAtLine,
unsigned int *foundAtCol,
unsigned int *matchLen,
bool backwards)
01738 {
01739
if (regexp.
isEmpty() || !regexp.
isValid())
01740
return false;
01741
01742
int line = startLine;
01743
int col = startCol;
01744
01745
if (!backwards)
01746 {
01747
int searchEnd = lastLine();
01748
01749
while (line <= searchEnd)
01750 {
01751 TextLine::Ptr textLine = buffer->plainLine(line);
01752
01753
if (!textLine)
01754
return false;
01755
01756 uint foundAt, myMatchLen;
01757
bool found = textLine->searchText (col, regexp, &foundAt, &myMatchLen,
false);
01758
01759
if (found)
01760 {
01761
01762
01763
if (myMatchLen == 0 && (uint) line == startLine && foundAt == (uint) col)
01764 {
01765
if (col < lineLength(line))
01766 col++;
01767
else {
01768 line++;
01769 col = 0;
01770 }
01771
continue;
01772 }
01773
01774 (*foundAtLine) = line;
01775 (*foundAtCol) = foundAt;
01776 (*matchLen) = myMatchLen;
01777
return true;
01778 }
01779
01780 col = 0;
01781 line++;
01782 }
01783 }
01784
else
01785 {
01786
01787
int searchEnd = 0;
01788
01789
while (line >= searchEnd)
01790 {
01791 TextLine::Ptr textLine = buffer->plainLine(line);
01792
01793
if (!textLine)
01794
return false;
01795
01796 uint foundAt, myMatchLen;
01797
bool found = textLine->searchText (col, regexp, &foundAt, &myMatchLen,
true);
01798
01799
if (found)
01800 {
01801
if ((uint) line == startLine && foundAt + myMatchLen >= (uint) col
01802 && line == selectStart.line() && foundAt == (uint) selectStart.col()
01803 && line == selectEnd.line() && foundAt + myMatchLen == (uint) selectEnd.col())
01804 {
01805
01806
01807
if (foundAt > 0)
01808 col = foundAt - 1;
01809
else {
01810
if (--line >= 0)
01811 col = lineLength(line);
01812 }
01813
continue;
01814 }
01815
01816 (*foundAtLine) = line;
01817 (*foundAtCol) = foundAt;
01818 (*matchLen) = myMatchLen;
01819
return true;
01820 }
01821
01822
if (line >= 1)
01823 col = lineLength(line-1);
01824
01825 line--;
01826 }
01827 }
01828
01829
return false;
01830 }
01831
01832
01833
01834
01835 uint KateDocument::hlMode ()
01836 {
01837
return HlManager::self()->findHl(m_highlight);
01838 }
01839
01840
bool KateDocument::setHlMode (uint mode)
01841 {
01842
if (internalSetHlMode (mode))
01843 {
01844 setDontChangeHlOnSave();
01845
return true;
01846 }
01847
01848
return false;
01849 }
01850
01851
bool KateDocument::internalSetHlMode (uint mode)
01852 {
01853 Highlight *h = HlManager::self()->getHl(mode);
01854
01855
01856
if (h != m_highlight)
01857 {
01858
if (m_highlight != 0L)
01859 m_highlight->release();
01860
01861 h->use();
01862
01863 m_highlight = h;
01864
01865
01866 buffer->setHighlight(m_highlight);
01867
01868
01869 makeAttribs();
01870
01871 emit hlChanged();
01872 }
01873
01874
return true;
01875 }
01876
01877 uint KateDocument::hlModeCount ()
01878 {
01879
return HlManager::self()->highlights();
01880 }
01881
01882 QString KateDocument::hlModeName (uint mode)
01883 {
01884
return HlManager::self()->hlName (mode);
01885 }
01886
01887 QString KateDocument::hlModeSectionName (uint mode)
01888 {
01889
return HlManager::self()->hlSection (mode);
01890 }
01891
01892
void KateDocument::setDontChangeHlOnSave()
01893 {
01894 hlSetByUser =
true;
01895 }
01896
01897
01898
01899
void KateDocument::readConfig(
KConfig *config)
01900 {
01901 config->
setGroup(
"Kate Document Defaults");
01902 KateDocumentConfig::global()->readConfig (config);
01903
01904 config->
setGroup(
"Kate View Defaults");
01905 KateViewConfig::global()->readConfig (config);
01906
01907 config->
setGroup(
"Kate Renderer Defaults");
01908 KateRendererConfig::global()->readConfig (config);
01909 }
01910
01911
void KateDocument::writeConfig(
KConfig *config)
01912 {
01913 config->
setGroup(
"Kate Document Defaults");
01914 KateDocumentConfig::global()->writeConfig (config);
01915
01916 config->
setGroup(
"Kate View Defaults");
01917 KateViewConfig::global()->writeConfig (config);
01918
01919 config->
setGroup(
"Kate Renderer Defaults");
01920 KateRendererConfig::global()->writeConfig (config);
01921 }
01922
01923
void KateDocument::readConfig()
01924 {
01925
KConfig *config = kapp->config();
01926 readConfig (config);
01927 }
01928
01929
void KateDocument::writeConfig()
01930 {
01931
KConfig *config = kapp->config();
01932 writeConfig (config);
01933 config->
sync();
01934 }
01935
01936
void KateDocument::readSessionConfig(
KConfig *config)
01937 {
01938
01939
KURL url (config->
readEntry(
"URL"));
01940
01941
01942 QString tmpenc=config->
readEntry(
"Encoding");
01943
if (!tmpenc.
isEmpty() && (tmpenc != encoding()))
01944 setEncoding(tmpenc);
01945
01946
01947
if (!url.
isEmpty() && url.
isValid())
01948 openURL (url);
01949
01950
01951 internalSetHlMode(HlManager::self()->nameFind(config->
readEntry(
"Highlighting")));
01952
01953
if (hlMode() > 0)
01954 hlSetByUser =
true;
01955
01956
01957
QValueList<int> marks = config->
readIntListEntry(
"Bookmarks");
01958
for( uint i = 0; i < marks.
count(); i++ )
01959 addMark( marks[i], KateDocument::markType01 );
01960 }
01961
01962
void KateDocument::writeSessionConfig(
KConfig *config)
01963 {
01964
01965 config->
writeEntry(
"URL", m_url.prettyURL() );
01966
01967
01968 config->
writeEntry(
"Encoding",encoding());
01969
01970
01971 config->
writeEntry(
"Highlighting", m_highlight->name());
01972
01973
01974
QValueList<int> marks;
01975
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks );
01976 it.
current() && it.
current()->type & KTextEditor::MarkInterface::markType01;
01977 ++it )
01978 marks << it.
current()->line;
01979
01980 config->
writeEntry(
"Bookmarks", marks );
01981 }
01982
01983
void KateDocument::configDialog()
01984 {
01985
KDialogBase *kd =
new KDialogBase ( KDialogBase::IconList,
01986 i18n(
"Configure"),
01987 KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Help,
01988 KDialogBase::Ok,
01989 kapp->mainWidget() );
01990
01991
KWin::setIcons( kd->winId(), kapp->icon(), kapp->miniIcon() );
01992
01993
QPtrList<KTextEditor::ConfigPage> editorPages;
01994
01995
for (uint i = 0; i < KTextEditor::configInterfaceExtension (
this)->configPages (); i++)
01996 {
01997
QStringList path;
01998 path.clear();
01999 path << KTextEditor::configInterfaceExtension (
this)->configPageName (i);
02000
QVBox *page = kd->
addVBoxPage(path, KTextEditor::configInterfaceExtension (
this)->configPageFullName (i),
02001 KTextEditor::configInterfaceExtension (
this)->configPagePixmap(i, KIcon::SizeMedium) );
02002
02003 editorPages.
append (KTextEditor::configInterfaceExtension (
this)->configPage(i, page));
02004 }
02005
02006
if (kd->
exec())
02007 {
02008 KateDocumentConfig::global()->configStart ();
02009 KateViewConfig::global()->configStart ();
02010 KateRendererConfig::global()->configStart ();
02011
02012
for (uint i=0; i<editorPages.
count(); i++)
02013 {
02014 editorPages.
at(i)->apply();
02015 }
02016
02017 KateDocumentConfig::global()->configEnd ();
02018 KateViewConfig::global()->configEnd ();
02019 KateRendererConfig::global()->configEnd ();
02020
02021 writeConfig ();
02022 }
02023
02024
delete kd;
02025 }
02026
02027 uint KateDocument::mark( uint line )
02028 {
02029
if( !m_marks[line] )
02030
return 0;
02031
return m_marks[line]->type;
02032 }
02033
02034
void KateDocument::setMark( uint line, uint markType )
02035 {
02036 clearMark( line );
02037 addMark( line, markType );
02038 }
02039
02040
void KateDocument::clearMark( uint line )
02041 {
02042
if( line > lastLine() )
02043
return;
02044
02045
if( !m_marks[line] )
02046
return;
02047
02048 KTextEditor::Mark* mark = m_marks.take( line );
02049 emit markChanged( *mark, MarkRemoved );
02050 emit marksChanged();
02051
delete mark;
02052 tagLines( line, line );
02053 repaintViews(
true);
02054 }
02055
02056
void KateDocument::addMark( uint line, uint markType )
02057 {
02058
if( line > lastLine())
02059
return;
02060
02061
if( markType == 0 )
02062
return;
02063
02064
if( m_marks[line] ) {
02065 KTextEditor::Mark* mark = m_marks[line];
02066
02067
02068 markType &= ~mark->type;
02069
02070
if( markType == 0 )
02071
return;
02072
02073
02074 mark->type |= markType;
02075 }
else {
02076 KTextEditor::Mark *mark =
new KTextEditor::Mark;
02077 mark->line = line;
02078 mark->type = markType;
02079 m_marks.insert( line, mark );
02080 }
02081
02082
02083 KTextEditor::Mark temp;
02084 temp.line = line;
02085 temp.type = markType;
02086 emit markChanged( temp, MarkAdded );
02087
02088 emit marksChanged();
02089 tagLines( line, line );
02090 repaintViews(
true);
02091 }
02092
02093
void KateDocument::removeMark( uint line, uint markType )
02094 {
02095
if( line > lastLine() )
02096
return;
02097
if( !m_marks[line] )
02098
return;
02099
02100 KTextEditor::Mark* mark = m_marks[line];
02101
02102
02103 markType &= mark->type;
02104
02105
if( markType == 0 )
02106
return;
02107
02108
02109 mark->type &= ~markType;
02110
02111
02112 KTextEditor::Mark temp;
02113 temp.line = line;
02114 temp.type = markType;
02115 emit markChanged( temp, MarkRemoved );
02116
02117
if( mark->type == 0 )
02118 m_marks.remove( line );
02119
02120 emit marksChanged();
02121 tagLines( line, line );
02122 repaintViews(
true);
02123 }
02124
02125
QPtrList<KTextEditor::Mark> KateDocument::marks()
02126 {
02127
QPtrList<KTextEditor::Mark> list;
02128
02129
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks );
02130 it.
current(); ++it ) {
02131 list.
append( it.
current() );
02132 }
02133
02134
return list;
02135 }
02136
02137
void KateDocument::clearMarks()
02138 {
02139
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks );
02140 it.
current(); ++it ) {
02141 KTextEditor::Mark* mark = it.
current();
02142 emit markChanged( *mark, MarkRemoved );
02143 tagLines( mark->line, mark->line );
02144 }
02145
02146 m_marks.clear();
02147
02148 emit marksChanged();
02149 repaintViews(
true);
02150 }
02151
02152
void KateDocument::setPixmap( MarkInterface::MarkTypes type,
const QPixmap& pixmap )
02153 {
02154 m_markPixmaps.replace( type,
new QPixmap( pixmap ) );
02155 }
02156
02157
void KateDocument::setDescription( MarkInterface::MarkTypes type,
const QString& description )
02158 {
02159 m_markDescriptions.replace( type,
new QString( description ) );
02160 }
02161
02162
QPixmap *KateDocument::markPixmap( MarkInterface::MarkTypes type )
02163 {
02164
return m_markPixmaps[type];
02165 }
02166
02167
QColor KateDocument::markColor( MarkInterface::MarkTypes type )
02168 {
02169
switch (type) {
02170
02171
case markType01:
02172
return Qt::blue;
02173
02174
02175
case markType02:
02176
return Qt::red;
02177
02178
02179
case markType03:
02180
return Qt::yellow;
02181
02182
02183
case markType04:
02184
return Qt::magenta;
02185
02186
02187
case markType05:
02188
return Qt::gray;
02189
02190
02191
case markType06:
02192
return Qt::green;
02193
02194
default:
02195
return QColor();
02196 }
02197 }
02198
02199 QString KateDocument::markDescription( MarkInterface::MarkTypes type )
02200 {
02201
if( m_markDescriptions[type] )
02202
return *m_markDescriptions[type];
02203
return QString::null;
02204 }
02205
02206
void KateDocument::setMarksUserChangable( uint markMask )
02207 {
02208 m_editableMarks = markMask;
02209 }
02210
02211 uint KateDocument::editableMarks()
02212 {
02213
return m_editableMarks;
02214 }
02215
02216
02217
02218
bool KateDocument::printDialog ()
02219 {
02220
return KatePrinter::print (
this);
02221 }
02222
02223
bool KateDocument::print ()
02224 {
02225
return KatePrinter::print (
this);
02226 }
02227
02228
02229
02230
02231
bool KateDocument::openURL(
const KURL &url )
02232 {
02233
02234
if ( !url.
isValid() )
02235
return false;
02236
02237
02238
if ( !closeURL() )
02239
return false;
02240
02241
02242 m_url = url;
02243
02244
if ( m_url.isLocalFile() )
02245 {
02246
02247
02248 m_file = m_url.
path();
02249
02250 emit started( 0 );
02251
02252
if (openFile())
02253 {
02254 emit completed();
02255 emit setWindowCaption( m_url.prettyURL() );
02256
02257
return true;
02258 }
02259
02260
return false;
02261 }
02262
else
02263 {
02264
02265
02266 m_bTemp =
true;
02267
02268 m_tempFile =
new KTempFile ();
02269 m_file = m_tempFile->name();
02270
02271 m_job =
KIO::get ( url,
false, isProgressInfoEnabled() );
02272
02273
QWidget *w = widget ();
02274
if (!w && !m_views.isEmpty ())
02275 w = m_views.first();
02276
02277
if (w)
02278 m_job->setWindow (w->
topLevelWidget());
02279
02280 emit started( m_job );
02281
02282 connect( m_job, SIGNAL( data(
KIO::Job*,
const QByteArray& ) ),
02283 SLOT( slotDataKate(
KIO::Job*,
const QByteArray& ) ) );
02284
02285 connect( m_job, SIGNAL(
result(
KIO::Job* ) ),
02286 SLOT( slotFinishedKate(
KIO::Job* ) ) );
02287
02288
return true;
02289 }
02290 }
02291
02292
void KateDocument::slotDataKate (
KIO::Job *,
const QByteArray &data )
02293 {
02294
kdDebug(13020) <<
"KateDocument::slotData" <<
endl;
02295
02296
if (!m_tempFile || !m_tempFile->file())
02297
return;
02298
02299 m_tempFile->file()->writeBlock (data);
02300 }
02301
02302
void KateDocument::slotFinishedKate (
KIO::Job * job )
02303 {
02304
kdDebug(13020) <<
"KateDocument::slotJobFinished" <<
endl;
02305
02306
if (!m_tempFile)
02307
return;
02308
02309
delete m_tempFile;
02310 m_tempFile = 0;
02311 m_job = 0;
02312
02313
if (job->
error())
02314 emit canceled( job->
errorString() );
02315
else
02316 {
02317
if ( openFile(job) )
02318 emit setWindowCaption( m_url.prettyURL() );
02319
02320 emit completed();
02321 }
02322 }
02323
02324
void KateDocument::abortLoadKate()
02325 {
02326
if ( m_job )
02327 {
02328
kdDebug(13020) <<
"Aborting job " << m_job <<
endl;
02329 m_job->kill();
02330 m_job = 0;
02331 }
02332
02333
delete m_tempFile;
02334 m_tempFile = 0;
02335 }
02336
02337
bool KateDocument::openFile()
02338 {
02339
return openFile (0);
02340 }
02341
02342
bool KateDocument::openFile(
KIO::Job * job)
02343 {
02344
02345 activateDirWatch ();
02346
02347
02348
02349
02350
if (job)
02351 {
02352 QString metaDataCharset = job->
queryMetaData(
"charset");
02353
02354
if (!metaDataCharset.
isEmpty ())
02355 setEncoding (metaDataCharset);
02356 }
02357
02358
02359
02360
02361 QString serviceType = m_extension->urlArgs().serviceType.simplifyWhiteSpace();
02362
int pos = serviceType.
find(
';');
02363
if (pos != -1)
02364 setEncoding (serviceType.
mid(pos+1));
02365
02366
02367
bool success = buffer->openFile (m_file);
02368
02369
02370
02371
02372
if (success)
02373 {
02374
if (m_highlight && !m_url.isLocalFile()) {
02375
02376 buffer->setHighlight(m_highlight);
02377 }
02378
02379
02380
if (!hlSetByUser)
02381 {
02382
int hl (HlManager::self()->detectHighlighting (
this));
02383
02384
if (hl >= 0)
02385 internalSetHlMode(hl);
02386
02387 }
02388
02389 updateFileType (KateFactory::self()->fileTypeManager()->fileType (
this));
02390
02391
02392 readVariables();
02393
02394
02395 createDigest( m_digest );
02396 }
02397
02398
02399
02400
02401 updateViews();
02402
02403
02404
02405
02406 emit fileNameChanged ();
02407
02408
02409
02410
02411 setDocName (QString::null);
02412
02413
02414
02415
02416
if (m_modOnHd)
02417 {
02418 m_modOnHd =
false;
02419 m_modOnHdReason = 0;
02420 emit modifiedOnDisc (
this, m_modOnHd, 0);
02421 }
02422
02423
02424
02425
02426
if (s_openErrorDialogsActivated)
02427 {
02428
if (!success && buffer->loadingBorked())
02429
KMessageBox::error (widget(), i18n (
"The file %1 could not been loaded completely, as there is not enough temporary disk storage for it!").arg(m_url.url()));
02430
else if (!success)
02431
KMessageBox::error (widget(), i18n (
"The file %1 could not been loaded, as it was not possible to read from it!\n\nCheck if you have read access to this file.").arg(m_url.url()));
02432 }
02433
02434
02435
02436
02437
return success;
02438 }
02439
02440
bool KateDocument::save()
02441 {
02442
02443
bool l ( url().isLocalFile() );
02444
if ( ( ( l && config()->backupFlags() & KateDocumentConfig::LocalFiles ) ||
02445 ( ! l && config()->backupFlags() & KateDocumentConfig::RemoteFiles ) )
02446 && isModified() ) {
02447
KURL u( url().path() + config()->backupSuffix() );
02448
if ( !
KIO::NetAccess::upload( url().path(), u, kapp->mainWidget() ) )
02449
kdDebug(13020)<<
"backing up failed ("<<url().prettyURL()<<
" -> "<<u.
prettyURL()<<
")"<<
endl;
02450 }
02451
02452
return KParts::ReadWritePart::save();
02453 }
02454
02455
bool KateDocument::saveFile()
02456 {
02457
02458
02459
02460
bool reallySaveIt = !buffer->loadingBorked() || (
KMessageBox::warningYesNo(widget(),
02461 i18n(
"This file could not be loaded correctly due to lack of temporary disk space. Saving it could cause data loss.\n\nDo you really want to save it?")) == KMessageBox::Yes);
02462
02463
if ( !url().isEmpty() )
02464 {
02465
if (s_fileChangedDialogsActivated && m_modOnHd)
02466 {
02467 QString str;
02468
02469
if (m_modOnHdReason == 1)
02470 str = i18n(
"The file %1 was changed (modified) on disc by another program!\n\n").
arg(url().fileName());
02471
else if (m_modOnHdReason == 2)
02472 str = i18n(
"The file %1 was changed (created) on disc by another program!\n\n").
arg(url().fileName());
02473
else if (m_modOnHdReason == 3)
02474 str = i18n(
"The file %1 was changed (deleted) on disc by another program!\n\n").
arg(url().fileName());
02475
02476
if (!isModified())
02477 {
02478
if (!(
KMessageBox::warningYesNo(0,
02479 str + i18n(
"Do you really want to save this unmodified file? You could overwrite changed data in the file on disk.")) == KMessageBox::Yes))
02480 reallySaveIt =
false;
02481 }
02482
else
02483 {
02484
if (!(
KMessageBox::warningYesNo(0,
02485 str + i18n(
"Do you really want to save this file? Both your open file and the file on disk were changed. There could be some data lost.")) == KMessageBox::Yes))
02486 reallySaveIt =
false;
02487 }
02488 }
02489 }
02490
02491
02492
02493
02494
bool canEncode =
true;
02495
02496
if (reallySaveIt)
02497 canEncode = buffer->canEncode ();
02498
02499
02500
02501
02502
bool success =
false;
02503
02504
02505 deactivateDirWatch ();
02506
02507
02508
02509
02510
if (reallySaveIt && canEncode)
02511 success = buffer->saveFile (m_file);
02512
02513
02514 createDigest( m_digest );
02515
02516
02517 activateDirWatch ();
02518
02519
02520
02521
02522
if (success)
02523 {
02524
02525
if (!hlSetByUser)
02526 {
02527
int hl (HlManager::self()->detectHighlighting (
this));
02528
02529
if (hl >= 0)
02530 internalSetHlMode(hl);
02531 }
02532
02533
02534 updateFileType (KateFactory::self()->fileTypeManager()->fileType (
this));
02535
02536
02537 readVariables();
02538 }
02539
02540
02541
02542
02543 emit fileNameChanged ();
02544
02545
02546
02547
02548 setDocName (QString::null);
02549
02550
02551
02552
02553
if (success && m_modOnHd)
02554 {
02555 m_modOnHd =
false;
02556 m_modOnHdReason = 0;
02557 emit modifiedOnDisc (
this, m_modOnHd, 0);
02558 }
02559
02560
02561
02562
02563
if (reallySaveIt && !canEncode)
02564
KMessageBox::error (widget(), i18n (
"The document could not be saved, as the selected encoding cannot encode every unicode character in it. If you are unsure of which encoding to use, try UTF-8 or UTF-16."));
02565
else if (reallySaveIt && !success)
02566
KMessageBox::error (widget(), i18n (
"The document could not be saved, as it was not possible to write to %1.\n\nCheck that you have write access to this file or that enough disc space is available.").arg(m_url.url()));
02567
02568
02569
02570
02571
return success;
02572 }
02573
02574
void KateDocument::activateDirWatch ()
02575 {
02576
02577
if (m_file == m_dirWatchFile)
02578
return;
02579
02580
02581 deactivateDirWatch ();
02582
02583
02584
if (m_url.isLocalFile() && !m_file.isEmpty())
02585 {
02586 KateFactory::self()->dirWatch ()->addFile (m_file);
02587 m_dirWatchFile = m_file;
02588 }
02589 }
02590
02591
void KateDocument::deactivateDirWatch ()
02592 {
02593
if (!m_dirWatchFile.isEmpty())
02594 KateFactory::self()->dirWatch ()->removeFile (m_dirWatchFile);
02595
02596 m_dirWatchFile = QString::null;
02597 }
02598
02599
bool KateDocument::closeURL()
02600 {
02601 abortLoadKate();
02602
02603
02604
02605
02606
if ( !m_reloading && !url().isEmpty() )
02607 {
02608
if (s_fileChangedDialogsActivated && m_modOnHd)
02609 {
02610 QString str;
02611
02612
if (m_modOnHdReason == 1)
02613 str = i18n(
"The file %1 was changed (modified) on disc by another program!\n\n").
arg(url().fileName());
02614
else if (m_modOnHdReason == 2)
02615 str = i18n(
"The file %1 was changed (created) on disc by another program!\n\n").
arg(url().fileName());
02616
else if (m_modOnHdReason == 3)
02617 str = i18n(
"The file %1 was changed (deleted) on disc by another program!\n\n").
arg(url().fileName());
02618
02619
if (!(
KMessageBox::warningYesNo(0,
02620 str + i18n(
"Do you really want to continue to close this file? Data loss may occur.")) == KMessageBox::Yes))
02621
return false;
02622 }
02623 }
02624
02625
02626
02627
02628
if (!
KParts::ReadWritePart::closeURL ())
02629
return false;
02630
02631
02632 deactivateDirWatch ();
02633
02634
02635
02636
02637 m_url =
KURL ();
02638 m_file = QString::null;
02639
02640
02641
if (m_modOnHd)
02642 {
02643 m_modOnHd =
false;
02644 m_modOnHdReason = 0;
02645 emit modifiedOnDisc (
this, m_modOnHd, 0);
02646 }
02647
02648
02649 buffer->clear();
02650
02651
02652 clearMarks ();
02653
02654
02655 clearUndo();
02656 clearRedo();
02657
02658
02659 setModified(
false);
02660
02661
02662 internalSetHlMode(0);
02663
02664
02665
for (KateView * view = m_views.first(); view != 0L; view = m_views.next() )
02666 {
02667
02668
02669 view->setCursorPositionInternal(0, 0, 1,
false);
02670 view->updateView(
true);
02671 }
02672
02673
02674 emit fileNameChanged ();
02675
02676
02677 setDocName (QString::null);
02678
02679
02680
return true;
02681 }
02682
02683
void KateDocument::setReadWrite(
bool rw )
02684 {
02685
if (isReadWrite() != rw)
02686 {
02687
KParts::ReadWritePart::setReadWrite (rw);
02688
02689
for( KateView* view = m_views.first(); view != 0L; view = m_views.next() )
02690 {
02691 view->slotUpdate();
02692 view->slotReadWriteChanged ();
02693 }
02694 }
02695 }
02696
02697
void KateDocument::setModified(
bool m) {
02698
02699
if (isModified() != m) {
02700
KParts::ReadWritePart::setModified (m);
02701
02702
for( KateView* view = m_views.first(); view != 0L; view = m_views.next() )
02703 {
02704 view->slotUpdate();
02705 }
02706
02707 emit modifiedChanged ();
02708 emit modStateChanged ((
Kate::Document *)
this);
02709 }
02710
if ( m ==
false && ! undoItems.isEmpty() )
02711 {
02712 lastUndoGroupWhenSaved = undoItems.last();
02713 }
02714
02715
if ( m ==
false ) docWasSavedWhenUndoWasEmpty = undoItems.isEmpty();
02716 }
02717
02718
02719
02720
02721
void KateDocument::makeAttribs()
02722 {
02723 m_highlight->clearAttributeArrays ();
02724
02725
for (uint z = 0; z < m_views.count(); z++)
02726 m_views.at(z)->renderer()->updateAttributes ();
02727
02728 buffer->invalidateHighlighting();
02729
02730 tagAll ();
02731 }
02732
02733
02734
void KateDocument::internalHlChanged()
02735 {
02736 makeAttribs();
02737 }
02738
02739
void KateDocument::addView(KTextEditor::View *view) {
02740
if (!view)
02741
return;
02742
02743 m_views.append( (KateView *) view );
02744 m_textEditViews.append( view );
02745
02746
02747
const KateFileType *t = 0;
02748
if ((m_fileType > -1) && (t = KateFactory::self()->fileTypeManager()->fileType(m_fileType)))
02749 readVariableLine (t->varLine,
true);
02750
02751
02752 readVariables (
true);
02753
02754 m_activeView = (KateView *) view;
02755 }
02756
02757
void KateDocument::removeView(KTextEditor::View *view) {
02758
if (!view)
02759
return;
02760
02761
if (m_activeView == view)
02762 m_activeView = 0L;
02763
02764 m_views.removeRef( (KateView *) view );
02765 m_textEditViews.removeRef( view );
02766 }
02767
02768
void KateDocument::addSuperCursor(
KateSuperCursor *cursor,
bool privateC) {
02769
if (!cursor)
02770
return;
02771
02772 m_superCursors.append( cursor );
02773
02774
if (!privateC)
02775 myCursors.append( cursor );
02776 }
02777
02778
void KateDocument::removeSuperCursor(
KateSuperCursor *cursor,
bool privateC) {
02779
if (!cursor)
02780
return;
02781
02782
if (!privateC)
02783 myCursors.removeRef( cursor );
02784
02785 m_superCursors.removeRef( cursor );
02786 }
02787
02788
bool KateDocument::ownedView(KateView *view) {
02789
02790
return (m_views.containsRef(view) > 0);
02791 }
02792
02793
bool KateDocument::isLastView(
int numViews) {
02794
return ((
int) m_views.count() == numViews);
02795 }
02796
02797 uint KateDocument::currentColumn(
const KateTextCursor& cursor )
02798 {
02799 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
02800
02801
if (textLine)
02802
return textLine->cursorX(cursor.
col(), config()->tabWidth());
02803
else
02804
return 0;
02805 }
02806
02807
bool KateDocument::typeChars ( KateView *view,
const QString &chars )
02808 {
02809 TextLine::Ptr textLine = buffer->plainLine(view->cursorLine ());
02810
02811
if (!textLine)
02812
return false;
02813
02814
int oldLine = view->cursorLine ();
02815
int oldCol = view->cursorColumnReal ();
02816
02817
bool bracketInserted =
false;
02818 QString buf;
02819
QChar c;
02820
for( uint z = 0; z < chars.
length(); z++ )
02821 {
02822
QChar ch = c = chars[z];
02823
02824
if (ch.
isPrint() || ch ==
'\t')
02825 {
02826 buf.
append (ch);
02827
02828
if (!bracketInserted && (config()->configFlags() & KateDocument::cfAutoBrackets))
02829 {
02830
if (ch ==
'(') { bracketInserted =
true; buf.
append (
')'); }
02831
if (ch ==
'[') { bracketInserted =
true; buf.
append (
']'); }
02832
if (ch ==
'{') { bracketInserted =
true; buf.
append (
'}'); }
02833 }
02834 }
02835 }
02836
02837
if (buf.
isEmpty())
02838
return false;
02839
02840 editStart ();
02841
02842
if (!(config()->configFlags() & KateDocument::cfPersistent) && hasSelection() )
02843 removeSelectedText();
02844
02845
if (config()->configFlags() & KateDocument::cfOvr)
02846 removeText (view->cursorLine(), view->cursorColumnReal(), view->cursorLine(), QMIN( view->cursorColumnReal()+buf.
length(), textLine->length() ) );
02847
02848 insertText (view->cursorLine(), view->cursorColumnReal(), buf);
02849 m_indenter->processChar(c);
02850
02851 editEnd ();
02852
02853
if (bracketInserted)
02854 view->setCursorPositionInternal (view->cursorLine(), view->cursorColumnReal()-1);
02855
02856 emit charactersInteractivelyInserted (oldLine, oldCol, chars);
02857
02858
return true;
02859 }
02860
02861
void KateDocument::newLine(
KateTextCursor& c, KateViewInternal *v )
02862 {
02863 editStart();
02864
02865
if( !(config()->configFlags() & cfPersistent) && hasSelection() )
02866 removeSelectedText();
02867
02868
02869 c = v->getCursor ();
02870
02871
if (c.
line() > (
int)lastLine())
02872 c.
setLine(lastLine());
02873
02874 TextLine::Ptr textLine = kateTextLine(c.
line());
02875
if (c.
col() > (
int)textLine->length())
02876 c.
setCol(textLine->length());
02877
02878
if (!(config()->configFlags() & KateDocument::cfAutoIndent))
02879 {
02880 insertText( c.
line(), c.
col(),
"\n" );
02881 c.
setPos(c.
line() + 1, 0);
02882 }
02883
else
02884 {
02885
int pos = textLine->firstChar();
02886
if (c.
col() < pos)
02887 c.
setCol(pos);
02888
02889 insertText (c.
line(), c.
col(),
"\n");
02890
02891
KateDocCursor cursor (c.
line() + 1, pos,
this);
02892 m_indenter->processNewline(cursor,
true);
02893 c.
setPos(cursor);
02894 }
02895
02896 editEnd();
02897 }
02898
02899
void KateDocument::transpose(
const KateTextCursor& cursor)
02900 {
02901 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
02902
02903
if (!textLine || (textLine->length() < 2))
02904
return;
02905
02906 uint col = cursor.
col();
02907
02908
if (col > 0)
02909 col--;
02910
02911
if ((textLine->length() - col) < 2)
02912
return;
02913
02914 uint line = cursor.
line();
02915 QString s;
02916
02917
02918
02919 s.
append (textLine->getChar(col+1));
02920 s.
append (textLine->getChar(col));
02921
02922
02923
02924 editStart ();
02925 editRemoveText (line, col, 2);
02926 editInsertText (line, col, s);
02927 editEnd ();
02928 }
02929
02930
void KateDocument::backspace(
const KateTextCursor& c )
02931 {
02932
if( !(config()->configFlags() & cfPersistent) && hasSelection() ) {
02933 removeSelectedText();
02934
return;
02935 }
02936
02937 uint col = QMAX( c.
col(), 0 );
02938 uint line = QMAX( c.
line(), 0 );
02939
02940
if ((col == 0) && (line == 0))
02941
return;
02942
02943
if (col > 0)
02944 {
02945
if (!(config()->configFlags() & KateDocument::cfBackspaceIndents))
02946 {
02947
02948
02949 removeText(line, col-1, line, col);
02950 }
02951
else
02952 {
02953
02954
02955 TextLine::Ptr textLine = buffer->plainLine(line);
02956
int colX = textLine->cursorX(col, config()->tabWidth());
02957
int pos = textLine->firstChar();
02958
if (pos > 0)
02959 pos = textLine->cursorX(pos, config()->tabWidth());
02960
02961
if (pos < 0 || pos >= (
int)colX)
02962 {
02963
02964
02965
int y = line;
02966
while (--y >= 0)
02967 {
02968 textLine = buffer->plainLine(y);
02969 pos = textLine->firstChar();
02970
02971
if (pos >= 0)
02972 {
02973 pos = textLine->cursorX(pos, config()->tabWidth());
02974
if (pos < (
int)colX)
02975 {
02976 replaceWithOptimizedSpace(line, col, pos, config()->configFlags());
02977
break;
02978 }
02979 }
02980 }
02981
if (y < 0) {
02982
02983 removeText(line, 0, line, col);
02984 }
02985 }
02986
else
02987 removeText(line, col-1, line, col);
02988 }
02989 }
02990
else
02991 {
02992
02993
if (line >= 1)
02994 {
02995 TextLine::Ptr textLine = buffer->plainLine(line-1);
02996
if (config()->wordWrap() && textLine->endingWith(QString::fromLatin1(
" ")))
02997 {
02998
02999 removeText (line-1, textLine->length()-1, line, 0);
03000 }
03001
else
03002 removeText (line-1, textLine->length(), line, 0);
03003 }
03004 }
03005
03006 emit backspacePressed();
03007 }
03008
03009
void KateDocument::del(
const KateTextCursor& c )
03010 {
03011
if ( !(config()->configFlags() & cfPersistent) && hasSelection() ) {
03012 removeSelectedText();
03013
return;
03014 }
03015
03016
if( c.
col() < (
int) buffer->plainLine(c.
line())->length())
03017 {
03018 removeText(c.
line(), c.
col(), c.
line(), c.
col()+1);
03019 }
03020
else
03021 {
03022 removeText(c.
line(), c.
col(), c.
line()+1, 0);
03023 }
03024 }
03025
03026
void KateDocument::cut()
03027 {
03028
if (!hasSelection())
03029
return;
03030
03031
copy();
03032 removeSelectedText();
03033 }
03034
03035
void KateDocument::copy()
03036 {
03037
if (!hasSelection())
03038
return;
03039
03040
QApplication::clipboard()->setText(selection ());
03041 }
03042
03043
void KateDocument::paste ( KateView* view )
03044 {
03045 QString s =
QApplication::clipboard()->text();
03046
03047
if (s.
isEmpty())
03048
return;
03049
03050 m_undoDontMerge =
true;
03051
03052 editStart ();
03053
03054
if (!(config()->configFlags() & KateDocument::cfPersistent) && hasSelection() )
03055 removeSelectedText();
03056
03057 uint line = view->cursorLine ();
03058 uint column = view->cursorColumnReal ();
03059
03060 insertText ( line, column, s, blockSelect );
03061
03062 editEnd();
03063
03064
03065
03066
03067
if (blockSelect)
03068 {
03069 uint lines = s.
contains (
QChar (
'\n'));
03070 view->setCursorPositionInternal (line+lines, column);
03071 }
03072
03073 m_undoDontMerge =
true;
03074 }
03075
03076
void KateDocument::selectWord(
const KateTextCursor& cursor )
03077 {
03078
int start,
end, len;
03079
03080 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
03081 len = textLine->length();
03082 start =
end = cursor.
col();
03083
while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
03084
while (
end < len && m_highlight->isInWord(textLine->getChar(end)))
end++;
03085
if (
end <= start)
return;
03086
03087
if (!(config()->configFlags() & KateDocument::cfKeepSelection))
03088 clearSelection ();
03089
03090 setSelection (cursor.
line(), start, cursor.
line(),
end);
03091 }
03092
03093
void KateDocument::selectLine(
const KateTextCursor& cursor )
03094 {
03095
if (!(config()->configFlags() & KateDocument::cfKeepSelection))
03096 clearSelection ();
03097
03098 setSelection (cursor.
line(), 0, cursor.
line(), buffer->plainLine(cursor.
line())->length() );
03099 }
03100
03101
void KateDocument::selectLength(
const KateTextCursor& cursor,
int length )
03102 {
03103
int start,
end;
03104
03105 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
03106 start = cursor.
col();
03107
end = start + length;
03108
if (
end <= start)
return;
03109
03110
if (!(config()->configFlags() & KateDocument::cfKeepSelection))
03111 clearSelection ();
03112 setSelection (cursor.
line(), start, cursor.
line(),
end);
03113 }
03114
03115
void KateDocument::insertIndentChars ( KateView *view )
03116 {
03117 editStart ();
03118
03119 QString s;
03120
if (config()->configFlags() & KateDocument::cfSpaceIndent)
03121 s.
fill (
' ', config()->indentationWidth());
03122
else
03123 s.
append (
'\t');
03124
03125 insertText (view->cursorLine(), view->cursorColumnReal(), s);
03126
03127 editEnd ();
03128 }
03129
03130
void KateDocument::indent ( KateView *, uint line,
int change)
03131 {
03132 editStart ();
03133
03134
if (!hasSelection())
03135 {
03136
03137 optimizeLeadingSpace(line, config()->configFlags(), change);
03138 }
03139
else
03140 {
03141
int sl = selectStart.line();
03142
int el = selectEnd.line();
03143
int ec = selectEnd.col();
03144
03145
if ((ec == 0) && ((el-1) >= 0))
03146 {
03147
03148
03149 el--;
03150 }
03151
03152
if (config()->configFlags() & KateDocument::cfKeepIndentProfile && change < 0) {
03153
03154
03155
int adjustedChange = -change;
03156
03157
for (line = sl; (
int) line <= el && adjustedChange > 0; line++) {
03158 TextLine::Ptr textLine = buffer->plainLine(line);
03159
int firstChar = textLine->firstChar();
03160
if (firstChar >= 0 && (lineSelected(line) || lineHasSelected(line))) {
03161
int maxUnindent = textLine->cursorX(firstChar, config()->tabWidth()) / config()->indentationWidth();
03162
if (maxUnindent < adjustedChange)
03163 adjustedChange = maxUnindent;
03164 }
03165 }
03166
03167 change = -adjustedChange;
03168 }
03169
03170
for (line = sl; (
int) line <= el; line++) {
03171
if (lineSelected(line) || lineHasSelected(line)) {
03172 optimizeLeadingSpace(line, config()->configFlags(), change);
03173 }
03174 }
03175 }
03176
03177 editEnd ();
03178 }
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
void KateDocument::optimizeLeadingSpace(uint line,
int flags,
int change)
03190 {
03191 TextLine::Ptr textline = buffer->plainLine(line);
03192
03193
int first_char = textline->firstChar();
03194
03195
int w = 0;
03196
if (flags & KateDocument::cfSpaceIndent)
03197 w = config()->indentationWidth();
03198
else
03199 w = config()->tabWidth();
03200
03201
if (first_char < 0)
03202 first_char = textline->length();
03203
03204
int space = textline->cursorX(first_char, config()->tabWidth()) + change * w;
03205
if (space < 0)
03206 space = 0;
03207
03208
if (!(flags & KateDocument::cfKeepExtraSpaces))
03209 {
03210 uint extra = space % w;
03211
03212 space -= extra;
03213
if (extra && change < 0) {
03214
03215 space += w;
03216 }
03217 }
03218
03219
03220 replaceWithOptimizedSpace(line, first_char, space, flags);
03221 }
03222
03223
void KateDocument::replaceWithOptimizedSpace(uint line, uint upto_column, uint space,
int flags)
03224 {
03225 uint length;
03226 QString new_space;
03227
03228
if (flags & KateDocument::cfSpaceIndent) {
03229 length = space;
03230 new_space.
fill(
' ', length);
03231 }
03232
else {
03233 length = space / config()->tabWidth();
03234 new_space.
fill(
'\t', length);
03235
03236 QString extra_space;
03237 extra_space.
fill(
' ', space % config()->tabWidth());
03238 length += space % config()->tabWidth();
03239 new_space += extra_space;
03240 }
03241
03242 TextLine::Ptr textline = buffer->plainLine(line);
03243 uint change_from;
03244
for (change_from = 0; change_from < upto_column && change_from < length; change_from++) {
03245
if (textline->getChar(change_from) != new_space[change_from])
03246
break;
03247 }
03248
03249 editStart();
03250
03251
if (change_from < upto_column)
03252 removeText(line, change_from, line, upto_column);
03253
03254
if (change_from < length)
03255 insertText(line, change_from, new_space.
right(length - change_from));
03256
03257 editEnd();
03258 }
03259
03260
03261
03262
03263
03264
bool KateDocument::removeStringFromBegining(
int line, QString &str)
03265 {
03266 TextLine::Ptr textline = buffer->plainLine(line);
03267
03268
int index = 0;
03269
bool there =
false;
03270
03271
if (textline->startingWith(str))
03272 there =
true;
03273
else
03274 {
03275 index = textline->firstChar ();
03276
03277
if ((index >= 0) && (textline->length() >= (index + str.
length())) && (textline->string(index, str.
length()) == str))
03278 there =
true;
03279 }
03280
03281
if (there)
03282 {
03283
03284 removeText (line, index, line, index+str.
length());
03285 }
03286
03287
return there;
03288 }
03289
03290
03291
03292
03293
03294
bool KateDocument::removeStringFromEnd(
int line, QString &str)
03295 {
03296 TextLine::Ptr textline = buffer->plainLine(line);
03297
03298
int index = 0;
03299
bool there =
false;
03300
03301
if(textline->endingWith(str))
03302 {
03303 index = textline->length() - str.
length();
03304 there =
true;
03305 }
03306
else
03307 {
03308 index = textline->lastChar ()-str.
length()+1;
03309
03310
if ((index >= 0) && (textline->length() >= (index + str.
length())) && (textline->string(index, str.
length()) == str))
03311 there =
true;
03312 }
03313
03314
if (there)
03315 {
03316
03317 removeText (line, index, line, index+str.
length());
03318 }
03319
03320
return there;
03321 }
03322
03323
03324
03325
03326
03327
void KateDocument::addStartLineCommentToSingleLine(
int line)
03328 {
03329 QString commentLineMark = m_highlight->getCommentSingleLineStart() +
" ";
03330 insertText (line, 0, commentLineMark);
03331 }
03332
03333
03334
03335
03336
03337
bool KateDocument::removeStartLineCommentFromSingleLine(
int line)
03338 {
03339 QString shortCommentMark = m_highlight->getCommentSingleLineStart();
03340 QString longCommentMark = shortCommentMark +
" ";
03341
03342 editStart();
03343
03344
03345
bool removed = (removeStringFromBegining(line, longCommentMark)
03346 || removeStringFromBegining(line, shortCommentMark));
03347
03348 editEnd();
03349
03350
return removed;
03351 }
03352
03353
03354
03355
03356
03357
void KateDocument::addStartStopCommentToSingleLine(
int line)
03358 {
03359 QString startCommentMark = m_highlight->getCommentStart() +
" ";
03360 QString stopCommentMark =
" " + m_highlight->getCommentEnd();
03361
03362 editStart();
03363
03364
03365 insertText (line, 0, startCommentMark);
03366
03367
03368
int col = buffer->plainLine(line)->length();
03369
03370
03371 insertText (line, col, stopCommentMark);
03372
03373 editEnd();
03374 }
03375
03376
03377
03378
03379
03380
bool KateDocument::removeStartStopCommentFromSingleLine(
int line)
03381 {
03382 QString shortStartCommentMark = m_highlight->getCommentStart();
03383 QString longStartCommentMark = shortStartCommentMark +
" ";
03384 QString shortStopCommentMark = m_highlight->getCommentEnd();
03385 QString longStopCommentMark =
" " + shortStopCommentMark;
03386
03387 editStart();
03388
03389
03390
bool removedStart = (removeStringFromBegining(line, longStartCommentMark)
03391 || removeStringFromBegining(line, shortStartCommentMark));
03392
03393
bool removedStop =
false;
03394
if (removedStart)
03395 {
03396
03397 removedStop = (removeStringFromEnd(line, longStopCommentMark)
03398 || removeStringFromEnd(line, shortStopCommentMark));
03399 }
03400
03401 editEnd();
03402
03403
return (removedStart || removedStop);
03404 }
03405
03406
03407
03408
03409
03410
03411
void KateDocument::addStartStopCommentToSelection()
03412 {
03413 QString startComment = m_highlight->getCommentStart();
03414 QString endComment = m_highlight->getCommentEnd();
03415
03416
int sl = selectStart.line();
03417
int el = selectEnd.line();
03418
int sc = selectStart.col();
03419
int ec = selectEnd.col();
03420
03421
if ((ec == 0) && ((el-1) >= 0))
03422 {
03423 el--;
03424 ec = buffer->plainLine (el)->length();
03425 }
03426
03427 editStart();
03428
03429 insertText (el, ec, endComment);
03430 insertText (sl, sc, startComment);
03431
03432 editEnd ();
03433
03434
03435 ec += endComment.
length() + ( (el == sl) ? startComment.
length() : 0 );
03436 setSelection(sl, sc, el, ec);
03437 }
03438
03439
03440
03441
03442
03443
void KateDocument::addStartLineCommentToSelection()
03444 {
03445 QString commentLineMark = m_highlight->getCommentSingleLineStart() +
" ";
03446
03447
int sl = selectStart.line();
03448
int el = selectEnd.line();
03449
03450
if ((selectEnd.col() == 0) && ((el-1) >= 0))
03451 {
03452 el--;
03453 }
03454
03455 editStart();
03456
03457
03458
for (
int z = el; z >= sl; z--) {
03459 insertText (z, 0, commentLineMark);
03460 }
03461
03462 editEnd ();
03463
03464
03465 selectEnd.setCol(selectEnd.col() + ((el == selectEnd.line()) ? commentLineMark.
length() : 0) );
03466 setSelection(selectStart.line(), 0, selectEnd.line(), selectEnd.col());
03467 }
03468
03469
bool KateDocument::nextNonSpaceCharPos(
int &line,
int &col)
03470 {
03471
for(; line < (
int)buffer->count(); line++) {
03472 col = buffer->plainLine(line)->nextNonSpaceChar(col);
03473
if(col != -1)
03474
return true;
03475 col = 0;
03476 }
03477
03478 line = -1;
03479 col = -1;
03480
return false;
03481 }
03482
03483
bool KateDocument::previousNonSpaceCharPos(
int &line,
int &col)
03484 {
03485
while(
true)
03486 {
03487 col = buffer->plainLine(line)->previousNonSpaceChar(col);
03488
if(col != -1)
return true;
03489
if(line == 0)
return false;
03490 --line;
03491 col = buffer->plainLine(line)->length();
03492 }
03493
03494 line = -1;
03495 col = -1;
03496
return false;
03497 }
03498
03499
03500
03501
03502
03503
bool KateDocument::removeStartStopCommentFromSelection()
03504 {
03505 QString startComment = m_highlight->getCommentStart();
03506 QString endComment = m_highlight->getCommentEnd();
03507
03508
int sl = selectStart.line();
03509
int el = selectEnd.line();
03510
int sc = selectStart.col();
03511
int ec = selectEnd.col();
03512
03513
03514
if (ec != 0) {
03515 ec--;
03516 }
else {
03517
if (el > 0) {
03518 el--;
03519 ec = buffer->plainLine(el)->length() - 1;
03520 }
03521 }
03522
03523
int startCommentLen = startComment.
length();
03524
int endCommentLen = endComment.
length();
03525
03526
03527
03528
bool remove = nextNonSpaceCharPos(sl, sc)
03529 && buffer->plainLine(sl)->stringAtPos(sc, startComment)
03530 && previousNonSpaceCharPos(el, ec)
03531 && ( (ec - endCommentLen + 1) >= 0 )
03532 && buffer->plainLine(el)->stringAtPos(ec - endCommentLen + 1, endComment);
03533
03534
if (remove) {
03535 editStart();
03536
03537 removeText (el, ec - endCommentLen + 1, el, ec + 1);
03538 removeText (sl, sc, sl, sc + startCommentLen);
03539
03540 editEnd ();
03541
03542
03543 ec -= endCommentLen + ( (el == sl) ? startCommentLen : 0 );
03544 setSelection(sl, sc, el, ec + 1);
03545 }
03546
03547
return remove;
03548 }
03549
03550
03551
03552
03553
03554
bool KateDocument::removeStartLineCommentFromSelection()
03555 {
03556 QString shortCommentMark = m_highlight->getCommentSingleLineStart();
03557 QString longCommentMark = shortCommentMark +
" ";
03558
03559
int sl = selectStart.line();
03560
int el = selectEnd.line();
03561
03562
if ((selectEnd.col() == 0) && ((el-1) >= 0))
03563 {
03564 el--;
03565 }
03566
03567
03568
int removeLength = 0;
03569
if (buffer->plainLine(el)->startingWith(longCommentMark))
03570 removeLength = longCommentMark.
length();
03571
else if (buffer->plainLine(el)->startingWith(shortCommentMark))
03572 removeLength = shortCommentMark.
length();
03573
03574
bool removed =
false;
03575
03576 editStart();
03577
03578
03579
for (
int z = el; z >= sl; z--)
03580 {
03581
03582 removed = (removeStringFromBegining(z, longCommentMark)
03583 || removeStringFromBegining(z, shortCommentMark)
03584 || removed);
03585 }
03586
03587 editEnd();
03588
03589
if(removed) {
03590
03591 selectEnd.setCol(selectEnd.col() - ((el == selectEnd.line()) ? removeLength : 0) );
03592 setSelection(selectStart.line(), selectStart.col(), selectEnd.line(), selectEnd.col());
03593 }
03594
03595
return removed;
03596 }
03597
03598
03599
03600
03601
03602
void KateDocument::comment( KateView *, uint line,
int change)
03603 {
03604
bool hasStartLineCommentMark = !(m_highlight->getCommentSingleLineStart().isEmpty());
03605
bool hasStartStopCommentMark = ( !(m_highlight->getCommentStart().isEmpty())
03606 && !(m_highlight->getCommentEnd().isEmpty()) );
03607
03608
bool removed =
false;
03609
03610
if (change > 0)
03611 {
03612
if ( !hasSelection() )
03613 {
03614
if ( hasStartLineCommentMark )
03615 addStartLineCommentToSingleLine(line);
03616
else if ( hasStartStopCommentMark )
03617 addStartStopCommentToSingleLine(line);
03618 }
03619
else
03620 {
03621
03622
03623
03624
03625
03626
03627
03628
if ( hasStartStopCommentMark &&
03629 ( !hasStartLineCommentMark || (
03630 ( selectStart.col() > buffer->plainLine( selectStart.line() )->firstChar() ) ||
03631 ( selectEnd.col() < ((
int)buffer->plainLine( selectEnd.line() )->length()) )
03632 ) ) )
03633 addStartStopCommentToSelection();
03634
else if ( hasStartLineCommentMark )
03635 addStartLineCommentToSelection();
03636 }
03637 }
03638
else
03639 {
03640
if ( !hasSelection() )
03641 {
03642 removed = ( hasStartLineCommentMark
03643 && removeStartLineCommentFromSingleLine(line) )
03644 || ( hasStartStopCommentMark
03645 && removeStartStopCommentFromSingleLine(line) );
03646 }
03647
else
03648 {
03649
03650 removed = ( hasStartLineCommentMark
03651 && removeStartLineCommentFromSelection() )
03652 || ( hasStartStopCommentMark
03653 && removeStartStopCommentFromSelection() );
03654 }
03655 }
03656 }
03657
03658
void KateDocument::transform( KateView *,
const KateTextCursor &c,
03659 KateDocument::TextTransform t )
03660 {
03661 editStart();
03662
if ( hasSelection() )
03663 {
03664
int ln = selStartLine();
03665
while ( ln <= selEndLine() )
03666 {
03667 uint start,
end;
03668 start = (ln == selStartLine() || blockSelectionMode()) ?
03669 selStartCol() : 0;
03670
end = (ln == selEndLine() || blockSelectionMode()) ?
03671 selEndCol() : lineLength( ln );
03672 QString s = text( ln, start, ln, end );
03673
03674
if ( t == Uppercase )
03675 s = s.
upper();
03676
else if ( t == Lowercase )
03677 s = s.
lower();
03678
else
03679 {
03680 TextLine::Ptr l = buffer->plainLine( ln );
03681 uint p ( 0 );
03682
while( p < s.
length() )
03683 {
03684
03685
03686
03687
03688
if ( ( ! start && ! p ) ||
03689 ( ( ln == selStartLine() || blockSelectionMode() ) &&
03690 ! p && ! m_highlight->isInWord( l->getChar( start - 1 ) ) ) ||
03691 ( p && ! m_highlight->isInWord( s.
at( p-1 ) ) )
03692 )
03693 s[p] = s.
at(p).upper();
03694 p++;
03695 }
03696 }
03697
03698 removeText( ln, start, ln, end );
03699 insertText( ln, start, s );
03700
03701 ln++;
03702 }
03703 }
else {
03704 QString s;
03705 uint cline(c.
line() ), ccol( c.
col() );
03706
int n ( ccol );
03707
switch ( t ) {
03708
case Uppercase:
03709 s = text( cline, ccol, cline, ccol + 1 ).
upper();
03710
break;
03711
case Lowercase:
03712 s = text( cline, ccol, cline, ccol + 1 ).
lower();
03713
break;
03714
case Capitalize:
03715 {
03716 TextLine::Ptr l = buffer->plainLine( cline );
03717
while ( n > 0 && m_highlight->isInWord( l->getChar( n-1 ) ) )
03718 n--;
03719 s = text( cline, n, cline, n + 1 ).
upper();
03720 }
03721
break;
03722
default:
03723
break;
03724 }
03725 removeText( cline, n, cline, n+1 );
03726 insertText( cline, n, s );
03727 }
03728 editEnd();
03729 }
03730
03731
void KateDocument::joinLines( uint first, uint last )
03732 {
03733
03734 editStart();
03735
int l( first );
03736
while ( first < last )
03737 {
03738 editUnWrapLine( l );
03739 first++;
03740 }
03741 editEnd();
03742 }
03743
03744 QString KateDocument::getWord(
const KateTextCursor& cursor ) {
03745
int start,
end, len;
03746
03747 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
03748 len = textLine->length();
03749 start =
end = cursor.
col();
03750
if (start > len)
03751
return QString(
"");
03752
03753
while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
03754
while (
end < len && m_highlight->isInWord(textLine->getChar(end)))
end++;
03755 len =
end - start;
03756
return QString(&textLine->text()[start], len);
03757 }
03758
03759
void KateDocument::tagLines(
int start,
int end)
03760 {
03761
for (uint z = 0; z < m_views.count(); z++)
03762 m_views.at(z)->tagLines (start, end,
true);
03763 }
03764
03765
void KateDocument::tagLines(
KateTextCursor start,
KateTextCursor end)
03766 {
03767
03768
if (blockSelectionMode() && start.
col() >
end.col()) {
03769
int sc = start.
col();
03770 start.
setCol(
end.col());
03771
end.setCol(sc);
03772 }
03773
03774
for (uint z = 0; z < m_views.count(); z++)
03775 m_views.at(z)->tagLines(start, end,
true);
03776 }
03777
03778
void KateDocument::tagSelection(
const KateTextCursor &oldSelectStart,
const KateTextCursor &oldSelectEnd)
03779 {
03780
if (hasSelection()) {
03781
if (oldSelectStart.
line() == -1) {
03782
03783
03784
03785 tagLines(selectStart, selectEnd);
03786
03787 }
else if (blockSelectionMode() && (oldSelectStart.
col() != selectStart.col() || oldSelectEnd.
col() != selectEnd.col())) {
03788
03789 tagLines(selectStart, selectEnd);
03790 tagLines(oldSelectStart, oldSelectEnd);
03791
03792 }
else {
03793
if (oldSelectStart != selectStart) {
03794
if (oldSelectStart < selectStart)
03795 tagLines(oldSelectStart, selectStart);
03796
else
03797 tagLines(selectStart, oldSelectStart);
03798 }
03799
03800
if (oldSelectEnd != selectEnd) {
03801
if (oldSelectEnd < selectEnd)
03802 tagLines(oldSelectEnd, selectEnd);
03803
else
03804 tagLines(selectEnd, oldSelectEnd);
03805 }
03806 }
03807
03808 }
else {
03809
03810 tagLines(oldSelectStart, oldSelectEnd);
03811 }
03812 }
03813
03814
void KateDocument::repaintViews(
bool paintOnlyDirty)
03815 {
03816
for (uint z = 0; z < m_views.count(); z++)
03817 m_views.at(z)->repaintText(paintOnlyDirty);
03818 }
03819
03820
void KateDocument::tagAll()
03821 {
03822
for (uint z = 0; z < m_views.count(); z++)
03823 {
03824 m_views.at(z)->tagAll();
03825 m_views.at(z)->updateView (
true);
03826 }
03827 }
03828
03829
void KateDocument::slotBufferChanged()
03830 {
03831 updateViews();
03832 }
03833
03834
void KateDocument::updateViews()
03835 {
03836
if (noViewUpdates)
03837
return;
03838
03839
for (KateView * view = m_views.first(); view != 0L; view = m_views.next() )
03840 {
03841 view->updateView(
true);
03842 }
03843 }
03844
03845 uint KateDocument::configFlags ()
03846 {
03847
return config()->configFlags();
03848 }
03849
03850
void KateDocument::setConfigFlags (uint flags)
03851 {
03852 config()->setConfigFlags(flags);
03853 }
03854
03855
bool KateDocument::lineColSelected (
int line,
int col)
03856 {
03857
if ( (!blockSelect) && (col < 0) )
03858 col = 0;
03859
03860
KateTextCursor cursor(line, col);
03861
03862
if (blockSelect)
03863
return cursor.
line() >= selectStart.line() && cursor.
line() <= selectEnd.line() && cursor.
col() >= selectStart.col() && cursor.
col() < selectEnd.col();
03864
else
03865
return (cursor >= selectStart) && (cursor < selectEnd);
03866 }
03867
03868
bool KateDocument::lineSelected (
int line)
03869 {
03870
return (!blockSelect)
03871 && (selectStart <=
KateTextCursor(line, 0))
03872 && (line < selectEnd.line());
03873 }
03874
03875
bool KateDocument::lineEndSelected (
int line,
int endCol)
03876 {
03877
return (!blockSelect)
03878 && (line > selectStart.line() || (line == selectStart.line() && (selectStart.col() < endCol || endCol == -1)))
03879 && (line < selectEnd.line() || (line == selectEnd.line() && (endCol <= selectEnd.col() && endCol != -1)));
03880 }
03881
03882
bool KateDocument::lineHasSelected (
int line)
03883 {
03884
return (selectStart < selectEnd)
03885 && (line >= selectStart.line())
03886 && (line <= selectEnd.line());
03887 }
03888
03889
bool KateDocument::lineIsSelection (
int line)
03890 {
03891
return (line == selectStart.line() && line == selectEnd.line());
03892 }
03893
03894
inline bool isStartBracket(
const QChar& c ) {
return c ==
'{' || c ==
'[' || c ==
'('; }
03895
inline bool isEndBracket (
const QChar& c ) {
return c ==
'}' || c ==
']' || c ==
')'; }
03896
inline bool isBracket (
const QChar& c ) {
return isStartBracket( c ) || isEndBracket( c ); }
03897
03898
03899
03900
03901
03902
03903
03904
03905
03906
03907
03908
void KateDocument::newBracketMark(
const KateTextCursor& cursor, KateTextRange& bm )
03909 {
03910 bm.setValid(
false);
03911
03912 bm.start() = cursor;
03913
03914
if( !findMatchingBracket( bm.start(), bm.end() ) )
03915
return;
03916
03917 bm.setValid(
true);
03918 }
03919
03920
bool KateDocument::findMatchingBracket(
KateTextCursor& start,
KateTextCursor& end )
03921 {
03922 TextLine::Ptr textLine = buffer->plainLine( start.
line() );
03923
if( !textLine )
03924
return false;
03925
03926
QChar right = textLine->getChar( start.
col() );
03927
QChar left = textLine->getChar( start.
col() - 1 );
03928
QChar bracket;
03929
03930
if ( config()->configFlags() & cfOvr ) {
03931
if( isBracket( right ) ) {
03932 bracket = right;
03933 }
else {
03934
return false;
03935 }
03936 }
else if ( isEndBracket( left ) ) {
03937 start.
setCol(start.
col() - 1);
03938 bracket = left;
03939 }
else if ( isStartBracket( right ) ) {
03940 bracket = right;
03941 }
else if ( isBracket( left ) ) {
03942 start.
setCol(start.
col() - 1);
03943 bracket = left;
03944 }
else if ( isBracket( right ) ) {
03945 bracket = right;
03946 }
else {
03947
return false;
03948 }
03949
03950
QChar opposite;
03951
03952
switch( bracket ) {
03953
case '{': opposite =
'}';
break;
03954
case '}': opposite =
'{';
break;
03955
case '[': opposite =
']';
break;
03956
case ']': opposite =
'[';
break;
03957
case '(': opposite =
')';
break;
03958
case ')': opposite =
'(';
break;
03959
default:
return false;
03960 }
03961
03962
bool forward = isStartBracket( bracket );
03963
int startAttr = textLine->attribute( start.
col() );
03964 uint count = 0;
03965
end = start;
03966
03967
while(
true ) {
03968
03969
if(
forward ) {
03970
end.setCol(
end.col() + 1);
03971
if(
end.col() >= lineLength(
end.line() ) ) {
03972
if(
end.line() >= (
int)lastLine() )
03973
return false;
03974
end.setPos(
end.line() + 1, 0);
03975 textLine = buffer->plainLine(
end.line() );
03976 }
03977 }
else {
03978
end.setCol(
end.col() - 1);
03979
if(
end.col() < 0 ) {
03980
if(
end.line() <= 0 )
03981
return false;
03982
end.setLine(
end.line() - 1);
03983
end.setCol(lineLength(
end.line() ) - 1);
03984 textLine = buffer->plainLine(
end.line() );
03985 }
03986 }
03987
03988
03989
if( textLine->attribute(
end.col() ) != startAttr )
03990
continue;
03991
03992
03993
QChar c = textLine->getChar(
end.col() );
03994
if( c == bracket ) {
03995 count++;
03996 }
else if( c == opposite ) {
03997
if( count == 0 )
03998
return true;
03999 count--;
04000 }
04001
04002 }
04003 }
04004
04005
void KateDocument::guiActivateEvent(
KParts::GUIActivateEvent *ev )
04006 {
04007
KParts::ReadWritePart::guiActivateEvent( ev );
04008
if ( ev->
activated() )
04009 emit selectionChanged();
04010 }
04011
04012
void KateDocument::setDocName (QString name )
04013 {
04014
if ( !
name.
isEmpty() )
04015 {
04016
04017 m_docName =
name;
04018 emit nameChanged((
Kate::Document *)
this);
04019
return;
04020 }
04021
04022
04023
if ( !m_docName.isEmpty() && m_docName.startsWith( url().filename() ) )
return;
04024
04025
int count = -1;
04026
04027
for (uint z=0; z < KateFactory::self()->documents()->count(); z++)
04028 {
04029
if ( (KateFactory::self()->documents()->at(z) !=
this) && (KateFactory::self()->documents()->at(z)->url().filename() == url().filename()) )
04030
if ( KateFactory::self()->documents()->at(z)->m_docNameNumber > count )
04031 count = KateFactory::self()->documents()->at(z)->m_docNameNumber;
04032 }
04033
04034 m_docNameNumber = count + 1;
04035
04036 m_docName = url().filename();
04037
04038
if (m_docName.isEmpty())
04039 m_docName = i18n (
"Untitled");
04040
04041
if (m_docNameNumber > 0)
04042 m_docName = QString(m_docName +
" (%1)").arg(m_docNameNumber+1);
04043
04044 emit nameChanged ((
Kate::Document *)
this);
04045 }
04046
04047
void KateDocument::isModOnHD(
bool )
04048 {
04049
if (m_modOnHd && !url().isEmpty())
04050 {
04051 reloadFile();
04052 }
04053 }
04054
04055
class KateDocumentTmpMark
04056 {
04057
public:
04058 QString line;
04059 KTextEditor::Mark mark;
04060 };
04061
04062
void KateDocument::reloadFile()
04063 {
04064
if ( !url().isEmpty() )
04065 {
04066
if (m_modOnHd)
04067 {
04068 QString str;
04069
04070
if (m_modOnHdReason == 1)
04071 str = i18n(
"The file %1 was changed (modified) on disc by another program!\n\n").
arg(url().fileName());
04072
else if (m_modOnHdReason == 2)
04073 str = i18n(
"The file %1 was changed (created) on disc by another program!\n\n").
arg(url().fileName());
04074
else if (m_modOnHdReason == 3)
04075 str = i18n(
"The file %1 was changed (deleted) on disc by another program!\n\n").
arg(url().fileName());
04076
04077
int i =
KMessageBox::warningYesNoCancel
04078 (0, str + i18n(
"Do you really want to reload the modified file? Data loss may occur."));
04079
if ( i != KMessageBox::Yes)
04080 {
04081
if (i == KMessageBox::No)
04082 {
04083 m_modOnHd =
false;
04084 m_modOnHdReason = 0;
04085 emit modifiedOnDisc (
this, m_modOnHd, 0);
04086 }
04087
04088
return;
04089 }
04090 }
04091
QValueList<KateDocumentTmpMark> tmp;
04092
04093
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks ); it.
current(); ++it )
04094 {
04095 KateDocumentTmpMark m;
04096
04097 m.line = buffer->textLine (it.
current()->line);
04098 m.mark = *it.
current();
04099
04100 tmp.
append (m);
04101 }
04102
04103 uint mode = hlMode ();
04104
bool byUser = hlSetByUser;
04105
04106 m_reloading =
true;
04107 KateDocument::openURL( url() );
04108 m_reloading =
false;
04109
04110
for (uint z=0; z < tmp.
size(); z++)
04111 {
04112
if (z < numLines())
04113 {
04114
if (buffer->textLine(tmp[z].mark.line) == tmp[z].line)
04115 setMark (tmp[z].mark.line, tmp[z].mark.type);
04116 }
04117 }
04118
04119
if (byUser)
04120 setHlMode (mode);
04121 }
04122 }
04123
04124
void KateDocument::flush ()
04125 {
04126 closeURL ();
04127 }
04128
04129
void KateDocument::setWordWrap (
bool on)
04130 {
04131 config()->setWordWrap (on);
04132 }
04133
04134
bool KateDocument::wordWrap ()
04135 {
04136
return config()->wordWrap ();
04137 }
04138
04139
void KateDocument::setWordWrapAt (uint col)
04140 {
04141 config()->setWordWrapAt (col);
04142 }
04143
04144
unsigned int KateDocument::wordWrapAt ()
04145 {
04146
return config()->wordWrapAt ();
04147 }
04148
04149
void KateDocument::applyWordWrap ()
04150 {
04151
if (hasSelection())
04152 wrapText (selectStart.line(), selectEnd.line());
04153
else
04154 wrapText (0, lastLine());
04155 }
04156
04157
void KateDocument::setPageUpDownMovesCursor (
bool on)
04158 {
04159 config()->setPageUpDownMovesCursor (on);
04160 }
04161
04162
bool KateDocument::pageUpDownMovesCursor ()
04163 {
04164
return config()->pageUpDownMovesCursor ();
04165 }
04166
04167
void KateDocument::exportAs(
const QString& filter)
04168 {
04169
if (filter==
"kate_html_export")
04170 {
04171 QString filename=
KFileDialog::getSaveFileName(QString::null,
"text/html",0,i18n(
"Export File As"));
04172
if (filename.
isEmpty())
04173 {
04174
return;
04175 }
04176
KSaveFile *savefile=
new KSaveFile(filename);
04177
if (!savefile->
status())
04178 {
04179
if (exportDocumentToHTML(savefile->
textStream(),filename)) savefile->
close();
04180
else savefile->
abort();
04181
04182 }
else {}
04183
delete savefile;
04184 }
04185 }
04186
04187
04188
bool KateDocument::exportDocumentToHTML(
QTextStream *outputStream,
const QString &name)
04189 {
04190 outputStream->
setEncoding(QTextStream::UnicodeUTF8);
04191
04192 (*outputStream) <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" <<
endl;
04193 (*outputStream) <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">" <<
endl;
04194 (*outputStream) <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" <<
endl;
04195 (*outputStream) <<
"<head>" <<
endl;
04196 (*outputStream) <<
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />" <<
endl;
04197 (*outputStream) <<
"<meta name=\"Generator\" content=\"Kate, the KDE Advanced Text Editor\" />" <<
endl;
04198
04199 (*outputStream) <<
"<title>" <<
name.
right(
name.
length() -
name.
findRev(
'/') -1) <<
"</title>" <<
endl;
04200 (*outputStream) <<
"</head>" <<
endl;
04201
04202 (*outputStream) <<
"<body><pre>" <<
endl;
04203
04204
04205
04206
bool previousCharacterWasBold =
false;
04207
bool previousCharacterWasItalic =
false;
04208
04209
04210
04211
bool needToReinitializeTags =
false;
04212
QColor previousCharacterColor(0,0,0);
04213 (*outputStream) <<
"<span style='color: #000000'>";
04214
04215
for (uint curLine=0;curLine<numLines();curLine++)
04216 {
04217 TextLine::Ptr textLine = buffer->plainLine(curLine);
04218
04219
04220
for (uint curPos=0;curPos<textLine->length();curPos++)
04221 {
04222
04223
QMemArray<KateAttribute> *attributes = m_highlight->attributes (0);
04224
KateAttribute* charAttributes = 0;
04225
04226
if (textLine->attribute(curPos) < attributes->
size())
04227 charAttributes = &attributes->
at(textLine->attribute(curPos));
04228
else
04229 charAttributes = &attributes->
at(0);
04230
04231
04232
04233
if ( (charAttributes->
textColor() != previousCharacterColor))
04234 {
04235
04236
if (previousCharacterWasBold)
04237 (*outputStream) <<
"</b>";
04238
if (previousCharacterWasItalic)
04239 (*outputStream) <<
"</i>";
04240
04241
04242 (*outputStream) <<
"</span>";
04243
04244
int red, green, blue;
04245
04246 charAttributes->
textColor().
rgb(&red, &green, &blue);
04247 (*outputStream) <<
"<span style='color: #"
04248 << ( (red < 0x10)?
"0":
"")
04249 <<
QString::number(red, 16)
04250 << ( (green < 0x10)?
"0":
"")
04251 <<
QString::number(green, 16)
04252 << ( (blue < 0x10)?
"0":
"")
04253 <<
QString::number(blue, 16)
04254 <<
"'>";
04255
04256 needToReinitializeTags =
true;
04257 }
04258
04259
if ( (needToReinitializeTags && charAttributes->
bold()) ||
04260 (!previousCharacterWasBold && charAttributes->
bold()) )
04261
04262 (*outputStream) <<
"<b>";
04263
if ( !needToReinitializeTags && (previousCharacterWasBold && !charAttributes->
bold()) )
04264
04265 (*outputStream) <<
"</b>";
04266
04267
04268
if ( (needToReinitializeTags && charAttributes->
italic()) ||
04269 (!previousCharacterWasItalic && charAttributes->
italic()) )
04270
04271 (*outputStream) <<
"<i>";
04272
if ( !needToReinitializeTags && (previousCharacterWasItalic && !charAttributes->
italic()) )
04273
04274 (*outputStream) <<
"</i>";
04275
04276
04277 (*outputStream) << HTMLEncode(textLine->getChar(curPos));
04278
04279
04280 previousCharacterWasItalic = charAttributes->
italic();
04281 previousCharacterWasBold = charAttributes->
bold();
04282 previousCharacterColor = charAttributes->
textColor();
04283 needToReinitializeTags =
false;
04284 }
04285
04286 (*outputStream) <<
endl;
04287 }
04288
04289
04290
if (previousCharacterWasBold)
04291 (*outputStream) <<
"</b>";
04292
if (previousCharacterWasItalic)
04293 (*outputStream) <<
"</i>";
04294
04295
04296 (*outputStream) <<
"</span>";
04297 (*outputStream) <<
"</pre></body>";
04298 (*outputStream) <<
"</html>";
04299
04300
return true;
04301 }
04302
04303 QString KateDocument::HTMLEncode(
QChar theChar)
04304 {
04305
switch (theChar.
latin1())
04306 {
04307
case '>':
04308
return QString(
">");
04309
case '<':
04310
return QString(
"<");
04311
case '&':
04312
return QString(
"&");
04313 };
04314
return theChar;
04315 }
04316
04317 Kate::ConfigPage *KateDocument::colorConfigPage (
QWidget *p)
04318 {
04319
return (Kate::ConfigPage*)
new KateSchemaConfigPage (p);
04320 }
04321
04322 Kate::ConfigPage *KateDocument::viewDefaultsConfigPage (
QWidget *p)
04323 {
04324
return (Kate::ConfigPage*)
new ViewDefaultsConfig(p);
04325 }
04326
04327 Kate::ConfigPage *KateDocument::fontConfigPage (
QWidget *p)
04328 {
04329
return (Kate::ConfigPage*)
new KateSchemaConfigPage (p);
04330 }
04331
04332 Kate::ConfigPage *KateDocument::indentConfigPage (
QWidget *p)
04333 {
04334
return (Kate::ConfigPage*)
new IndentConfigTab(p);
04335 }
04336
04337 Kate::ConfigPage *KateDocument::selectConfigPage (
QWidget *p)
04338 {
04339
return (Kate::ConfigPage*)
new SelectConfigTab(p);
04340 }
04341
04342 Kate::ConfigPage *KateDocument::editConfigPage (
QWidget *p)
04343 {
04344
return (Kate::ConfigPage*)
new EditConfigTab(p);
04345 }
04346
04347 Kate::ConfigPage *KateDocument::keysConfigPage (
QWidget *p)
04348 {
04349
return (Kate::ConfigPage*)
new EditKeyConfiguration(p,
this);
04350 }
04351
04352 Kate::ConfigPage *KateDocument::hlConfigPage (
QWidget *p)
04353 {
04354
return (Kate::ConfigPage*)
new HlConfigPage (p);
04355 }
04356
04357 Kate::ConfigPage *KateDocument::saveConfigPage(
QWidget *p)
04358 {
04359
return (Kate::ConfigPage*)
new SaveConfigTab(p);
04360 }
04361
04362 Kate::ActionMenu *KateDocument::hlActionMenu (
const QString& text,
QObject* parent,
const char* name)
04363 {
04364 KateViewHighlightAction *menu =
new KateViewHighlightAction (text, parent, name);
04365 menu->setWhatsThis(i18n(
"Here you can choose how the current document should be highlighted."));
04366 menu->updateMenu (
this);
04367
04368
return (Kate::ActionMenu *)menu;
04369 }
04370
04371 Kate::ActionMenu *KateDocument::exportActionMenu (
const QString& text,
QObject* parent,
const char* name)
04372 {
04373 KateExportAction *menu =
new KateExportAction (text, parent, name);
04374 menu->updateMenu (
this);
04375 menu->setWhatsThis(i18n(
"This command allows you to export the current document"
04376
" with all highlighting information into a markup document, e.g. HTML."));
04377
return (Kate::ActionMenu *)menu;
04378 }
04379
04380
void KateDocument::dumpRegionTree()
04381 {
04382 buffer->dumpRegionTree();
04383 }
04384
04385
unsigned int KateDocument::getRealLine(
unsigned int virtualLine)
04386 {
04387
return buffer->lineNumber (virtualLine);
04388 }
04389
04390
unsigned int KateDocument::getVirtualLine(
unsigned int realLine)
04391 {
04392
return buffer->lineVisibleNumber (realLine);
04393 }
04394
04395
unsigned int KateDocument::visibleLines ()
04396 {
04397
return buffer->countVisible ();
04398 }
04399
04400 TextLine::Ptr KateDocument::kateTextLine(uint i)
04401 {
04402
return buffer->line (i);
04403 }
04404
04405 TextLine::Ptr KateDocument::plainKateTextLine(uint i)
04406 {
04407
return buffer->plainLine (i);
04408 }
04409
04410
04411
04412
04413 KTextEditor::Cursor *KateDocument::createCursor ( )
04414 {
04415
return new KateSuperCursor (
this,
false, 0, 0,
this);
04416 }
04417
04418
void KateDocument::tagArbitraryLines(KateView* view,
KateSuperRange* range)
04419 {
04420
if (view)
04421 view->tagLines(range->
start(), range->
end());
04422
else
04423 tagLines(range->
start(), range->
end());
04424 }
04425
04426
04427
04428
04429
void KateDocument::spellcheck()
04430 {
04431
if( !isReadWrite() || text().
isEmpty())
04432
return;
04433
04434 m_kspell =
new KSpell( 0, i18n(
"Spellcheck"),
04435
this, SLOT(ready(KSpell *)) );
04436
04437 connect( m_kspell, SIGNAL(death()),
04438
this, SLOT(spellCleanDone()) );
04439
04440 connect( m_kspell, SIGNAL(misspelling(
const QString&,
const QStringList&,
unsigned int)),
04441
this, SLOT(misspelling(
const QString&,
const QStringList&,
unsigned int)) );
04442 connect( m_kspell, SIGNAL(corrected(
const QString&,
const QString&,
unsigned int)),
04443
this, SLOT(corrected(
const QString&,
const QString&,
unsigned int)) );
04444 connect( m_kspell, SIGNAL(
done(
const QString&)),
04445
this, SLOT(spellResult(
const QString&)) );
04446 }
04447
04448
void KateDocument::ready(KSpell *)
04449 {
04450 m_mispellCount = 0;
04451 m_replaceCount = 0;
04452
04453 m_kspell->setProgressResolution( 1 );
04454
04455 m_kspell->check( text() );
04456
04457
kdDebug () <<
"SPELLING READY STATUS: " << m_kspell->status () <<
endl;
04458 }
04459
04460
void KateDocument::locatePosition( uint pos, uint& line, uint& col )
04461 {
04462 uint cnt = 0;
04463
04464 line = col = 0;
04465
04466
04467
04468
04469
for( ; line < numLines() && cnt <= pos; line++ )
04470 cnt += lineLength(line) + 1;
04471
04472 line--;
04473 col = pos - (cnt - lineLength(line)) + 1;
04474 }
04475
04476
void KateDocument::misspelling(
const QString& origword,
const QStringList&,
unsigned int pos )
04477 {
04478 m_mispellCount++;
04479
04480 uint line, col;
04481
04482 locatePosition( pos, line, col );
04483
04484
if (activeView())
04485 activeView()->setCursorPositionInternal (line, col, 1);
04486
04487 setSelection( line, col, line, col + origword.
length() );
04488 }
04489
04490
void KateDocument::corrected(
const QString& originalword,
const QString& newword,
unsigned int pos )
04491 {
04492 m_replaceCount++;
04493
04494 uint line, col;
04495
04496 locatePosition( pos, line, col );
04497
04498 removeText( line, col, line, col + originalword.
length() );
04499 insertText( line, col, newword );
04500 }
04501
04502
void KateDocument::spellResult(
const QString& )
04503 {
04504 clearSelection();
04505 m_kspell->cleanUp();
04506 }
04507
04508
void KateDocument::spellCleanDone()
04509 {
04510
KSpell::spellStatus status = m_kspell->status();
04511
04512
if( status == KSpell::Error ) {
04513
KMessageBox::sorry( 0,
04514 i18n(
"ISpell could not be started. "
04515
"Please make sure you have ISpell "
04516
"properly configured and in your PATH."));
04517 }
else if( status == KSpell::Crashed ) {
04518
KMessageBox::sorry( 0,
04519 i18n(
"ISpell seems to have crashed."));
04520 }
04521
04522
delete m_kspell;
04523 m_kspell = 0;
04524
04525
kdDebug () <<
"SPELLING END" <<
endl;
04526 }
04527
04528
04529
void KateDocument::lineInfo (KateLineInfo *info,
unsigned int line)
04530 {
04531 buffer->lineInfo(info,line);
04532 }
04533
04534 KateCodeFoldingTree *KateDocument::foldingTree ()
04535 {
04536
return buffer->foldingTree();
04537 }
04538
04539
void KateDocument::setEncoding (
const QString &e)
04540 {
04541 m_config->setEncoding(e);
04542 }
04543
04544 QString KateDocument::encoding()
const
04545
{
04546
return m_config->encoding();
04547 }
04548
04549
void KateDocument::updateConfig ()
04550 {
04551 emit undoChanged ();
04552 tagAll();
04553
04554
for (KateView * view = m_views.first(); view != 0L; view = m_views.next() )
04555 {
04556 view->updateDocumentConfig ();
04557 }
04558
04559
04560
if (m_indenter->modeNumber() != m_config->indentationMode())
04561 {
04562
delete m_indenter;
04563 m_indenter = KateAutoIndent::createIndenter (
this, m_config->indentationMode() );
04564 }
04565
04566 m_indenter->updateConfig();
04567
04568 buffer->setTabWidth (config()->tabWidth());
04569
04570
04571
for (uint i=0; i<KateFactory::self()->plugins().count(); i++)
04572 {
04573
if (config()->plugin (i))
04574 loadPlugin (i);
04575
else
04576 unloadPlugin (i);
04577 }
04578 }
04579
04580
04581
04582
04583
04584
04585
04586
04587
QRegExp KateDocument::kvLine =
QRegExp(
"kate:(.*)");
04588 QRegExp KateDocument::kvVar = QRegExp(
"([\\w\\-]+)\\s+([^;]+)");
04589
04590
void KateDocument::readVariables(
bool onlyViewAndRenderer)
04591 {
04592
if (!onlyViewAndRenderer)
04593 m_config->configStart();
04594
04595
04596 KateView *v;
04597
for (v = m_views.first(); v != 0L; v= m_views.next() )
04598 {
04599 v->config()->configStart();
04600 v->renderer()->config()->configStart();
04601 }
04602
04603
for (uint i=0; i < QMIN( 9, numLines() ); ++i )
04604 {
04605 readVariableLine( textLine( i ), onlyViewAndRenderer );
04606 }
04607
if ( numLines() > 10 )
04608 {
04609
for ( uint i = QMAX(10, numLines() - 10); i < numLines(); ++i )
04610 {
04611 readVariableLine( textLine( i ), onlyViewAndRenderer );
04612 }
04613 }
04614
04615
if (!onlyViewAndRenderer)
04616 m_config->configEnd();
04617
04618
for (v = m_views.first(); v != 0L; v= m_views.next() )
04619 {
04620 v->config()->configEnd();
04621 v->renderer()->config()->configEnd();
04622 }
04623 }
04624
04625
void KateDocument::readVariableLine( QString t,
bool onlyViewAndRenderer )
04626 {
04627
if ( kvLine.search( t ) > -1 )
04628 {
04629
QStringList vvl;
04630 vvl <<
"dynamic-word-wrap" <<
"dynamic-word-wrap-indicators"
04631 <<
"line-numbers" <<
"icon-border" <<
"folding-markers"
04632 <<
"bookmark-sorting" <<
"auto-center-lines"
04633 <<
"icon-bar-color"
04634
04635 <<
"background-color" <<
"selection-color"
04636 <<
"current-line-color" <<
"bracket-highlight-color"
04637 <<
"word-wrap-marker-color"
04638 <<
"font" <<
"font-size" <<
"scheme";
04639
int p( 0 );
04640 QString s = kvLine.cap(1);
04641 QString var, val;
04642
while ( (p = kvVar.search( s, p )) > -1 )
04643 {
04644 p += kvVar.matchedLength();
04645 var = kvVar.cap( 1 );
04646 val = kvVar.cap( 2 ).
stripWhiteSpace();
04647
bool state;
04648
int n;
04649
04650
04651
if (onlyViewAndRenderer)
04652 {
04653
if ( vvl.contains( var ) )
04654 setViewVariable( var, val );
04655 }
04656
else
04657 {
04658
04659
if ( var ==
"word-wrap" && checkBoolValue( val, &state ) )
04660 setWordWrap( state );
04661
else if ( var ==
"block-selection" && checkBoolValue( val, &state ) )
04662 setBlockSelectionMode( state );
04663
04664
04665
else if ( var ==
"auto-indent" && checkBoolValue( val, &state ) )
04666 m_config->setConfigFlags( KateDocumentConfig::cfAutoIndent, state );
04667
else if ( var ==
"backspace-indents" && checkBoolValue( val, &state ) )
04668 m_config->setConfigFlags( KateDocumentConfig::cfBackspaceIndents, state );
04669
else if ( var ==
"replace-tabs" && checkBoolValue( val, &state ) )
04670 m_config->setConfigFlags( KateDocumentConfig::cfReplaceTabs, state );
04671
else if ( var ==
"wrap-cursor" && checkBoolValue( val, &state ) )
04672 m_config->setConfigFlags( KateDocumentConfig::cfWrapCursor, state );
04673
else if ( var ==
"auto-brackets" && checkBoolValue( val, &state ) )
04674 m_config->setConfigFlags( KateDocumentConfig::cfAutoBrackets, state );
04675
else if ( var ==
"persistent-selection" && checkBoolValue( val, &state ) )
04676 m_config->setConfigFlags( KateDocumentConfig::cfPersistent, state );
04677
else if ( var ==
"keep-selection" && checkBoolValue( val, &state ) )
04678 m_config->setConfigFlags( KateDocumentConfig::cfBackspaceIndents, state );
04679
else if ( var ==
"overwrite-mode" && checkBoolValue( val, &state ) )
04680 m_config->setConfigFlags( KateDocumentConfig::cfOvr, state );
04681
else if ( var ==
"keep-indent-profile" && checkBoolValue( val, &state ) )
04682 m_config->setConfigFlags( KateDocumentConfig::cfKeepIndentProfile, state );
04683
else if ( var ==
"keep-extra-spaces" && checkBoolValue( val, &state ) )
04684 m_config->setConfigFlags( KateDocumentConfig::cfKeepExtraSpaces, state );
04685
else if ( var ==
"tab-indents" && checkBoolValue( val, &state ) )
04686 m_config->setConfigFlags( KateDocumentConfig::cfTabIndents, state );
04687
else if ( var ==
"show-tabs" && checkBoolValue( val, &state ) )
04688 m_config->setConfigFlags( KateDocumentConfig::cfShowTabs, state );
04689
else if ( var ==
"space-indent" && checkBoolValue( val, &state ) )
04690 m_config->setConfigFlags( KateDocumentConfig::cfSpaceIndent, state );
04691
else if ( var ==
"smart-home" && checkBoolValue( val, &state ) )
04692 m_config->setConfigFlags( KateDocumentConfig::cfSmartHome, state );
04693
04694
04695
else if ( var ==
"tab-width" && checkIntValue( val, &n ) )
04696 m_config->setTabWidth( n );
04697
else if ( var ==
"indent-width" && checkIntValue( val, &n ) )
04698 m_config->setIndentationWidth( n );
04699
else if ( var ==
"indent-mode" )
04700 {
04701
if ( checkIntValue( val, &n ) )
04702 m_config->setIndentationMode( n );
04703
else
04704 m_config->setIndentationMode( KateAutoIndent::modeNumber( val) );
04705 }
04706
else if ( var ==
"word-wrap-column" && n > 0 && checkIntValue( val, &n ) )
04707 m_config->setWordWrapAt( n );
04708
else if ( var ==
"undo-steps" && n >= 0 && checkIntValue( val, &n ) )
04709 setUndoSteps( n );
04710
04711
04712
else if ( var ==
"eol" || var ==
"end-of-line" )
04713 {
04714
QStringList l;
04715 l <<
"unix" <<
"dos" <<
"mac";
04716
if ( (n = l.findIndex( val.
lower() )) != -1 )
04717 m_config->setEol( n );
04718 }
04719
else if ( var ==
"encoding" )
04720 m_config->setEncoding( val );
04721
else if ( var ==
"syntax" || var ==
"hl" )
04722 {
04723
for ( uint i=0; i < hlModeCount(); i++ )
04724 {
04725
if ( hlModeName( i ) == val )
04726 {
04727 setHlMode( i );
04728
break;
04729 }
04730 }
04731 }
04732
04733
04734
else if ( vvl.contains( var ) )
04735 setViewVariable( var, val );
04736 }
04737 }
04738 }
04739 }
04740
04741
void KateDocument::setViewVariable( QString var, QString val )
04742 {
04743
04744 KateView *v;
04745
bool state;
04746
int n;
04747
QColor c;
04748
for (v = m_views.first(); v != 0L; v= m_views.next() )
04749 {
04750
if ( var ==
"dynamic-word-wrap" && checkBoolValue( val, &state ) )
04751 v->config()->setDynWordWrap( state );
04752
04753
04754
else if ( var ==
"line-numbers" && checkBoolValue( val, &state ) )
04755 v->config()->setLineNumbers( state );
04756
else if (var ==
"icon-border" && checkBoolValue( val, &state ) )
04757 v->config()->setIconBar( state );
04758
else if (var ==
"folding-markers" && checkBoolValue( val, &state ) )
04759 v->config()->setFoldingBar( state );
04760
else if ( var ==
"auto-center-lines" && checkIntValue( val, &n ) )
04761 v->config()->setAutoCenterLines( n );
04762
else if ( var ==
"icon-bar-color" && checkColorValue( val, c ) )
04763 v->renderer()->config()->setIconBarColor( c );
04764
04765
else if ( var ==
"background-color" && checkColorValue( val, c ) )
04766 v->renderer()->config()->setBackgroundColor( c );
04767
else if ( var ==
"selection-color" && checkColorValue( val, c ) )
04768 v->renderer()->config()->setSelectionColor( c );
04769
else if ( var ==
"current-line-color" && checkColorValue( val, c ) )
04770 v->renderer()->config()->setHighlightedLineColor( c );
04771
else if ( var ==
"bracket-highlight-color" && checkColorValue( val, c ) )
04772 v->renderer()->config()->setHighlightedBracketColor( c );
04773
else if ( var ==
"word-wrap-marker-color" && checkColorValue( val, c ) )
04774 v->renderer()->config()->setWordWrapMarkerColor( c );
04775
else if ( var ==
"font" || ( var ==
"font-size" && checkIntValue( val, &n ) ) )
04776 {
04777
QFont _f( *v->renderer()->config()->font( ) );
04778
04779
if ( var ==
"font" )
04780 {
04781 _f.
setFamily( val );
04782 _f.
setFixedPitch(
QFont( val ).fixedPitch() );
04783 }
04784
else
04785 _f.
setPointSize( n );
04786
04787 v->renderer()->config()->setFont( _f );
04788 }
04789
else if ( var ==
"scheme" )
04790 {
04791 v->renderer()->config()->setSchema( KateFactory::self()->schemaManager()->
number( val ) );
04792 }
04793 }
04794 }
04795
04796
bool KateDocument::checkBoolValue( QString val,
bool *result )
04797 {
04798 val = val.
stripWhiteSpace().lower();
04799
QStringList l;
04800 l <<
"1" <<
"on" <<
"true";
04801
if ( l.contains( val ) )
04802 {
04803 *result =
true;
04804
return true;
04805 }
04806 l.clear();
04807 l <<
"0" <<
"off" <<
"false";
04808
if ( l.contains( val ) )
04809 {
04810 *result =
false;
04811
return true;
04812 }
04813
return false;
04814 }
04815
04816
bool KateDocument::checkIntValue( QString val,
int *result )
04817 {
04818
bool ret(
false );
04819 *result = val.
toInt( &ret );
04820
return ret;
04821 }
04822
04823
bool KateDocument::checkColorValue( QString val,
QColor &c )
04824 {
04825 c.
setNamedColor( val );
04826
return c.
isValid();
04827 }
04828
04829
04830
04831
void KateDocument::slotModOnHdDirty (
const QString &path)
04832 {
04833
if ((path == m_dirWatchFile) && (!m_modOnHd || m_modOnHdReason != 1))
04834 {
04835
04836
if ( ! m_digest.isEmpty() )
04837 {
04838
QCString tmp;
04839
if ( createDigest( tmp ) && tmp == m_digest )
04840
return;
04841 }
04842 m_modOnHd =
true;
04843 m_modOnHdReason = 1;
04844 emit modifiedOnDisc (
this, m_modOnHd, m_modOnHdReason);
04845 }
04846 }
04847
04848
void KateDocument::slotModOnHdCreated (
const QString &path)
04849 {
04850
if ((path == m_dirWatchFile) && (!m_modOnHd || m_modOnHdReason != 2))
04851 {
04852 m_modOnHd =
true;
04853 m_modOnHdReason = 2;
04854 emit modifiedOnDisc (
this, m_modOnHd, m_modOnHdReason);
04855 }
04856 }
04857
04858
void KateDocument::slotModOnHdDeleted (
const QString &path)
04859 {
04860
if ((path == m_dirWatchFile) && (!m_modOnHd || m_modOnHdReason != 3))
04861 {
04862 m_modOnHd =
true;
04863 m_modOnHdReason = 3;
04864 emit modifiedOnDisc (
this, m_modOnHd, m_modOnHdReason);
04865 }
04866 }
04867
04868
bool KateDocument::createDigest(
QCString &result )
04869 {
04870
bool ret =
false;
04871 result =
"";
04872
if ( url().isLocalFile() )
04873 {
04874
QFile f ( url().path() );
04875
if ( f.
open( IO_ReadOnly) )
04876 {
04877
KMD5 md5;
04878 ret = md5.
update( f );
04879 md5.
hexDigest( result );
04880 f.
close();
04881 }
04882 }
04883
return ret;
04884 }
04885
04886
bool KateDocument::wrapCursor ()
04887 {
04888
return !blockSelect && (configFlags() & KateDocument::cfWrapCursor);
04889 }
04890
04891
void KateDocument::updateFileType (
int newType,
bool user)
04892 {
04893
if (user || !m_fileTypeSetByUser)
04894 {
04895
const KateFileType *t = 0;
04896
if ((newType == -1) || (t = KateFactory::self()->fileTypeManager()->fileType (newType)))
04897 {
04898 m_fileType = newType;
04899
04900
if (t)
04901 {
04902 m_config->configStart();
04903
04904 KateView *v;
04905
for (v = m_views.first(); v != 0L; v= m_views.next() )
04906 {
04907 v->config()->configStart();
04908 v->renderer()->config()->configStart();
04909 }
04910
04911 readVariableLine( t->varLine );
04912
04913 m_config->configEnd();
04914
for (v = m_views.first(); v != 0L; v= m_views.next() )
04915 {
04916 v->config()->configEnd();
04917 v->renderer()->config()->configEnd();
04918 }
04919 }
04920 }
04921 }
04922 }
04923
04924 uint KateDocument::documentNumber ()
const
04925
{
04926
return KTextEditor::Document::documentNumber ();
04927 }
04928
04929
04930
04931
04932
void KateDocument::slotQueryClose_save(
bool *handled,
bool* abortClosing) {
04933 *handled=
true;
04934 *abortClosing=
true;
04935
if (m_url.isEmpty())
04936 {
04937 KEncodingFileDialog::Result res=
KEncodingFileDialog::getSaveURLAndEncoding(config()->encoding(),
04938 QString::null,QString::null,0,i18n(
"Save File"));
04939
04940
if( res.URLs.isEmpty() || !checkOverwrite( res.URLs.first() ) ) {
04941 *abortClosing=
true;
04942
return;
04943 }
04944 setEncoding( res.encoding );
04945
saveAs( res.URLs.first() );
04946 *abortClosing=
false;
04947 }
04948
else
04949 {
04950
save();
04951 *abortClosing=
false;
04952 }
04953
04954 }
04955
04956
04957
bool KateDocument::checkOverwrite(
KURL u )
04958 {
04959
if( !u.
isLocalFile() )
04960
return true;
04961
04962
QFileInfo info( u.
path() );
04963
if( !info.
exists() )
04964
return true;
04965
04966
return KMessageBox::Cancel !=
KMessageBox::warningContinueCancel( 0,
04967 i18n(
"A file named \"%1\" already exists. "
04968
"Are you sure you want to overwrite it?" ).arg( info.
fileName() ),
04969 i18n(
"Overwrite File?" ),
04970 i18n(
"&Overwrite" ) );
04971 }
04972
04973
void KateDocument::setDefaultEncoding (
const QString &encoding)
04974 {
04975 s_defaultEncoding = encoding;
04976 }
04977
04978
void KateDocument::setIMSelectionValue( uint imStartLine, uint imStart, uint imEnd,
04979 uint imSelStart, uint imSelEnd,
bool imComposeEvent )
04980 {
04981 m_imStartLine = imStartLine;
04982 m_imStart = imStart;
04983 m_imEnd = imEnd;
04984 m_imSelStart = imSelStart;
04985 m_imSelEnd = imSelEnd;
04986 m_imComposeEvent = imComposeEvent;
04987 }
04988
04989
void KateDocument::getIMSelectionValue( uint *imStartLine, uint *imStart, uint *imEnd,
04990 uint *imSelStart, uint *imSelEnd )
04991 {
04992 *imStartLine = m_imStartLine;
04993 *imStart = m_imStart;
04994 *imEnd = m_imEnd;
04995 *imSelStart = m_imSelStart;
04996 *imSelEnd = m_imSelEnd;
04997 }
04998
04999