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
02274 m_job->addMetaData (
"textmode",
"true" );
02275
02276
QWidget *w = widget ();
02277
if (!w && !m_views.isEmpty ())
02278 w = m_views.first();
02279
02280
if (w)
02281 m_job->setWindow (w->topLevelWidget());
02282
02283 emit started( m_job );
02284
02285 connect( m_job, SIGNAL( data(
KIO::Job*,
const QByteArray& ) ),
02286 SLOT( slotDataKate(
KIO::Job*,
const QByteArray& ) ) );
02287
02288 connect( m_job, SIGNAL( result(
KIO::Job* ) ),
02289 SLOT( slotFinishedKate(
KIO::Job* ) ) );
02290
02291
return true;
02292 }
02293 }
02294
02295
void KateDocument::slotDataKate (
KIO::Job *,
const QByteArray &data )
02296 {
02297
kdDebug(13020) <<
"KateDocument::slotData" <<
endl;
02298
02299
if (!m_tempFile || !m_tempFile->file())
02300
return;
02301
02302 m_tempFile->file()->writeBlock (data);
02303 }
02304
02305
void KateDocument::slotFinishedKate (
KIO::Job * job )
02306 {
02307
kdDebug(13020) <<
"KateDocument::slotJobFinished" <<
endl;
02308
02309
if (!m_tempFile)
02310
return;
02311
02312
delete m_tempFile;
02313 m_tempFile = 0;
02314 m_job = 0;
02315
02316
if (job->
error())
02317 emit canceled( job->
errorString() );
02318
else
02319 {
02320
if ( openFile(job) )
02321 emit setWindowCaption( m_url.prettyURL() );
02322
02323 emit completed();
02324 }
02325 }
02326
02327
void KateDocument::abortLoadKate()
02328 {
02329
if ( m_job )
02330 {
02331
kdDebug(13020) <<
"Aborting job " << m_job <<
endl;
02332 m_job->kill();
02333 m_job = 0;
02334 }
02335
02336
delete m_tempFile;
02337 m_tempFile = 0;
02338 }
02339
02340
bool KateDocument::openFile()
02341 {
02342
return openFile (0);
02343 }
02344
02345
bool KateDocument::openFile(
KIO::Job * job)
02346 {
02347
02348 activateDirWatch ();
02349
02350
02351
02352
02353
if (job)
02354 {
02355 QString metaDataCharset = job->
queryMetaData(
"charset");
02356
02357
if (!metaDataCharset.isEmpty ())
02358 setEncoding (metaDataCharset);
02359 }
02360
02361
02362
02363
02364 QString serviceType = m_extension->urlArgs().serviceType.simplifyWhiteSpace();
02365
int pos = serviceType.find(
';');
02366
if (pos != -1)
02367 setEncoding (serviceType.mid(pos+1));
02368
02369
02370
bool success = buffer->openFile (m_file);
02371
02372
02373
02374
02375
if (success)
02376 {
02377
if (m_highlight && !m_url.isLocalFile()) {
02378
02379 buffer->setHighlight(m_highlight);
02380 }
02381
02382
02383
if (!hlSetByUser)
02384 {
02385
int hl (HlManager::self()->detectHighlighting (
this));
02386
02387
if (hl >= 0)
02388 internalSetHlMode(hl);
02389
02390 }
02391
02392 updateFileType (KateFactory::self()->fileTypeManager()->fileType (
this));
02393
02394
02395 readVariables();
02396
02397
02398 createDigest( m_digest );
02399 }
02400
02401
02402
02403
02404 updateViews();
02405
02406
02407
02408
02409 emit fileNameChanged ();
02410
02411
02412
02413
02414 setDocName (QString::null);
02415
02416
02417
02418
02419
if (m_modOnHd)
02420 {
02421 m_modOnHd =
false;
02422 m_modOnHdReason = 0;
02423 emit modifiedOnDisc (
this, m_modOnHd, 0);
02424 }
02425
02426
02427
02428
02429
if (s_openErrorDialogsActivated)
02430 {
02431
if (!success && buffer->loadingBorked())
02432
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()));
02433
else if (!success)
02434
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()));
02435 }
02436
02437
02438
02439
02440
return success;
02441 }
02442
02443
bool KateDocument::save()
02444 {
02445
02446
bool l ( url().isLocalFile() );
02447
if ( ( ( l && config()->backupFlags() & KateDocumentConfig::LocalFiles ) ||
02448 ( ! l && config()->backupFlags() & KateDocumentConfig::RemoteFiles ) )
02449 && isModified() ) {
02450
KURL u( url().path() + config()->backupSuffix() );
02451
if ( !
KIO::NetAccess::upload( url().path(), u, kapp->mainWidget() ) )
02452
kdDebug(13020)<<
"backing up failed ("<<url().prettyURL()<<
" -> "<<u.
prettyURL()<<
")"<<
endl;
02453 }
02454
02455
return KParts::ReadWritePart::save();
02456 }
02457
02458
bool KateDocument::saveFile()
02459 {
02460
02461
02462
02463
bool reallySaveIt = !buffer->loadingBorked() || (
KMessageBox::warningYesNo(widget(),
02464 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);
02465
02466
if ( !url().isEmpty() )
02467 {
02468
if (s_fileChangedDialogsActivated && m_modOnHd)
02469 {
02470 QString str;
02471
02472
if (m_modOnHdReason == 1)
02473 str = i18n(
"The file %1 was changed (modified) on disc by another program!\n\n").arg(url().fileName());
02474
else if (m_modOnHdReason == 2)
02475 str = i18n(
"The file %1 was changed (created) on disc by another program!\n\n").arg(url().fileName());
02476
else if (m_modOnHdReason == 3)
02477 str = i18n(
"The file %1 was changed (deleted) on disc by another program!\n\n").arg(url().fileName());
02478
02479
if (!isModified())
02480 {
02481
if (!(
KMessageBox::warningYesNo(0,
02482 str + i18n(
"Do you really want to save this unmodified file? You could overwrite changed data in the file on disk.")) == KMessageBox::Yes))
02483 reallySaveIt =
false;
02484 }
02485
else
02486 {
02487
if (!(
KMessageBox::warningYesNo(0,
02488 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))
02489 reallySaveIt =
false;
02490 }
02491 }
02492 }
02493
02494
02495
02496
02497
bool canEncode =
true;
02498
02499
if (reallySaveIt)
02500 canEncode = buffer->canEncode ();
02501
02502
02503
02504
02505
bool success =
false;
02506
02507
02508 deactivateDirWatch ();
02509
02510
02511
02512
02513
if (reallySaveIt && canEncode)
02514 success = buffer->saveFile (m_file);
02515
02516
02517 createDigest( m_digest );
02518
02519
02520 activateDirWatch ();
02521
02522
02523
02524
02525
if (success)
02526 {
02527
02528
if (!hlSetByUser)
02529 {
02530
int hl (HlManager::self()->detectHighlighting (
this));
02531
02532
if (hl >= 0)
02533 internalSetHlMode(hl);
02534 }
02535
02536
02537 updateFileType (KateFactory::self()->fileTypeManager()->fileType (
this));
02538
02539
02540 readVariables();
02541 }
02542
02543
02544
02545
02546 emit fileNameChanged ();
02547
02548
02549
02550
02551 setDocName (QString::null);
02552
02553
02554
02555
02556
if (success && m_modOnHd)
02557 {
02558 m_modOnHd =
false;
02559 m_modOnHdReason = 0;
02560 emit modifiedOnDisc (
this, m_modOnHd, 0);
02561 }
02562
02563
02564
02565
02566
if (reallySaveIt && !canEncode)
02567
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."));
02568
else if (reallySaveIt && !success)
02569
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()));
02570
02571
02572
02573
02574
return success;
02575 }
02576
02577
void KateDocument::activateDirWatch ()
02578 {
02579
02580
if (m_file == m_dirWatchFile)
02581
return;
02582
02583
02584 deactivateDirWatch ();
02585
02586
02587
if (m_url.isLocalFile() && !m_file.isEmpty())
02588 {
02589 KateFactory::self()->dirWatch ()->addFile (m_file);
02590 m_dirWatchFile = m_file;
02591 }
02592 }
02593
02594
void KateDocument::deactivateDirWatch ()
02595 {
02596
if (!m_dirWatchFile.isEmpty())
02597 KateFactory::self()->dirWatch ()->removeFile (m_dirWatchFile);
02598
02599 m_dirWatchFile = QString::null;
02600 }
02601
02602
bool KateDocument::closeURL()
02603 {
02604 abortLoadKate();
02605
02606
02607
02608
02609
if ( !m_reloading && !url().isEmpty() )
02610 {
02611
if (s_fileChangedDialogsActivated && m_modOnHd)
02612 {
02613 QString str;
02614
02615
if (m_modOnHdReason == 1)
02616 str = i18n(
"The file %1 was changed (modified) on disc by another program!\n\n").arg(url().fileName());
02617
else if (m_modOnHdReason == 2)
02618 str = i18n(
"The file %1 was changed (created) on disc by another program!\n\n").arg(url().fileName());
02619
else if (m_modOnHdReason == 3)
02620 str = i18n(
"The file %1 was changed (deleted) on disc by another program!\n\n").arg(url().fileName());
02621
02622
if (!(
KMessageBox::warningYesNo(0,
02623 str + i18n(
"Do you really want to continue to close this file? Data loss may occur.")) == KMessageBox::Yes))
02624
return false;
02625 }
02626 }
02627
02628
02629
02630
02631
if (!
KParts::ReadWritePart::closeURL ())
02632
return false;
02633
02634
02635 deactivateDirWatch ();
02636
02637
02638
02639
02640 m_url =
KURL ();
02641 m_file = QString::null;
02642
02643
02644
if (m_modOnHd)
02645 {
02646 m_modOnHd =
false;
02647 m_modOnHdReason = 0;
02648 emit modifiedOnDisc (
this, m_modOnHd, 0);
02649 }
02650
02651
02652 buffer->clear();
02653
02654
02655 clearMarks ();
02656
02657
02658 clearUndo();
02659 clearRedo();
02660
02661
02662 setModified(
false);
02663
02664
02665 internalSetHlMode(0);
02666
02667
02668
for (KateView * view = m_views.first(); view != 0L; view = m_views.next() )
02669 {
02670
02671
02672 view->setCursorPositionInternal(0, 0, 1,
false);
02673 view->updateView(
true);
02674 }
02675
02676
02677 emit fileNameChanged ();
02678
02679
02680 setDocName (QString::null);
02681
02682
02683
return true;
02684 }
02685
02686
void KateDocument::setReadWrite(
bool rw )
02687 {
02688
if (isReadWrite() != rw)
02689 {
02690
KParts::ReadWritePart::setReadWrite (rw);
02691
02692
for( KateView* view = m_views.first(); view != 0L; view = m_views.next() )
02693 {
02694 view->slotUpdate();
02695 view->slotReadWriteChanged ();
02696 }
02697 }
02698 }
02699
02700
void KateDocument::setModified(
bool m) {
02701
02702
if (isModified() != m) {
02703
KParts::ReadWritePart::setModified (m);
02704
02705
for( KateView* view = m_views.first(); view != 0L; view = m_views.next() )
02706 {
02707 view->slotUpdate();
02708 }
02709
02710 emit modifiedChanged ();
02711 emit modStateChanged ((
Kate::Document *)
this);
02712 }
02713
if ( m ==
false && ! undoItems.isEmpty() )
02714 {
02715 lastUndoGroupWhenSaved = undoItems.last();
02716 }
02717
02718
if ( m ==
false ) docWasSavedWhenUndoWasEmpty = undoItems.isEmpty();
02719 }
02720
02721
02722
02723
02724
void KateDocument::makeAttribs()
02725 {
02726 m_highlight->clearAttributeArrays ();
02727
02728
for (uint z = 0; z < m_views.count(); z++)
02729 m_views.at(z)->renderer()->updateAttributes ();
02730
02731 buffer->invalidateHighlighting();
02732
02733 tagAll ();
02734 }
02735
02736
02737
void KateDocument::internalHlChanged()
02738 {
02739 makeAttribs();
02740 }
02741
02742
void KateDocument::addView(KTextEditor::View *view) {
02743
if (!view)
02744
return;
02745
02746 m_views.append( (KateView *) view );
02747 m_textEditViews.append( view );
02748
02749
02750
const KateFileType *t = 0;
02751
if ((m_fileType > -1) && (t = KateFactory::self()->fileTypeManager()->fileType(m_fileType)))
02752 readVariableLine (t->varLine,
true);
02753
02754
02755 readVariables (
true);
02756
02757 m_activeView = (KateView *) view;
02758 }
02759
02760
void KateDocument::removeView(KTextEditor::View *view) {
02761
if (!view)
02762
return;
02763
02764
if (m_activeView == view)
02765 m_activeView = 0L;
02766
02767 m_views.removeRef( (KateView *) view );
02768 m_textEditViews.removeRef( view );
02769 }
02770
02771
void KateDocument::addSuperCursor(
KateSuperCursor *cursor,
bool privateC) {
02772
if (!cursor)
02773
return;
02774
02775 m_superCursors.append( cursor );
02776
02777
if (!privateC)
02778 myCursors.append( cursor );
02779 }
02780
02781
void KateDocument::removeSuperCursor(
KateSuperCursor *cursor,
bool privateC) {
02782
if (!cursor)
02783
return;
02784
02785
if (!privateC)
02786 myCursors.removeRef( cursor );
02787
02788 m_superCursors.removeRef( cursor );
02789 }
02790
02791
bool KateDocument::ownedView(KateView *view) {
02792
02793
return (m_views.containsRef(view) > 0);
02794 }
02795
02796
bool KateDocument::isLastView(
int numViews) {
02797
return ((
int) m_views.count() == numViews);
02798 }
02799
02800 uint KateDocument::currentColumn(
const KateTextCursor& cursor )
02801 {
02802 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
02803
02804
if (textLine)
02805
return textLine->cursorX(cursor.
col(), config()->tabWidth());
02806
else
02807
return 0;
02808 }
02809
02810
bool KateDocument::typeChars ( KateView *view,
const QString &chars )
02811 {
02812 TextLine::Ptr textLine = buffer->plainLine(view->cursorLine ());
02813
02814
if (!textLine)
02815
return false;
02816
02817
int oldLine = view->cursorLine ();
02818
int oldCol = view->cursorColumnReal ();
02819
02820
bool bracketInserted =
false;
02821 QString buf;
02822
QChar c;
02823
for( uint z = 0; z < chars.length(); z++ )
02824 {
02825
QChar ch = c = chars[z];
02826
02827
if (ch.isPrint() || ch ==
'\t')
02828 {
02829 buf.append (ch);
02830
02831
if (!bracketInserted && (config()->configFlags() & KateDocument::cfAutoBrackets))
02832 {
02833
if (ch ==
'(') { bracketInserted =
true; buf.append (
')'); }
02834
if (ch ==
'[') { bracketInserted =
true; buf.append (
']'); }
02835
if (ch ==
'{') { bracketInserted =
true; buf.append (
'}'); }
02836 }
02837 }
02838 }
02839
02840
if (buf.isEmpty())
02841
return false;
02842
02843 editStart ();
02844
02845
if (!(config()->configFlags() & KateDocument::cfPersistent) && hasSelection() )
02846 removeSelectedText();
02847
02848
if (config()->configFlags() & KateDocument::cfOvr)
02849 removeText (view->cursorLine(), view->cursorColumnReal(), view->cursorLine(), QMIN( view->cursorColumnReal()+buf.length(), textLine->length() ) );
02850
02851 insertText (view->cursorLine(), view->cursorColumnReal(), buf);
02852 m_indenter->processChar(c);
02853
02854 editEnd ();
02855
02856
if (bracketInserted)
02857 view->setCursorPositionInternal (view->cursorLine(), view->cursorColumnReal()-1);
02858
02859 emit charactersInteractivelyInserted (oldLine, oldCol, chars);
02860
02861
return true;
02862 }
02863
02864
void KateDocument::newLine(
KateTextCursor& c, KateViewInternal *v )
02865 {
02866 editStart();
02867
02868
if( !(config()->configFlags() & cfPersistent) && hasSelection() )
02869 removeSelectedText();
02870
02871
02872 c = v->getCursor ();
02873
02874
if (c.
line() > (
int)lastLine())
02875 c.
setLine(lastLine());
02876
02877 TextLine::Ptr textLine = kateTextLine(c.
line());
02878
if (c.
col() > (
int)textLine->length())
02879 c.
setCol(textLine->length());
02880
02881
if (!(config()->configFlags() & KateDocument::cfAutoIndent))
02882 {
02883 insertText( c.
line(), c.
col(),
"\n" );
02884 c.
setPos(c.
line() + 1, 0);
02885 }
02886
else
02887 {
02888
int pos = textLine->firstChar();
02889
if (c.
col() < pos)
02890 c.
setCol(pos);
02891
02892 insertText (c.
line(), c.
col(),
"\n");
02893
02894
KateDocCursor cursor (c.
line() + 1, pos,
this);
02895 m_indenter->processNewline(cursor,
true);
02896 c.
setPos(cursor);
02897 }
02898
02899 editEnd();
02900 }
02901
02902
void KateDocument::transpose(
const KateTextCursor& cursor)
02903 {
02904 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
02905
02906
if (!textLine || (textLine->length() < 2))
02907
return;
02908
02909 uint col = cursor.
col();
02910
02911
if (col > 0)
02912 col--;
02913
02914
if ((textLine->length() - col) < 2)
02915
return;
02916
02917 uint line = cursor.
line();
02918 QString s;
02919
02920
02921
02922 s.append (textLine->getChar(col+1));
02923 s.append (textLine->getChar(col));
02924
02925
02926
02927 editStart ();
02928 editRemoveText (line, col, 2);
02929 editInsertText (line, col, s);
02930 editEnd ();
02931 }
02932
02933
void KateDocument::backspace(
const KateTextCursor& c )
02934 {
02935
if( !(config()->configFlags() & cfPersistent) && hasSelection() ) {
02936 removeSelectedText();
02937
return;
02938 }
02939
02940 uint col = QMAX( c.
col(), 0 );
02941 uint line = QMAX( c.
line(), 0 );
02942
02943
if ((col == 0) && (line == 0))
02944
return;
02945
02946
if (col > 0)
02947 {
02948
if (!(config()->configFlags() & KateDocument::cfBackspaceIndents))
02949 {
02950
02951
02952 removeText(line, col-1, line, col);
02953 }
02954
else
02955 {
02956
02957
02958 TextLine::Ptr textLine = buffer->plainLine(line);
02959
int colX = textLine->cursorX(col, config()->tabWidth());
02960
int pos = textLine->firstChar();
02961
if (pos > 0)
02962 pos = textLine->cursorX(pos, config()->tabWidth());
02963
02964
if (pos < 0 || pos >= (
int)colX)
02965 {
02966
02967
02968
int y = line;
02969
while (--y >= 0)
02970 {
02971 textLine = buffer->plainLine(y);
02972 pos = textLine->firstChar();
02973
02974
if (pos >= 0)
02975 {
02976 pos = textLine->cursorX(pos, config()->tabWidth());
02977
if (pos < (
int)colX)
02978 {
02979 replaceWithOptimizedSpace(line, col, pos, config()->configFlags());
02980
break;
02981 }
02982 }
02983 }
02984
if (y < 0) {
02985
02986 removeText(line, 0, line, col);
02987 }
02988 }
02989
else
02990 removeText(line, col-1, line, col);
02991 }
02992 }
02993
else
02994 {
02995
02996
if (line >= 1)
02997 {
02998 TextLine::Ptr textLine = buffer->plainLine(line-1);
02999
if (config()->wordWrap() && textLine->endingWith(QString::fromLatin1(
" ")))
03000 {
03001
03002 removeText (line-1, textLine->length()-1, line, 0);
03003 }
03004
else
03005 removeText (line-1, textLine->length(), line, 0);
03006 }
03007 }
03008
03009 emit backspacePressed();
03010 }
03011
03012
void KateDocument::del(
const KateTextCursor& c )
03013 {
03014
if ( !(config()->configFlags() & cfPersistent) && hasSelection() ) {
03015 removeSelectedText();
03016
return;
03017 }
03018
03019
if( c.
col() < (
int) buffer->plainLine(c.
line())->length())
03020 {
03021 removeText(c.
line(), c.
col(), c.
line(), c.
col()+1);
03022 }
03023
else
03024 {
03025 removeText(c.
line(), c.
col(), c.
line()+1, 0);
03026 }
03027 }
03028
03029
void KateDocument::cut()
03030 {
03031
if (!hasSelection())
03032
return;
03033
03034
copy();
03035 removeSelectedText();
03036 }
03037
03038
void KateDocument::copy()
03039 {
03040
if (!hasSelection())
03041
return;
03042
03043 QApplication::clipboard()->setText(selection ());
03044 }
03045
03046
void KateDocument::paste ( KateView* view )
03047 {
03048 QString s = QApplication::clipboard()->text();
03049
03050
if (s.isEmpty())
03051
return;
03052
03053 m_undoDontMerge =
true;
03054
03055 editStart ();
03056
03057
if (!(config()->configFlags() & KateDocument::cfPersistent) && hasSelection() )
03058 removeSelectedText();
03059
03060 uint line = view->cursorLine ();
03061 uint column = view->cursorColumnReal ();
03062
03063 insertText ( line, column, s, blockSelect );
03064
03065 editEnd();
03066
03067
03068
03069
03070
if (blockSelect)
03071 {
03072 uint lines = s.contains (
QChar (
'\n'));
03073 view->setCursorPositionInternal (line+lines, column);
03074 }
03075
03076 m_undoDontMerge =
true;
03077 }
03078
03079
void KateDocument::selectWord(
const KateTextCursor& cursor )
03080 {
03081
int start,
end, len;
03082
03083 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
03084 len = textLine->length();
03085 start =
end = cursor.
col();
03086
while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
03087
while (
end < len && m_highlight->isInWord(textLine->getChar(end)))
end++;
03088
if (
end <= start)
return;
03089
03090
if (!(config()->configFlags() & KateDocument::cfKeepSelection))
03091 clearSelection ();
03092
03093 setSelection (cursor.
line(), start, cursor.
line(),
end);
03094 }
03095
03096
void KateDocument::selectLine(
const KateTextCursor& cursor )
03097 {
03098
if (!(config()->configFlags() & KateDocument::cfKeepSelection))
03099 clearSelection ();
03100
03101 setSelection (cursor.
line(), 0, cursor.
line(), buffer->plainLine(cursor.
line())->length() );
03102 }
03103
03104
void KateDocument::selectLength(
const KateTextCursor& cursor,
int length )
03105 {
03106
int start,
end;
03107
03108 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
03109 start = cursor.
col();
03110
end = start + length;
03111
if (
end <= start)
return;
03112
03113
if (!(config()->configFlags() & KateDocument::cfKeepSelection))
03114 clearSelection ();
03115 setSelection (cursor.
line(), start, cursor.
line(),
end);
03116 }
03117
03118
void KateDocument::insertIndentChars ( KateView *view )
03119 {
03120 editStart ();
03121
03122 QString s;
03123
if (config()->configFlags() & KateDocument::cfSpaceIndent)
03124 s.fill (
' ', config()->indentationWidth());
03125
else
03126 s.append (
'\t');
03127
03128 insertText (view->cursorLine(), view->cursorColumnReal(), s);
03129
03130 editEnd ();
03131 }
03132
03133
void KateDocument::indent ( KateView *, uint line,
int change)
03134 {
03135 editStart ();
03136
03137
if (!hasSelection())
03138 {
03139
03140 optimizeLeadingSpace(line, config()->configFlags(), change);
03141 }
03142
else
03143 {
03144
int sl = selectStart.line();
03145
int el = selectEnd.line();
03146
int ec = selectEnd.col();
03147
03148
if ((ec == 0) && ((el-1) >= 0))
03149 {
03150
03151
03152 el--;
03153 }
03154
03155
if (config()->configFlags() & KateDocument::cfKeepIndentProfile && change < 0) {
03156
03157
03158
int adjustedChange = -change;
03159
03160
for (line = sl; (
int) line <= el && adjustedChange > 0; line++) {
03161 TextLine::Ptr textLine = buffer->plainLine(line);
03162
int firstChar = textLine->firstChar();
03163
if (firstChar >= 0 && (lineSelected(line) || lineHasSelected(line))) {
03164
int maxUnindent = textLine->cursorX(firstChar, config()->tabWidth()) / config()->indentationWidth();
03165
if (maxUnindent < adjustedChange)
03166 adjustedChange = maxUnindent;
03167 }
03168 }
03169
03170 change = -adjustedChange;
03171 }
03172
03173
for (line = sl; (
int) line <= el; line++) {
03174
if (lineSelected(line) || lineHasSelected(line)) {
03175 optimizeLeadingSpace(line, config()->configFlags(), change);
03176 }
03177 }
03178 }
03179
03180 editEnd ();
03181 }
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
void KateDocument::optimizeLeadingSpace(uint line,
int flags,
int change)
03193 {
03194 TextLine::Ptr textline = buffer->plainLine(line);
03195
03196
int first_char = textline->firstChar();
03197
03198
int w = 0;
03199
if (flags & KateDocument::cfSpaceIndent)
03200 w = config()->indentationWidth();
03201
else
03202 w = config()->tabWidth();
03203
03204
if (first_char < 0)
03205 first_char = textline->length();
03206
03207
int space = textline->cursorX(first_char, config()->tabWidth()) + change * w;
03208
if (space < 0)
03209 space = 0;
03210
03211
if (!(flags & KateDocument::cfKeepExtraSpaces))
03212 {
03213 uint extra = space % w;
03214
03215 space -= extra;
03216
if (extra && change < 0) {
03217
03218 space += w;
03219 }
03220 }
03221
03222
03223 replaceWithOptimizedSpace(line, first_char, space, flags);
03224 }
03225
03226
void KateDocument::replaceWithOptimizedSpace(uint line, uint upto_column, uint space,
int flags)
03227 {
03228 uint length;
03229 QString new_space;
03230
03231
if (flags & KateDocument::cfSpaceIndent) {
03232 length = space;
03233 new_space.fill(
' ', length);
03234 }
03235
else {
03236 length = space / config()->tabWidth();
03237 new_space.fill(
'\t', length);
03238
03239 QString extra_space;
03240 extra_space.fill(
' ', space % config()->tabWidth());
03241 length += space % config()->tabWidth();
03242 new_space += extra_space;
03243 }
03244
03245 TextLine::Ptr textline = buffer->plainLine(line);
03246 uint change_from;
03247
for (change_from = 0; change_from < upto_column && change_from < length; change_from++) {
03248
if (textline->getChar(change_from) != new_space[change_from])
03249
break;
03250 }
03251
03252 editStart();
03253
03254
if (change_from < upto_column)
03255 removeText(line, change_from, line, upto_column);
03256
03257
if (change_from < length)
03258 insertText(line, change_from, new_space.right(length - change_from));
03259
03260 editEnd();
03261 }
03262
03263
03264
03265
03266
03267
bool KateDocument::removeStringFromBegining(
int line, QString &str)
03268 {
03269 TextLine::Ptr textline = buffer->plainLine(line);
03270
03271
int index = 0;
03272
bool there =
false;
03273
03274
if (textline->startingWith(str))
03275 there =
true;
03276
else
03277 {
03278 index = textline->firstChar ();
03279
03280
if ((index >= 0) && (textline->length() >= (index + str.length())) && (textline->string(index, str.length()) == str))
03281 there =
true;
03282 }
03283
03284
if (there)
03285 {
03286
03287 removeText (line, index, line, index+str.length());
03288 }
03289
03290
return there;
03291 }
03292
03293
03294
03295
03296
03297
bool KateDocument::removeStringFromEnd(
int line, QString &str)
03298 {
03299 TextLine::Ptr textline = buffer->plainLine(line);
03300
03301
int index = 0;
03302
bool there =
false;
03303
03304
if(textline->endingWith(str))
03305 {
03306 index = textline->length() - str.length();
03307 there =
true;
03308 }
03309
else
03310 {
03311 index = textline->lastChar ()-str.length()+1;
03312
03313
if ((index >= 0) && (textline->length() >= (index + str.length())) && (textline->string(index, str.length()) == str))
03314 there =
true;
03315 }
03316
03317
if (there)
03318 {
03319
03320 removeText (line, index, line, index+str.length());
03321 }
03322
03323
return there;
03324 }
03325
03326
03327
03328
03329
03330
void KateDocument::addStartLineCommentToSingleLine(
int line)
03331 {
03332 QString commentLineMark = m_highlight->getCommentSingleLineStart() +
" ";
03333 insertText (line, 0, commentLineMark);
03334 }
03335
03336
03337
03338
03339
03340
bool KateDocument::removeStartLineCommentFromSingleLine(
int line)
03341 {
03342 QString shortCommentMark = m_highlight->getCommentSingleLineStart();
03343 QString longCommentMark = shortCommentMark +
" ";
03344
03345 editStart();
03346
03347
03348
bool removed = (removeStringFromBegining(line, longCommentMark)
03349 || removeStringFromBegining(line, shortCommentMark));
03350
03351 editEnd();
03352
03353
return removed;
03354 }
03355
03356
03357
03358
03359
03360
void KateDocument::addStartStopCommentToSingleLine(
int line)
03361 {
03362 QString startCommentMark = m_highlight->getCommentStart() +
" ";
03363 QString stopCommentMark =
" " + m_highlight->getCommentEnd();
03364
03365 editStart();
03366
03367
03368 insertText (line, 0, startCommentMark);
03369
03370
03371
int col = buffer->plainLine(line)->length();
03372
03373
03374 insertText (line, col, stopCommentMark);
03375
03376 editEnd();
03377 }
03378
03379
03380
03381
03382
03383
bool KateDocument::removeStartStopCommentFromSingleLine(
int line)
03384 {
03385 QString shortStartCommentMark = m_highlight->getCommentStart();
03386 QString longStartCommentMark = shortStartCommentMark +
" ";
03387 QString shortStopCommentMark = m_highlight->getCommentEnd();
03388 QString longStopCommentMark =
" " + shortStopCommentMark;
03389
03390 editStart();
03391
03392
03393
bool removedStart = (removeStringFromBegining(line, longStartCommentMark)
03394 || removeStringFromBegining(line, shortStartCommentMark));
03395
03396
bool removedStop =
false;
03397
if (removedStart)
03398 {
03399
03400 removedStop = (removeStringFromEnd(line, longStopCommentMark)
03401 || removeStringFromEnd(line, shortStopCommentMark));
03402 }
03403
03404 editEnd();
03405
03406
return (removedStart || removedStop);
03407 }
03408
03409
03410
03411
03412
03413
03414
void KateDocument::addStartStopCommentToSelection()
03415 {
03416 QString startComment = m_highlight->getCommentStart();
03417 QString endComment = m_highlight->getCommentEnd();
03418
03419
int sl = selectStart.line();
03420
int el = selectEnd.line();
03421
int sc = selectStart.col();
03422
int ec = selectEnd.col();
03423
03424
if ((ec == 0) && ((el-1) >= 0))
03425 {
03426 el--;
03427 ec = buffer->plainLine (el)->length();
03428 }
03429
03430 editStart();
03431
03432 insertText (el, ec, endComment);
03433 insertText (sl, sc, startComment);
03434
03435 editEnd ();
03436
03437
03438 ec += endComment.length() + ( (el == sl) ? startComment.length() : 0 );
03439 setSelection(sl, sc, el, ec);
03440 }
03441
03442
03443
03444
03445
03446
void KateDocument::addStartLineCommentToSelection()
03447 {
03448 QString commentLineMark = m_highlight->getCommentSingleLineStart() +
" ";
03449
03450
int sl = selectStart.line();
03451
int el = selectEnd.line();
03452
03453
if ((selectEnd.col() == 0) && ((el-1) >= 0))
03454 {
03455 el--;
03456 }
03457
03458 editStart();
03459
03460
03461
for (
int z = el; z >= sl; z--) {
03462 insertText (z, 0, commentLineMark);
03463 }
03464
03465 editEnd ();
03466
03467
03468 selectEnd.setCol(selectEnd.col() + ((el == selectEnd.line()) ? commentLineMark.length() : 0) );
03469 setSelection(selectStart.line(), 0, selectEnd.line(), selectEnd.col());
03470 }
03471
03472
bool KateDocument::nextNonSpaceCharPos(
int &line,
int &col)
03473 {
03474
for(; line < (
int)buffer->count(); line++) {
03475 col = buffer->plainLine(line)->nextNonSpaceChar(col);
03476
if(col != -1)
03477
return true;
03478 col = 0;
03479 }
03480
03481 line = -1;
03482 col = -1;
03483
return false;
03484 }
03485
03486
bool KateDocument::previousNonSpaceCharPos(
int &line,
int &col)
03487 {
03488
while(
true)
03489 {
03490 col = buffer->plainLine(line)->previousNonSpaceChar(col);
03491
if(col != -1)
return true;
03492
if(line == 0)
return false;
03493 --line;
03494 col = buffer->plainLine(line)->length();
03495 }
03496
03497 line = -1;
03498 col = -1;
03499
return false;
03500 }
03501
03502
03503
03504
03505
03506
bool KateDocument::removeStartStopCommentFromSelection()
03507 {
03508 QString startComment = m_highlight->getCommentStart();
03509 QString endComment = m_highlight->getCommentEnd();
03510
03511
int sl = selectStart.line();
03512
int el = selectEnd.line();
03513
int sc = selectStart.col();
03514
int ec = selectEnd.col();
03515
03516
03517
if (ec != 0) {
03518 ec--;
03519 }
else {
03520
if (el > 0) {
03521 el--;
03522 ec = buffer->plainLine(el)->length() - 1;
03523 }
03524 }
03525
03526
int startCommentLen = startComment.length();
03527
int endCommentLen = endComment.length();
03528
03529
03530
03531
bool remove = nextNonSpaceCharPos(sl, sc)
03532 && buffer->plainLine(sl)->stringAtPos(sc, startComment)
03533 && previousNonSpaceCharPos(el, ec)
03534 && ( (ec - endCommentLen + 1) >= 0 )
03535 && buffer->plainLine(el)->stringAtPos(ec - endCommentLen + 1, endComment);
03536
03537
if (remove) {
03538 editStart();
03539
03540 removeText (el, ec - endCommentLen + 1, el, ec + 1);
03541 removeText (sl, sc, sl, sc + startCommentLen);
03542
03543 editEnd ();
03544
03545
03546 ec -= endCommentLen + ( (el == sl) ? startCommentLen : 0 );
03547 setSelection(sl, sc, el, ec + 1);
03548 }
03549
03550
return remove;
03551 }
03552
03553
03554
03555
03556
03557
bool KateDocument::removeStartLineCommentFromSelection()
03558 {
03559 QString shortCommentMark = m_highlight->getCommentSingleLineStart();
03560 QString longCommentMark = shortCommentMark +
" ";
03561
03562
int sl = selectStart.line();
03563
int el = selectEnd.line();
03564
03565
if ((selectEnd.col() == 0) && ((el-1) >= 0))
03566 {
03567 el--;
03568 }
03569
03570
03571
int removeLength = 0;
03572
if (buffer->plainLine(el)->startingWith(longCommentMark))
03573 removeLength = longCommentMark.length();
03574
else if (buffer->plainLine(el)->startingWith(shortCommentMark))
03575 removeLength = shortCommentMark.length();
03576
03577
bool removed =
false;
03578
03579 editStart();
03580
03581
03582
for (
int z = el; z >= sl; z--)
03583 {
03584
03585 removed = (removeStringFromBegining(z, longCommentMark)
03586 || removeStringFromBegining(z, shortCommentMark)
03587 || removed);
03588 }
03589
03590 editEnd();
03591
03592
if(removed) {
03593
03594 selectEnd.setCol(selectEnd.col() - ((el == selectEnd.line()) ? removeLength : 0) );
03595 setSelection(selectStart.line(), selectStart.col(), selectEnd.line(), selectEnd.col());
03596 }
03597
03598
return removed;
03599 }
03600
03601
03602
03603
03604
03605
void KateDocument::comment( KateView *, uint line,
int change)
03606 {
03607
bool hasStartLineCommentMark = !(m_highlight->getCommentSingleLineStart().isEmpty());
03608
bool hasStartStopCommentMark = ( !(m_highlight->getCommentStart().isEmpty())
03609 && !(m_highlight->getCommentEnd().isEmpty()) );
03610
03611
bool removed =
false;
03612
03613
if (change > 0)
03614 {
03615
if ( !hasSelection() )
03616 {
03617
if ( hasStartLineCommentMark )
03618 addStartLineCommentToSingleLine(line);
03619
else if ( hasStartStopCommentMark )
03620 addStartStopCommentToSingleLine(line);
03621 }
03622
else
03623 {
03624
03625
03626
03627
03628
03629
03630
03631
if ( hasStartStopCommentMark &&
03632 ( !hasStartLineCommentMark || (
03633 ( selectStart.col() > buffer->plainLine( selectStart.line() )->firstChar() ) ||
03634 ( selectEnd.col() < ((
int)buffer->plainLine( selectEnd.line() )->length()) )
03635 ) ) )
03636 addStartStopCommentToSelection();
03637
else if ( hasStartLineCommentMark )
03638 addStartLineCommentToSelection();
03639 }
03640 }
03641
else
03642 {
03643
if ( !hasSelection() )
03644 {
03645 removed = ( hasStartLineCommentMark
03646 && removeStartLineCommentFromSingleLine(line) )
03647 || ( hasStartStopCommentMark
03648 && removeStartStopCommentFromSingleLine(line) );
03649 }
03650
else
03651 {
03652
03653 removed = ( hasStartLineCommentMark
03654 && removeStartLineCommentFromSelection() )
03655 || ( hasStartStopCommentMark
03656 && removeStartStopCommentFromSelection() );
03657 }
03658 }
03659 }
03660
03661
void KateDocument::transform( KateView *,
const KateTextCursor &c,
03662 KateDocument::TextTransform t )
03663 {
03664 editStart();
03665
if ( hasSelection() )
03666 {
03667
int ln = selStartLine();
03668
while ( ln <= selEndLine() )
03669 {
03670 uint start,
end;
03671 start = (ln == selStartLine() || blockSelectionMode()) ?
03672 selStartCol() : 0;
03673
end = (ln == selEndLine() || blockSelectionMode()) ?
03674 selEndCol() : lineLength( ln );
03675 QString s = text( ln, start, ln, end );
03676
03677
if ( t == Uppercase )
03678 s = s.upper();
03679
else if ( t == Lowercase )
03680 s = s.lower();
03681
else
03682 {
03683 TextLine::Ptr l = buffer->plainLine( ln );
03684 uint p ( 0 );
03685
while( p < s.length() )
03686 {
03687
03688
03689
03690
03691
if ( ( ! start && ! p ) ||
03692 ( ( ln == selStartLine() || blockSelectionMode() ) &&
03693 ! p && ! m_highlight->isInWord( l->getChar( start - 1 ) ) ) ||
03694 ( p && ! m_highlight->isInWord( s.at( p-1 ) ) )
03695 )
03696 s[p] = s.at(p).upper();
03697 p++;
03698 }
03699 }
03700
03701 removeText( ln, start, ln, end );
03702 insertText( ln, start, s );
03703
03704 ln++;
03705 }
03706 }
else {
03707 QString s;
03708 uint cline(c.
line() ), ccol( c.
col() );
03709
int n ( ccol );
03710
switch ( t ) {
03711
case Uppercase:
03712 s = text( cline, ccol, cline, ccol + 1 ).upper();
03713
break;
03714
case Lowercase:
03715 s = text( cline, ccol, cline, ccol + 1 ).lower();
03716
break;
03717
case Capitalize:
03718 {
03719 TextLine::Ptr l = buffer->plainLine( cline );
03720
while ( n > 0 && m_highlight->isInWord( l->getChar( n-1 ) ) )
03721 n--;
03722 s = text( cline, n, cline, n + 1 ).upper();
03723 }
03724
break;
03725
default:
03726
break;
03727 }
03728 removeText( cline, n, cline, n+1 );
03729 insertText( cline, n, s );
03730 }
03731 editEnd();
03732 }
03733
03734
void KateDocument::joinLines( uint first, uint last )
03735 {
03736
03737 editStart();
03738
int line( first );
03739
while ( first < last )
03740 {
03741
03742
03743
03744
03745
03746 TextLine::Ptr l = buffer->line( line );
03747 TextLine::Ptr tl = buffer->line( line + 1 );
03748
03749
if ( !l || !tl )
03750 {
03751 editEnd();
03752
return;
03753 }
03754
03755
int pos = tl->firstChar();
03756
if ( pos >= 0 )
03757 {
03758
if (pos != 0)
03759 editRemoveText( line + 1, 0, pos );
03760
if ( !( l->length() == 0 || l->getChar( l->length() - 1 ).isSpace() ) )
03761 editInsertText( line + 1, 0,
" " );
03762 }
03763
else
03764 {
03765
03766 editRemoveText( line + 1, 0, tl->length() );
03767 }
03768
03769 editUnWrapLine( line );
03770 first++;
03771 }
03772 editEnd();
03773 }
03774
03775 QString KateDocument::getWord(
const KateTextCursor& cursor ) {
03776
int start,
end, len;
03777
03778 TextLine::Ptr textLine = buffer->plainLine(cursor.
line());
03779 len = textLine->length();
03780 start =
end = cursor.
col();
03781
if (start > len)
03782
return QString(
"");
03783
03784
while (start > 0 && m_highlight->isInWord(textLine->getChar(start - 1))) start--;
03785
while (
end < len && m_highlight->isInWord(textLine->getChar(end)))
end++;
03786 len =
end - start;
03787
return QString(&textLine->text()[start], len);
03788 }
03789
03790
void KateDocument::tagLines(
int start,
int end)
03791 {
03792
for (uint z = 0; z < m_views.count(); z++)
03793 m_views.at(z)->tagLines (start, end,
true);
03794 }
03795
03796
void KateDocument::tagLines(
KateTextCursor start,
KateTextCursor end)
03797 {
03798
03799
if (blockSelectionMode() && start.
col() >
end.col()) {
03800
int sc = start.
col();
03801 start.
setCol(
end.col());
03802
end.setCol(sc);
03803 }
03804
03805
for (uint z = 0; z < m_views.count(); z++)
03806 m_views.at(z)->tagLines(start, end,
true);
03807 }
03808
03809
void KateDocument::tagSelection(
const KateTextCursor &oldSelectStart,
const KateTextCursor &oldSelectEnd)
03810 {
03811
if (hasSelection()) {
03812
if (oldSelectStart.
line() == -1) {
03813
03814
03815
03816 tagLines(selectStart, selectEnd);
03817
03818 }
else if (blockSelectionMode() && (oldSelectStart.
col() != selectStart.col() || oldSelectEnd.
col() != selectEnd.col())) {
03819
03820 tagLines(selectStart, selectEnd);
03821 tagLines(oldSelectStart, oldSelectEnd);
03822
03823 }
else {
03824
if (oldSelectStart != selectStart) {
03825
if (oldSelectStart < selectStart)
03826 tagLines(oldSelectStart, selectStart);
03827
else
03828 tagLines(selectStart, oldSelectStart);
03829 }
03830
03831
if (oldSelectEnd != selectEnd) {
03832
if (oldSelectEnd < selectEnd)
03833 tagLines(oldSelectEnd, selectEnd);
03834
else
03835 tagLines(selectEnd, oldSelectEnd);
03836 }
03837 }
03838
03839 }
else {
03840
03841 tagLines(oldSelectStart, oldSelectEnd);
03842 }
03843 }
03844
03845
void KateDocument::repaintViews(
bool paintOnlyDirty)
03846 {
03847
for (uint z = 0; z < m_views.count(); z++)
03848 m_views.at(z)->repaintText(paintOnlyDirty);
03849 }
03850
03851
void KateDocument::tagAll()
03852 {
03853
for (uint z = 0; z < m_views.count(); z++)
03854 {
03855 m_views.at(z)->tagAll();
03856 m_views.at(z)->updateView (
true);
03857 }
03858 }
03859
03860
void KateDocument::slotBufferChanged()
03861 {
03862 updateViews();
03863 }
03864
03865
void KateDocument::updateViews()
03866 {
03867
if (noViewUpdates)
03868
return;
03869
03870
for (KateView * view = m_views.first(); view != 0L; view = m_views.next() )
03871 {
03872 view->updateView(
true);
03873 }
03874 }
03875
03876 uint KateDocument::configFlags ()
03877 {
03878
return config()->configFlags();
03879 }
03880
03881
void KateDocument::setConfigFlags (uint flags)
03882 {
03883 config()->setConfigFlags(flags);
03884 }
03885
03886
bool KateDocument::lineColSelected (
int line,
int col)
03887 {
03888
if ( (!blockSelect) && (col < 0) )
03889 col = 0;
03890
03891
KateTextCursor cursor(line, col);
03892
03893
if (blockSelect)
03894
return cursor.
line() >= selectStart.line() && cursor.
line() <= selectEnd.line() && cursor.
col() >= selectStart.col() && cursor.
col() < selectEnd.col();
03895
else
03896
return (cursor >= selectStart) && (cursor < selectEnd);
03897 }
03898
03899
bool KateDocument::lineSelected (
int line)
03900 {
03901
return (!blockSelect)
03902 && (selectStart <=
KateTextCursor(line, 0))
03903 && (line < selectEnd.line());
03904 }
03905
03906
bool KateDocument::lineEndSelected (
int line,
int endCol)
03907 {
03908
return (!blockSelect)
03909 && (line > selectStart.line() || (line == selectStart.line() && (selectStart.col() < endCol || endCol == -1)))
03910 && (line < selectEnd.line() || (line == selectEnd.line() && (endCol <= selectEnd.col() && endCol != -1)));
03911 }
03912
03913
bool KateDocument::lineHasSelected (
int line)
03914 {
03915
return (selectStart < selectEnd)
03916 && (line >= selectStart.line())
03917 && (line <= selectEnd.line());
03918 }
03919
03920
bool KateDocument::lineIsSelection (
int line)
03921 {
03922
return (line == selectStart.line() && line == selectEnd.line());
03923 }
03924
03925
inline bool isStartBracket(
const QChar& c ) {
return c ==
'{' || c ==
'[' || c ==
'('; }
03926
inline bool isEndBracket (
const QChar& c ) {
return c ==
'}' || c ==
']' || c ==
')'; }
03927
inline bool isBracket (
const QChar& c ) {
return isStartBracket( c ) || isEndBracket( c ); }
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
void KateDocument::newBracketMark(
const KateTextCursor& cursor, KateTextRange& bm )
03940 {
03941 bm.setValid(
false);
03942
03943 bm.start() = cursor;
03944
03945
if( !findMatchingBracket( bm.start(), bm.end() ) )
03946
return;
03947
03948 bm.setValid(
true);
03949 }
03950
03951
bool KateDocument::findMatchingBracket(
KateTextCursor& start,
KateTextCursor& end )
03952 {
03953 TextLine::Ptr textLine = buffer->plainLine( start.
line() );
03954
if( !textLine )
03955
return false;
03956
03957
QChar right = textLine->getChar( start.
col() );
03958
QChar left = textLine->getChar( start.
col() - 1 );
03959
QChar bracket;
03960
03961
if ( config()->configFlags() & cfOvr ) {
03962
if( isBracket( right ) ) {
03963 bracket = right;
03964 }
else {
03965
return false;
03966 }
03967 }
else if ( isEndBracket( left ) ) {
03968 start.
setCol(start.
col() - 1);
03969 bracket = left;
03970 }
else if ( isStartBracket( right ) ) {
03971 bracket = right;
03972 }
else if ( isBracket( left ) ) {
03973 start.
setCol(start.
col() - 1);
03974 bracket = left;
03975 }
else if ( isBracket( right ) ) {
03976 bracket = right;
03977 }
else {
03978
return false;
03979 }
03980
03981
QChar opposite;
03982
03983
switch( bracket ) {
03984
case '{': opposite =
'}';
break;
03985
case '}': opposite =
'{';
break;
03986
case '[': opposite =
']';
break;
03987
case ']': opposite =
'[';
break;
03988
case '(': opposite =
')';
break;
03989
case ')': opposite =
'(';
break;
03990
default:
return false;
03991 }
03992
03993
bool forward = isStartBracket( bracket );
03994
int startAttr = textLine->attribute( start.
col() );
03995 uint count = 0;
03996
end = start;
03997
03998
while(
true ) {
03999
04000
if(
forward ) {
04001
end.setCol(
end.col() + 1);
04002
if(
end.col() >= lineLength(
end.line() ) ) {
04003
if(
end.line() >= (
int)lastLine() )
04004
return false;
04005
end.setPos(
end.line() + 1, 0);
04006 textLine = buffer->plainLine(
end.line() );
04007 }
04008 }
else {
04009
end.setCol(
end.col() - 1);
04010
if(
end.col() < 0 ) {
04011
if(
end.line() <= 0 )
04012
return false;
04013
end.setLine(
end.line() - 1);
04014
end.setCol(lineLength(
end.line() ) - 1);
04015 textLine = buffer->plainLine(
end.line() );
04016 }
04017 }
04018
04019
04020
if( textLine->attribute(
end.col() ) != startAttr )
04021
continue;
04022
04023
04024
QChar c = textLine->getChar(
end.col() );
04025
if( c == bracket ) {
04026 count++;
04027 }
else if( c == opposite ) {
04028
if( count == 0 )
04029
return true;
04030 count--;
04031 }
04032
04033 }
04034 }
04035
04036
void KateDocument::guiActivateEvent(
KParts::GUIActivateEvent *ev )
04037 {
04038
KParts::ReadWritePart::guiActivateEvent( ev );
04039
if ( ev->
activated() )
04040 emit selectionChanged();
04041 }
04042
04043
void KateDocument::setDocName (QString name )
04044 {
04045
if ( !
name.isEmpty() )
04046 {
04047
04048 m_docName =
name;
04049 emit nameChanged((
Kate::Document *)
this);
04050
return;
04051 }
04052
04053
04054
if ( !m_docName.isEmpty() && m_docName.startsWith( url().filename() ) )
return;
04055
04056
int count = -1;
04057
04058
for (uint z=0; z < KateFactory::self()->documents()->count(); z++)
04059 {
04060
if ( (KateFactory::self()->documents()->at(z) !=
this) && (KateFactory::self()->documents()->at(z)->url().filename() == url().filename()) )
04061
if ( KateFactory::self()->documents()->at(z)->m_docNameNumber > count )
04062 count = KateFactory::self()->documents()->at(z)->m_docNameNumber;
04063 }
04064
04065 m_docNameNumber = count + 1;
04066
04067 m_docName = url().filename();
04068
04069
if (m_docName.isEmpty())
04070 m_docName = i18n (
"Untitled");
04071
04072
if (m_docNameNumber > 0)
04073 m_docName = QString(m_docName +
" (%1)").arg(m_docNameNumber+1);
04074
04075 emit nameChanged ((
Kate::Document *)
this);
04076 }
04077
04078
void KateDocument::isModOnHD(
bool )
04079 {
04080
if (m_modOnHd && !url().isEmpty())
04081 {
04082 reloadFile();
04083 }
04084 }
04085
04086
class KateDocumentTmpMark
04087 {
04088
public:
04089 QString line;
04090 KTextEditor::Mark mark;
04091 };
04092
04093
void KateDocument::reloadFile()
04094 {
04095
if ( !url().isEmpty() )
04096 {
04097
if (m_modOnHd)
04098 {
04099 QString str;
04100
04101
if (m_modOnHdReason == 1)
04102 str = i18n(
"The file %1 was changed (modified) on disc by another program!\n\n").arg(url().fileName());
04103
else if (m_modOnHdReason == 2)
04104 str = i18n(
"The file %1 was changed (created) on disc by another program!\n\n").arg(url().fileName());
04105
else if (m_modOnHdReason == 3)
04106 str = i18n(
"The file %1 was changed (deleted) on disc by another program!\n\n").arg(url().fileName());
04107
04108
int i =
KMessageBox::warningYesNoCancel
04109 (0, str + i18n(
"Do you really want to reload the modified file? Data loss may occur."));
04110
if ( i != KMessageBox::Yes)
04111 {
04112
if (i == KMessageBox::No)
04113 {
04114 m_modOnHd =
false;
04115 m_modOnHdReason = 0;
04116 emit modifiedOnDisc (
this, m_modOnHd, 0);
04117 }
04118
04119
return;
04120 }
04121 }
04122
QValueList<KateDocumentTmpMark> tmp;
04123
04124
for(
QIntDictIterator<KTextEditor::Mark> it( m_marks ); it.current(); ++it )
04125 {
04126 KateDocumentTmpMark m;
04127
04128 m.line = buffer->textLine (it.current()->line);
04129 m.mark = *it.current();
04130
04131 tmp.append (m);
04132 }
04133
04134 uint mode = hlMode ();
04135
bool byUser = hlSetByUser;
04136
04137 m_reloading =
true;
04138 KateDocument::openURL( url() );
04139 m_reloading =
false;
04140
04141
for (uint z=0; z < tmp.size(); z++)
04142 {
04143
if (z < numLines())
04144 {
04145
if (buffer->textLine(tmp[z].mark.line) == tmp[z].line)
04146 setMark (tmp[z].mark.line, tmp[z].mark.type);
04147 }
04148 }
04149
04150
if (byUser)
04151 setHlMode (mode);
04152 }
04153 }
04154
04155
void KateDocument::flush ()
04156 {
04157 closeURL ();
04158 }
04159
04160
void KateDocument::setWordWrap (
bool on)
04161 {
04162 config()->setWordWrap (on);
04163 }
04164
04165
bool KateDocument::wordWrap ()
04166 {
04167
return config()->wordWrap ();
04168 }
04169
04170
void KateDocument::setWordWrapAt (uint col)
04171 {
04172 config()->setWordWrapAt (col);
04173 }
04174
04175
unsigned int KateDocument::wordWrapAt ()
04176 {
04177
return config()->wordWrapAt ();
04178 }
04179
04180
void KateDocument::applyWordWrap ()
04181 {
04182
if (hasSelection())
04183 wrapText (selectStart.line(), selectEnd.line());
04184
else
04185 wrapText (0, lastLine());
04186 }
04187
04188
void KateDocument::setPageUpDownMovesCursor (
bool on)
04189 {
04190 config()->setPageUpDownMovesCursor (on);
04191 }
04192
04193
bool KateDocument::pageUpDownMovesCursor ()
04194 {
04195
return config()->pageUpDownMovesCursor ();
04196 }
04197
04198
void KateDocument::exportAs(
const QString& filter)
04199 {
04200
if (filter==
"kate_html_export")
04201 {
04202 QString filename=
KFileDialog::getSaveFileName(QString::null,
"text/html",0,i18n(
"Export File As"));
04203
if (filename.isEmpty())
04204 {
04205
return;
04206 }
04207
KSaveFile *savefile=
new KSaveFile(filename);
04208
if (!savefile->
status())
04209 {
04210
if (exportDocumentToHTML(savefile->
textStream(),filename)) savefile->
close();
04211
else savefile->
abort();
04212
04213 }
else {}
04214
delete savefile;
04215 }
04216 }
04217
04218
04219
bool KateDocument::exportDocumentToHTML(
QTextStream *outputStream,
const QString &name)
04220 {
04221 outputStream->setEncoding(QTextStream::UnicodeUTF8);
04222
04223 (*outputStream) <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" <<
endl;
04224 (*outputStream) <<
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">" <<
endl;
04225 (*outputStream) <<
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" <<
endl;
04226 (*outputStream) <<
"<head>" <<
endl;
04227 (*outputStream) <<
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />" <<
endl;
04228 (*outputStream) <<
"<meta name=\"Generator\" content=\"Kate, the KDE Advanced Text Editor\" />" <<
endl;
04229
04230 (*outputStream) <<
"<title>" <<
name.right(
name.length() -
name.findRev(
'/') -1) <<
"</title>" <<
endl;
04231 (*outputStream) <<
"</head>" <<
endl;
04232
04233 (*outputStream) <<
"<body><pre>" <<
endl;
04234
04235
04236
04237
bool previousCharacterWasBold =
false;
04238
bool previousCharacterWasItalic =
false;
04239
04240
04241
04242
bool needToReinitializeTags =
false;
04243
QColor previousCharacterColor(0,0,0);
04244 (*outputStream) <<
"<span style='color: #000000'>";
04245
04246
for (uint curLine=0;curLine<numLines();curLine++)
04247 {
04248 TextLine::Ptr textLine = buffer->plainLine(curLine);
04249
04250
04251
for (uint curPos=0;curPos<textLine->length();curPos++)
04252 {
04253
04254
QMemArray<KateAttribute> *attributes = m_highlight->attributes (0);
04255
KateAttribute* charAttributes = 0;
04256
04257
if (textLine->attribute(curPos) < attributes->size())
04258 charAttributes = &attributes->at(textLine->attribute(curPos));
04259
else
04260 charAttributes = &attributes->at(0);
04261
04262
04263
04264
if ( (charAttributes->
textColor() != previousCharacterColor))
04265 {
04266
04267
if (previousCharacterWasBold)
04268 (*outputStream) <<
"</b>";
04269
if (previousCharacterWasItalic)
04270 (*outputStream) <<
"</i>";
04271
04272
04273 (*outputStream) <<
"</span>";
04274
04275
int red, green, blue;
04276
04277 charAttributes->
textColor().rgb(&red, &green, &blue);
04278 (*outputStream) <<
"<span style='color: #"
04279 << ( (red < 0x10)?
"0":
"")
04280 << QString::number(red, 16)
04281 << ( (green < 0x10)?
"0":
"")
04282 << QString::number(green, 16)
04283 << ( (blue < 0x10)?
"0":
"")
04284 << QString::number(blue, 16)
04285 <<
"'>";
04286
04287 needToReinitializeTags =
true;
04288 }
04289
04290
if ( (needToReinitializeTags && charAttributes->
bold()) ||
04291 (!previousCharacterWasBold && charAttributes->
bold()) )
04292
04293 (*outputStream) <<
"<b>";
04294
if ( !needToReinitializeTags && (previousCharacterWasBold && !charAttributes->
bold()) )
04295
04296 (*outputStream) <<
"</b>";
04297
04298
04299
if ( (needToReinitializeTags && charAttributes->
italic()) ||
04300 (!previousCharacterWasItalic && charAttributes->
italic()) )
04301
04302 (*outputStream) <<
"<i>";
04303
if ( !needToReinitializeTags && (previousCharacterWasItalic && !charAttributes->
italic()) )
04304
04305 (*outputStream) <<
"</i>";
04306
04307
04308 (*outputStream) << HTMLEncode(textLine->getChar(curPos));
04309
04310
04311 previousCharacterWasItalic = charAttributes->
italic();
04312 previousCharacterWasBold = charAttributes->
bold();
04313 previousCharacterColor = charAttributes->
textColor();
04314 needToReinitializeTags =
false;
04315 }
04316
04317 (*outputStream) <<
endl;
04318 }
04319
04320
04321
if (previousCharacterWasBold)
04322 (*outputStream) <<
"</b>";
04323
if (previousCharacterWasItalic)
04324 (*outputStream) <<
"</i>";
04325
04326
04327 (*outputStream) <<
"</span>";
04328 (*outputStream) <<
"</pre></body>";
04329 (*outputStream) <<
"</html>";
04330
04331
return true;
04332 }
04333
04334 QString KateDocument::HTMLEncode(
QChar theChar)
04335 {
04336
switch (theChar.latin1())
04337 {
04338
case '>':
04339
return QString(
">");
04340
case '<':
04341
return QString(
"<");
04342
case '&':
04343
return QString(
"&");
04344 };
04345
return theChar;
04346 }
04347
04348 Kate::ConfigPage *KateDocument::colorConfigPage (
QWidget *p)
04349 {
04350
return (Kate::ConfigPage*)
new KateSchemaConfigPage (p);
04351 }
04352
04353 Kate::ConfigPage *KateDocument::viewDefaultsConfigPage (
QWidget *p)
04354 {
04355
return (Kate::ConfigPage*)
new ViewDefaultsConfig(p);
04356 }
04357
04358 Kate::ConfigPage *KateDocument::fontConfigPage (
QWidget *p)
04359 {
04360
return (Kate::ConfigPage*)
new KateSchemaConfigPage (p);
04361 }
04362
04363 Kate::ConfigPage *KateDocument::indentConfigPage (
QWidget *p)
04364 {
04365
return (Kate::ConfigPage*)
new IndentConfigTab(p);
04366 }
04367
04368 Kate::ConfigPage *KateDocument::selectConfigPage (
QWidget *p)
04369 {
04370
return (Kate::ConfigPage*)
new SelectConfigTab(p);
04371 }
04372
04373 Kate::ConfigPage *KateDocument::editConfigPage (
QWidget *p)
04374 {
04375
return (Kate::ConfigPage*)
new EditConfigTab(p);
04376 }
04377
04378 Kate::ConfigPage *KateDocument::keysConfigPage (
QWidget *p)
04379 {
04380
return (Kate::ConfigPage*)
new EditKeyConfiguration(p,
this);
04381 }
04382
04383 Kate::ConfigPage *KateDocument::hlConfigPage (
QWidget *p)
04384 {
04385
return (Kate::ConfigPage*)
new HlConfigPage (p);
04386 }
04387
04388 Kate::ConfigPage *KateDocument::saveConfigPage(
QWidget *p)
04389 {
04390
return (Kate::ConfigPage*)
new SaveConfigTab(p);
04391 }
04392
04393 Kate::ActionMenu *KateDocument::hlActionMenu (
const QString& text,
QObject* parent,
const char* name)
04394 {
04395 KateViewHighlightAction *menu =
new KateViewHighlightAction (text, parent, name);
04396 menu->setWhatsThis(i18n(
"Here you can choose how the current document should be highlighted."));
04397 menu->updateMenu (
this);
04398
04399
return (Kate::ActionMenu *)menu;
04400 }
04401
04402 Kate::ActionMenu *KateDocument::exportActionMenu (
const QString& text,
QObject* parent,
const char* name)
04403 {
04404 KateExportAction *menu =
new KateExportAction (text, parent, name);
04405 menu->updateMenu (
this);
04406 menu->setWhatsThis(i18n(
"This command allows you to export the current document"
04407
" with all highlighting information into a markup document, e.g. HTML."));
04408
return (Kate::ActionMenu *)menu;
04409 }
04410
04411
void KateDocument::dumpRegionTree()
04412 {
04413 buffer->dumpRegionTree();
04414 }
04415
04416
unsigned int KateDocument::getRealLine(
unsigned int virtualLine)
04417 {
04418
return buffer->lineNumber (virtualLine);
04419 }
04420
04421
unsigned int KateDocument::getVirtualLine(
unsigned int realLine)
04422 {
04423
return buffer->lineVisibleNumber (realLine);
04424 }
04425
04426
unsigned int KateDocument::visibleLines ()
04427 {
04428
return buffer->countVisible ();
04429 }
04430
04431 TextLine::Ptr KateDocument::kateTextLine(uint i)
04432 {
04433
return buffer->line (i);
04434 }
04435
04436 TextLine::Ptr KateDocument::plainKateTextLine(uint i)
04437 {
04438
return buffer->plainLine (i);
04439 }
04440
04441
04442
04443
04444 KTextEditor::Cursor *KateDocument::createCursor ( )
04445 {
04446
return new KateSuperCursor (
this,
false, 0, 0,
this);
04447 }
04448
04449
void KateDocument::tagArbitraryLines(KateView* view,
KateSuperRange* range)
04450 {
04451
if (view)
04452 view->tagLines(range->
start(), range->
end());
04453
else
04454 tagLines(range->
start(), range->
end());
04455 }
04456
04457
04458
04459
04460
void KateDocument::spellcheck()
04461 {
04462
if( !isReadWrite() || text().isEmpty())
04463
return;
04464
04465 m_kspell =
new KSpell( 0, i18n(
"Spellcheck"),
04466
this, SLOT(ready(KSpell *)) );
04467
04468 connect( m_kspell, SIGNAL(death()),
04469
this, SLOT(spellCleanDone()) );
04470
04471 connect( m_kspell, SIGNAL(misspelling(
const QString&,
const QStringList&,
unsigned int)),
04472
this, SLOT(misspelling(
const QString&,
const QStringList&,
unsigned int)) );
04473 connect( m_kspell, SIGNAL(corrected(
const QString&,
const QString&,
unsigned int)),
04474
this, SLOT(corrected(
const QString&,
const QString&,
unsigned int)) );
04475 connect( m_kspell, SIGNAL(done(
const QString&)),
04476
this, SLOT(spellResult(
const QString&)) );
04477 }
04478
04479
void KateDocument::ready(KSpell *)
04480 {
04481 m_mispellCount = 0;
04482 m_replaceCount = 0;
04483
04484 m_kspell->setProgressResolution( 1 );
04485
04486 m_kspell->check( text() );
04487
04488
kdDebug () <<
"SPELLING READY STATUS: " << m_kspell->status () <<
endl;
04489 }
04490
04491
void KateDocument::locatePosition( uint pos, uint& line, uint& col )
04492 {
04493 uint cnt = 0;
04494
04495 line = col = 0;
04496
04497
04498
04499
04500
for( ; line < numLines() && cnt <= pos; line++ )
04501 cnt += lineLength(line) + 1;
04502
04503 line--;
04504 col = pos - (cnt - lineLength(line)) + 1;
04505 }
04506
04507
void KateDocument::misspelling(
const QString& origword,
const QStringList&,
unsigned int pos )
04508 {
04509 m_mispellCount++;
04510
04511 uint line, col;
04512
04513 locatePosition( pos, line, col );
04514
04515
if (activeView())
04516 activeView()->setCursorPositionInternal (line, col, 1);
04517
04518 setSelection( line, col, line, col + origword.length() );
04519 }
04520
04521
void KateDocument::corrected(
const QString& originalword,
const QString& newword,
unsigned int pos )
04522 {
04523 m_replaceCount++;
04524
04525 uint line, col;
04526
04527 locatePosition( pos, line, col );
04528
04529 removeText( line, col, line, col + originalword.length() );
04530 insertText( line, col, newword );
04531 }
04532
04533
void KateDocument::spellResult(
const QString& )
04534 {
04535 clearSelection();
04536 m_kspell->cleanUp();
04537 }
04538
04539
void KateDocument::spellCleanDone()
04540 {
04541
KSpell::spellStatus status = m_kspell->status();
04542
04543
if( status == KSpell::Error ) {
04544
KMessageBox::sorry( 0,
04545 i18n(
"ISpell could not be started. "
04546
"Please make sure you have ISpell "
04547
"properly configured and in your PATH."));
04548 }
else if( status == KSpell::Crashed ) {
04549
KMessageBox::sorry( 0,
04550 i18n(
"ISpell seems to have crashed."));
04551 }
04552
04553
delete m_kspell;
04554 m_kspell = 0;
04555
04556
kdDebug () <<
"SPELLING END" <<
endl;
04557 }
04558
04559
04560
void KateDocument::lineInfo (KateLineInfo *info,
unsigned int line)
04561 {
04562 buffer->lineInfo(info,line);
04563 }
04564
04565 KateCodeFoldingTree *KateDocument::foldingTree ()
04566 {
04567
return buffer->foldingTree();
04568 }
04569
04570
void KateDocument::setEncoding (
const QString &e)
04571 {
04572 m_config->setEncoding(e);
04573 }
04574
04575 QString KateDocument::encoding()
const
04576
{
04577
return m_config->encoding();
04578 }
04579
04580
void KateDocument::updateConfig ()
04581 {
04582 emit undoChanged ();
04583 tagAll();
04584
04585
for (KateView * view = m_views.first(); view != 0L; view = m_views.next() )
04586 {
04587 view->updateDocumentConfig ();
04588 }
04589
04590
04591
if (m_indenter->modeNumber() != m_config->indentationMode())
04592 {
04593
delete m_indenter;
04594 m_indenter = KateAutoIndent::createIndenter (
this, m_config->indentationMode() );
04595 }
04596
04597 m_indenter->updateConfig();
04598
04599 buffer->setTabWidth (config()->tabWidth());
04600
04601
04602
for (uint i=0; i<KateFactory::self()->plugins().count(); i++)
04603 {
04604
if (config()->plugin (i))
04605 loadPlugin (i);
04606
else
04607 unloadPlugin (i);
04608 }
04609 }
04610
04611
04612
04613
04614
04615
04616
04617
04618
QRegExp KateDocument::kvLine =
QRegExp(
"kate:(.*)");
04619 QRegExp KateDocument::kvVar = QRegExp(
"([\\w\\-]+)\\s+([^;]+)");
04620
04621
void KateDocument::readVariables(
bool onlyViewAndRenderer)
04622 {
04623
if (!onlyViewAndRenderer)
04624 m_config->configStart();
04625
04626
04627 KateView *v;
04628
for (v = m_views.first(); v != 0L; v= m_views.next() )
04629 {
04630 v->config()->configStart();
04631 v->renderer()->config()->configStart();
04632 }
04633
04634
for (uint i=0; i < QMIN( 9, numLines() ); ++i )
04635 {
04636 readVariableLine( textLine( i ), onlyViewAndRenderer );
04637 }
04638
if ( numLines() > 10 )
04639 {
04640
for ( uint i = QMAX(10, numLines() - 10); i < numLines(); ++i )
04641 {
04642 readVariableLine( textLine( i ), onlyViewAndRenderer );
04643 }
04644 }
04645
04646
if (!onlyViewAndRenderer)
04647 m_config->configEnd();
04648
04649
for (v = m_views.first(); v != 0L; v= m_views.next() )
04650 {
04651 v->config()->configEnd();
04652 v->renderer()->config()->configEnd();
04653 }
04654 }
04655
04656
void KateDocument::readVariableLine( QString t,
bool onlyViewAndRenderer )
04657 {
04658
if ( kvLine.search( t ) > -1 )
04659 {
04660
QStringList vvl;
04661 vvl <<
"dynamic-word-wrap" <<
"dynamic-word-wrap-indicators"
04662 <<
"line-numbers" <<
"icon-border" <<
"folding-markers"
04663 <<
"bookmark-sorting" <<
"auto-center-lines"
04664 <<
"icon-bar-color"
04665
04666 <<
"background-color" <<
"selection-color"
04667 <<
"current-line-color" <<
"bracket-highlight-color"
04668 <<
"word-wrap-marker-color"
04669 <<
"font" <<
"font-size" <<
"scheme";
04670
int p( 0 );
04671 QString s = kvLine.cap(1);
04672 QString var, val;
04673
while ( (p = kvVar.search( s, p )) > -1 )
04674 {
04675 p += kvVar.matchedLength();
04676 var = kvVar.cap( 1 );
04677 val = kvVar.cap( 2 ).stripWhiteSpace();
04678
bool state;
04679
int n;
04680
04681
04682
if (onlyViewAndRenderer)
04683 {
04684
if ( vvl.contains( var ) )
04685 setViewVariable( var, val );
04686 }
04687
else
04688 {
04689
04690
if ( var ==
"word-wrap" && checkBoolValue( val, &state ) )
04691 setWordWrap( state );
04692
else if ( var ==
"block-selection" && checkBoolValue( val, &state ) )
04693 setBlockSelectionMode( state );
04694
04695
04696
else if ( var ==
"auto-indent" && checkBoolValue( val, &state ) )
04697 m_config->setConfigFlags( KateDocumentConfig::cfAutoIndent, state );
04698
else if ( var ==
"backspace-indents" && checkBoolValue( val, &state ) )
04699 m_config->setConfigFlags( KateDocumentConfig::cfBackspaceIndents, state );
04700
else if ( var ==
"replace-tabs" && checkBoolValue( val, &state ) )
04701 m_config->setConfigFlags( KateDocumentConfig::cfReplaceTabs, state );
04702
else if ( var ==
"wrap-cursor" && checkBoolValue( val, &state ) )
04703 m_config->setConfigFlags( KateDocumentConfig::cfWrapCursor, state );
04704
else if ( var ==
"auto-brackets" && checkBoolValue( val, &state ) )
04705 m_config->setConfigFlags( KateDocumentConfig::cfAutoBrackets, state );
04706
else if ( var ==
"persistent-selection" && checkBoolValue( val, &state ) )
04707 m_config->setConfigFlags( KateDocumentConfig::cfPersistent, state );
04708
else if ( var ==
"keep-selection" && checkBoolValue( val, &state ) )
04709 m_config->setConfigFlags( KateDocumentConfig::cfBackspaceIndents, state );
04710
else if ( var ==
"overwrite-mode" && checkBoolValue( val, &state ) )
04711 m_config->setConfigFlags( KateDocumentConfig::cfOvr, state );
04712
else if ( var ==
"keep-indent-profile" && checkBoolValue( val, &state ) )
04713 m_config->setConfigFlags( KateDocumentConfig::cfKeepIndentProfile, state );
04714
else if ( var ==
"keep-extra-spaces" && checkBoolValue( val, &state ) )
04715 m_config->setConfigFlags( KateDocumentConfig::cfKeepExtraSpaces, state );
04716
else if ( var ==
"tab-indents" && checkBoolValue( val, &state ) )
04717 m_config->setConfigFlags( KateDocumentConfig::cfTabIndents, state );
04718
else if ( var ==
"show-tabs" && checkBoolValue( val, &state ) )
04719 m_config->setConfigFlags( KateDocumentConfig::cfShowTabs, state );
04720
else if ( var ==
"space-indent" && checkBoolValue( val, &state ) )
04721 m_config->setConfigFlags( KateDocumentConfig::cfSpaceIndent, state );
04722
else if ( var ==
"smart-home" && checkBoolValue( val, &state ) )
04723 m_config->setConfigFlags( KateDocumentConfig::cfSmartHome, state );
04724
04725
04726
else if ( var ==
"tab-width" && checkIntValue( val, &n ) )
04727 m_config->setTabWidth( n );
04728
else if ( var ==
"indent-width" && checkIntValue( val, &n ) )
04729 m_config->setIndentationWidth( n );
04730
else if ( var ==
"indent-mode" )
04731 {
04732
if ( checkIntValue( val, &n ) )
04733 m_config->setIndentationMode( n );
04734
else
04735 m_config->setIndentationMode( KateAutoIndent::modeNumber( val) );
04736 }
04737
else if ( var ==
"word-wrap-column" && n > 0 && checkIntValue( val, &n ) )
04738 m_config->setWordWrapAt( n );
04739
else if ( var ==
"undo-steps" && n >= 0 && checkIntValue( val, &n ) )
04740 setUndoSteps( n );
04741
04742
04743
else if ( var ==
"eol" || var ==
"end-of-line" )
04744 {
04745
QStringList l;
04746 l <<
"unix" <<
"dos" <<
"mac";
04747
if ( (n = l.findIndex( val.lower() )) != -1 )
04748 m_config->setEol( n );
04749 }
04750
else if ( var ==
"encoding" )
04751 m_config->setEncoding( val );
04752
else if ( var ==
"syntax" || var ==
"hl" )
04753 {
04754
for ( uint i=0; i < hlModeCount(); i++ )
04755 {
04756
if ( hlModeName( i ) == val )
04757 {
04758 setHlMode( i );
04759
break;
04760 }
04761 }
04762 }
04763
04764
04765
else if ( vvl.contains( var ) )
04766 setViewVariable( var, val );
04767 }
04768 }
04769 }
04770 }
04771
04772
void KateDocument::setViewVariable( QString var, QString val )
04773 {
04774
04775 KateView *v;
04776
bool state;
04777
int n;
04778
QColor c;
04779
for (v = m_views.first(); v != 0L; v= m_views.next() )
04780 {
04781
if ( var ==
"dynamic-word-wrap" && checkBoolValue( val, &state ) )
04782 v->config()->setDynWordWrap( state );
04783
04784
04785
else if ( var ==
"line-numbers" && checkBoolValue( val, &state ) )
04786 v->config()->setLineNumbers( state );
04787
else if (var ==
"icon-border" && checkBoolValue( val, &state ) )
04788 v->config()->setIconBar( state );
04789
else if (var ==
"folding-markers" && checkBoolValue( val, &state ) )
04790 v->config()->setFoldingBar( state );
04791
else if ( var ==
"auto-center-lines" && checkIntValue( val, &n ) )
04792 v->config()->setAutoCenterLines( n );
04793
else if ( var ==
"icon-bar-color" && checkColorValue( val, c ) )
04794 v->renderer()->config()->setIconBarColor( c );
04795
04796
else if ( var ==
"background-color" && checkColorValue( val, c ) )
04797 v->renderer()->config()->setBackgroundColor( c );
04798
else if ( var ==
"selection-color" && checkColorValue( val, c ) )
04799 v->renderer()->config()->setSelectionColor( c );
04800
else if ( var ==
"current-line-color" && checkColorValue( val, c ) )
04801 v->renderer()->config()->setHighlightedLineColor( c );
04802
else if ( var ==
"bracket-highlight-color" && checkColorValue( val, c ) )
04803 v->renderer()->config()->setHighlightedBracketColor( c );
04804
else if ( var ==
"word-wrap-marker-color" && checkColorValue( val, c ) )
04805 v->renderer()->config()->setWordWrapMarkerColor( c );
04806
else if ( var ==
"font" || ( var ==
"font-size" && checkIntValue( val, &n ) ) )
04807 {
04808
QFont _f( *v->renderer()->config()->font( ) );
04809
04810
if ( var ==
"font" )
04811 {
04812 _f.setFamily( val );
04813 _f.setFixedPitch(
QFont( val ).fixedPitch() );
04814 }
04815
else
04816 _f.setPointSize( n );
04817
04818 v->renderer()->config()->setFont( _f );
04819 }
04820
else if ( var ==
"scheme" )
04821 {
04822 v->renderer()->config()->setSchema( KateFactory::self()->schemaManager()->
number( val ) );
04823 }
04824 }
04825 }
04826
04827
bool KateDocument::checkBoolValue( QString val,
bool *result )
04828 {
04829 val = val.stripWhiteSpace().lower();
04830
QStringList l;
04831 l <<
"1" <<
"on" <<
"true";
04832
if ( l.contains( val ) )
04833 {
04834 *result =
true;
04835
return true;
04836 }
04837 l.clear();
04838 l <<
"0" <<
"off" <<
"false";
04839
if ( l.contains( val ) )
04840 {
04841 *result =
false;
04842
return true;
04843 }
04844
return false;
04845 }
04846
04847
bool KateDocument::checkIntValue( QString val,
int *result )
04848 {
04849
bool ret(
false );
04850 *result = val.toInt( &ret );
04851
return ret;
04852 }
04853
04854
bool KateDocument::checkColorValue( QString val,
QColor &c )
04855 {
04856 c.setNamedColor( val );
04857
return c.isValid();
04858 }
04859
04860
04861
04862
void KateDocument::slotModOnHdDirty (
const QString &path)
04863 {
04864
if ((path == m_dirWatchFile) && (!m_modOnHd || m_modOnHdReason != 1))
04865 {
04866
04867
if ( ! m_digest.isEmpty() )
04868 {
04869
QCString tmp;
04870
if ( createDigest( tmp ) && tmp == m_digest )
04871
return;
04872 }
04873 m_modOnHd =
true;
04874 m_modOnHdReason = 1;
04875 emit modifiedOnDisc (
this, m_modOnHd, m_modOnHdReason);
04876 }
04877 }
04878
04879
void KateDocument::slotModOnHdCreated (
const QString &path)
04880 {
04881
if ((path == m_dirWatchFile) && (!m_modOnHd || m_modOnHdReason != 2))
04882 {
04883 m_modOnHd =
true;
04884 m_modOnHdReason = 2;
04885 emit modifiedOnDisc (
this, m_modOnHd, m_modOnHdReason);
04886 }
04887 }
04888
04889
void KateDocument::slotModOnHdDeleted (
const QString &path)
04890 {
04891
if ((path == m_dirWatchFile) && (!m_modOnHd || m_modOnHdReason != 3))
04892 {
04893 m_modOnHd =
true;
04894 m_modOnHdReason = 3;
04895 emit modifiedOnDisc (
this, m_modOnHd, m_modOnHdReason);
04896 }
04897 }
04898
04899
bool KateDocument::createDigest(
QCString &result )
04900 {
04901
bool ret =
false;
04902 result =
"";
04903
if ( url().isLocalFile() )
04904 {
04905
QFile f ( url().path() );
04906
if ( f.open( IO_ReadOnly) )
04907 {
04908
KMD5 md5;
04909 ret = md5.
update( f );
04910 md5.
hexDigest( result );
04911 f.close();
04912 }
04913 }
04914
return ret;
04915 }
04916
04917
bool KateDocument::wrapCursor ()
04918 {
04919
return !blockSelect && (configFlags() & KateDocument::cfWrapCursor);
04920 }
04921
04922
void KateDocument::updateFileType (
int newType,
bool user)
04923 {
04924
if (user || !m_fileTypeSetByUser)
04925 {
04926
const KateFileType *t = 0;
04927
if ((newType == -1) || (t = KateFactory::self()->fileTypeManager()->fileType (newType)))
04928 {
04929 m_fileType = newType;
04930
04931
if (t)
04932 {
04933 m_config->configStart();
04934
04935 KateView *v;
04936
for (v = m_views.first(); v != 0L; v= m_views.next() )
04937 {
04938 v->config()->configStart();
04939 v->renderer()->config()->configStart();
04940 }
04941
04942 readVariableLine( t->varLine );
04943
04944 m_config->configEnd();
04945
for (v = m_views.first(); v != 0L; v= m_views.next() )
04946 {
04947 v->config()->configEnd();
04948 v->renderer()->config()->configEnd();
04949 }
04950 }
04951 }
04952 }
04953 }
04954
04955 uint KateDocument::documentNumber ()
const
04956
{
04957
return KTextEditor::Document::documentNumber ();
04958 }
04959
04960
04961
04962
04963
void KateDocument::slotQueryClose_save(
bool *handled,
bool* abortClosing) {
04964 *handled=
true;
04965 *abortClosing=
true;
04966
if (m_url.isEmpty())
04967 {
04968 KEncodingFileDialog::Result res=
KEncodingFileDialog::getSaveURLAndEncoding(config()->encoding(),
04969 QString::null,QString::null,0,i18n(
"Save File"));
04970
04971
if( res.URLs.isEmpty() || !checkOverwrite( res.URLs.first() ) ) {
04972 *abortClosing=
true;
04973
return;
04974 }
04975 setEncoding( res.encoding );
04976
saveAs( res.URLs.first() );
04977 *abortClosing=
false;
04978 }
04979
else
04980 {
04981
save();
04982 *abortClosing=
false;
04983 }
04984
04985 }
04986
04987
04988
bool KateDocument::checkOverwrite(
KURL u )
04989 {
04990
if( !u.
isLocalFile() )
04991
return true;
04992
04993
QFileInfo info( u.
path() );
04994
if( !info.exists() )
04995
return true;
04996
04997
return KMessageBox::Cancel !=
KMessageBox::warningContinueCancel( 0,
04998 i18n(
"A file named \"%1\" already exists. "
04999
"Are you sure you want to overwrite it?" ).arg( info.fileName() ),
05000 i18n(
"Overwrite File?" ),
05001 i18n(
"&Overwrite" ) );
05002 }
05003
05004
void KateDocument::setDefaultEncoding (
const QString &encoding)
05005 {
05006 s_defaultEncoding = encoding;
05007 }
05008
05009
void KateDocument::setIMSelectionValue( uint imStartLine, uint imStart, uint imEnd,
05010 uint imSelStart, uint imSelEnd,
bool imComposeEvent )
05011 {
05012 m_imStartLine = imStartLine;
05013 m_imStart = imStart;
05014 m_imEnd = imEnd;
05015 m_imSelStart = imSelStart;
05016 m_imSelEnd = imSelEnd;
05017 m_imComposeEvent = imComposeEvent;
05018 }
05019
05020
void KateDocument::getIMSelectionValue( uint *imStartLine, uint *imStart, uint *imEnd,
05021 uint *imSelStart, uint *imSelEnd )
05022 {
05023 *imStartLine = m_imStartLine;
05024 *imStart = m_imStart;
05025 *imEnd = m_imEnd;
05026 *imSelStart = m_imSelStart;
05027 *imSelEnd = m_imSelEnd;
05028 }
05029
05030