• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kate
 

kate

  • kate
  • app
katedocmanager.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
3 Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "katedocmanager.h"
21#include "katedocmanager.moc"
22#include "kateapp.h"
23#include "katemainwindow.h"
24#include "kateviewmanager.h"
25#include "katedocmanageriface.h"
26#include "kateexternaltools.h"
27#include "kateviewspacecontainer.h"
28
29#include <kate/view.h>
30
31#include <tdetexteditor/encodinginterface.h>
32
33#include <tdeparts/factory.h>
34
35#include <tdelocale.h>
36#include <kdebug.h>
37#include <tdeconfig.h>
38#include <klibloader.h>
39#include <kmdcodec.h>
40#include <tdemessagebox.h>
41#include <kencodingfiledialog.h>
42#include <tdeio/job.h>
43#include <twin.h>
44
45#include <tqdatetime.h>
46#include <tqtextcodec.h>
47#include <tqprogressdialog.h>
48
49KateDocManager::KateDocManager (TQObject *parent)
50 : TQObject (parent)
51 , m_saveMetaInfos(true)
52 , m_daysMetaInfos(0)
53{
54 m_factory = (KParts::Factory *) KLibLoader::self()->factory ("libkatepart");
55
56 m_documentManager = new Kate::DocumentManager (this);
57 m_docList.setAutoDelete(true);
58 m_docDict.setAutoDelete(false);
59 m_docInfos.setAutoDelete(true);
60
61 m_dcop = new KateDocManagerDCOPIface (this);
62
63 m_metaInfos = new TDEConfig("metainfos", false, false, "appdata");
64
65 createDoc ();
66}
67
68KateDocManager::~KateDocManager ()
69{
70 // save config
71 if (!m_docList.isEmpty())
72 m_docList.at(0)->writeConfig(KateApp::self()->config());
73
74 if (m_saveMetaInfos)
75 {
76 // saving meta-infos when file is saved is not enough, we need to do it once more at the end
77 for (Kate::Document *doc = m_docList.first(); doc; doc = m_docList.next())
78 saveMetaInfos(doc);
79
80 // purge saved filesessions
81 if (m_daysMetaInfos > 0)
82 {
83 TQStringList groups = m_metaInfos->groupList();
84 TQDateTime *def = new TQDateTime(TQDate(1970, 1, 1));
85 for (TQStringList::Iterator it = groups.begin(); it != groups.end(); ++it)
86 {
87 m_metaInfos->setGroup(*it);
88 TQDateTime last = m_metaInfos->readDateTimeEntry("Time", def);
89 if (last.daysTo(TQDateTime::currentDateTime()) > m_daysMetaInfos)
90 m_metaInfos->deleteGroup(*it);
91 }
92 delete def;
93 }
94 }
95
96 delete m_dcop;
97 delete m_metaInfos;
98}
99
100KateDocManager *KateDocManager::self ()
101{
102 return KateApp::self()->documentManager ();
103}
104
105Kate::Document *KateDocManager::createDoc ()
106{
107 KTextEditor::Document *doc = (KTextEditor::Document *) m_factory->createPart (0, "", this, "", "KTextEditor::Document");
108
109 m_docList.append((Kate::Document *)doc);
110 m_docDict.insert (doc->documentNumber(), (Kate::Document *)doc);
111 m_docInfos.insert (doc, new KateDocumentInfo ());
112
113 if (m_docList.count() < 2)
114 ((Kate::Document *)doc)->readConfig(KateApp::self()->config());
115
116 emit documentCreated ((Kate::Document *)doc);
117 emit m_documentManager->documentCreated ((Kate::Document *)doc);
118
119 connect(doc,TQ_SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),this,TQ_SLOT(slotModifiedOnDisc(Kate::Document *, bool, unsigned char)));
120 return (Kate::Document *)doc;
121}
122
123void KateDocManager::deleteDoc (Kate::Document *doc)
124{
125 uint id = doc->documentNumber();
126 uint activeId = 0;
127 if (m_currentDoc)
128 activeId = m_currentDoc->documentNumber ();
129
130 if (m_docList.count() < 2)
131 doc->writeConfig(KateApp::self()->config());
132
133 m_docInfos.remove (doc);
134 m_docDict.remove (id);
135 m_docList.remove (doc);
136
137 emit documentDeleted (id);
138 emit m_documentManager->documentDeleted (id);
139
140 // ohh, current doc was deleted
141 if (activeId == id)
142 {
143 // special case of documentChanged, no longer any doc here !
144 m_currentDoc = 0;
145
146 emit documentChanged ();
147 emit m_documentManager->documentChanged ();
148 }
149}
150
151Kate::Document *KateDocManager::document (uint n)
152{
153 return m_docList.at(n);
154}
155
156Kate::Document *KateDocManager::activeDocument ()
157{
158 return m_currentDoc;
159}
160
161void KateDocManager::setActiveDocument (Kate::Document *doc)
162{
163 if (!doc)
164 return;
165
166 if (m_currentDoc && (m_currentDoc->documentNumber() == doc->documentNumber()))
167 return;
168
169 m_currentDoc = doc;
170
171 emit documentChanged ();
172 emit m_documentManager->documentChanged ();
173}
174
175Kate::Document *KateDocManager::firstDocument ()
176{
177 return m_docList.first();
178}
179
180Kate::Document *KateDocManager::nextDocument ()
181{
182 return m_docList.next();
183}
184
185Kate::Document *KateDocManager::documentWithID (uint id)
186{
187 return m_docDict[id];
188}
189
190const KateDocumentInfo *KateDocManager::documentInfo (Kate::Document *doc)
191{
192 return m_docInfos[doc];
193}
194
195int KateDocManager::findDocument (Kate::Document *doc)
196{
197 return m_docList.find (doc);
198}
199
200uint KateDocManager::documents ()
201{
202 return m_docList.count ();
203}
204
205int KateDocManager::findDocument ( KURL url )
206{
207 TQPtrListIterator<Kate::Document> it(m_docList);
208
209 for (; it.current(); ++it)
210 {
211 if ( it.current()->url() == url)
212 return it.current()->documentNumber();
213 }
214 return -1;
215}
216
217Kate::Document *KateDocManager::findDocumentByUrl( KURL url )
218{
219 for (TQPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
220 {
221 if ( it.current()->url() == url)
222 return it.current();
223 }
224
225 return 0L;
226}
227
228bool KateDocManager::isOpen(KURL url)
229{
230 // return just if we found some document with this url
231 return findDocumentByUrl (url) != 0;
232}
233
234Kate::Document *KateDocManager::openURL (const KURL& url,const TQString &encoding, uint *id, bool isTempFile)
235{
236 // special handling if still only the first initial doc is there
237 if (!documentList().isEmpty() && (documentList().count() == 1) && (!documentList().at(0)->isModified() && documentList().at(0)->url().isEmpty()))
238 {
239 Kate::Document* doc = documentList().getFirst();
240
241 doc->setEncoding(encoding);
242
243 if (!loadMetaInfos(doc, url))
244 doc->openURL (url);
245
246 if (id)
247 *id=doc->documentNumber();
248
249 if ( isTempFile && !url.isEmpty() && url.isLocalFile() )
250 {
251 TQFileInfo fi( url.path() );
252 if ( fi.exists() )
253 {
254 m_tempFiles[ doc->documentNumber() ] = qMakePair(url, fi.lastModified());
255 kdDebug(13001)<<"temporary file will be deleted after use unless modified: "<<url.prettyURL()<<endl;
256 }
257 }
258
259 connect(doc, TQ_SIGNAL(modStateChanged(Kate::Document *)), this, TQ_SLOT(slotModChanged(Kate::Document *)));
260
261 emit initialDocumentReplaced();
262
263 return doc;
264 }
265
266 Kate::Document *doc = findDocumentByUrl (url);
267 if ( !doc )
268 {
269 doc = (Kate::Document *)createDoc ();
270
271 doc->setEncoding(encoding.isNull() ? Kate::Document::defaultEncoding() : encoding);
272
273 if (!loadMetaInfos(doc, url))
274 doc->openURL (url);
275 }
276
277 if (id)
278 *id=doc->documentNumber();
279
280 if ( isTempFile && !url.isEmpty() && url.isLocalFile() )
281 {
282 TQFileInfo fi( url.path() );
283 if ( fi.exists() )
284 {
285 m_tempFiles[ doc->documentNumber() ] = qMakePair(url, fi.lastModified());
286 kdDebug(13001)<<"temporary file will be deleted after use unless modified: "<<url.prettyURL()<<endl;
287 }
288 }
289
290 return doc;
291}
292
293bool KateDocManager::closeDocument(class Kate::Document *doc,bool closeURL)
294{
295 if (!doc) return false;
296
297 saveMetaInfos(doc);
298 if (closeURL)
299 if (!doc->closeURL()) return false;
300
301 TQPtrList<Kate::View> closeList;
302 uint documentNumber = doc->documentNumber();
303
304 for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
305 {
306 KateApp::self()->mainWindow(i)->viewManager()->closeViews(documentNumber);
307 }
308
309 if ( closeURL && m_tempFiles.contains( documentNumber ) )
310 {
311 TQFileInfo fi( m_tempFiles[ documentNumber ].first.path() );
312 if ( fi.lastModified() <= m_tempFiles[ documentNumber ].second /*||
313 KMessageBox::questionYesNo( KateApp::self()->activeMainWindow(),
314 i18n("The supposedly temporary file %1 has been modified. "
315 "Do you want to delete it anyway?").arg(m_tempFiles[ documentNumber ].first.prettyURL()),
316 i18n("Delete File?") ) == KMessageBox::Yes*/ )
317 {
318 TDEIO::del( m_tempFiles[ documentNumber ].first, false, false );
319 kdDebug(13001)<<"Deleted temporary file "<<m_tempFiles[ documentNumber ].first<<endl;
320 m_tempFiles.remove( documentNumber );
321 }
322 else
323 kdWarning(13001)<<"The supposedly temporary file "<<m_tempFiles[ documentNumber ].first.prettyURL()<<" have been modified since loaded, and has not been deleted."<<endl;
324 }
325
326 deleteDoc (doc);
327
328 // never ever empty the whole document list
329 if (m_docList.isEmpty())
330 createDoc ();
331
332 return true;
333}
334
335bool KateDocManager::closeDocument(uint n)
336{
337 return closeDocument(document(n));
338}
339
340bool KateDocManager::closeDocumentWithID(uint id)
341{
342 return closeDocument(documentWithID(id));
343}
344
345bool KateDocManager::closeAllDocuments(bool closeURL)
346{
347 bool res = true;
348
349 TQPtrList<Kate::Document> docs = m_docList;
350
351 for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
352 {
353 KateApp::self()->mainWindow(i)->viewManager()->setViewActivationBlocked(true);
354 }
355
356 while (!docs.isEmpty() && res)
357 if (! closeDocument(docs.at(0),closeURL) )
358 res = false;
359 else
360 docs.remove ((uint)0);
361
362 for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
363 {
364 KateApp::self()->mainWindow(i)->viewManager()->setViewActivationBlocked(false);
365
366 for (uint s=0; s < KateApp::self()->mainWindow(i)->viewManager()->containers()->count(); s++)
367 KateApp::self()->mainWindow(i)->viewManager()->containers()->at(s)->activateView (m_docList.at(0)->documentNumber());
368 }
369
370 return res;
371}
372
373TQPtrList<Kate::Document> KateDocManager::modifiedDocumentList() {
374 TQPtrList<Kate::Document> modified;
375 for (TQPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it) {
376 Kate::Document *doc = it.current();
377 if (doc->isModified()) {
378 modified.append(doc);
379 }
380 }
381 return modified;
382}
383
384
385bool KateDocManager::queryCloseDocuments(KateMainWindow *w)
386{
387 uint docCount = m_docList.count();
388 for (TQPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
389 {
390 Kate::Document *doc = it.current();
391
392 if (doc->url().isEmpty() && doc->isModified())
393 {
394 int msgres=KMessageBox::warningYesNoCancel( w,
395 i18n("<p>The document '%1' has been modified, but not saved."
396 "<p>Do you want to save your changes or discard them?").arg( doc->docName() ),
397 i18n("Close Document"), KStdGuiItem::save(), KStdGuiItem::discard() );
398
399 if (msgres==KMessageBox::Cancel)
400 return false;
401
402 if (msgres==KMessageBox::Yes)
403 {
404 KEncodingFileDialog::Result r=KEncodingFileDialog::getSaveURLAndEncoding(
405 KTextEditor::encodingInterface(doc)->encoding(),TQString::null,TQString::null,w,i18n("Save As"));
406
407 doc->setEncoding( r.encoding );
408
409 if (!r.URLs.isEmpty())
410 {
411 KURL tmp = r.URLs.first();
412
413 if ( !doc->saveAs( tmp ) )
414 return false;
415 }
416 else
417 return false;
418 }
419 }
420 else
421 {
422 if (!doc->queryClose())
423 return false;
424 }
425 }
426
427 // document count changed while queryClose, abort and notify user
428 if (m_docList.count() > docCount)
429 {
430 KMessageBox::information (w,
431 i18n ("New file opened while trying to close Kate, closing aborted."),
432 i18n ("Closing Aborted"));
433 return false;
434 }
435
436 return true;
437}
438
439
440void KateDocManager::saveAll()
441{
442 for (TQPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
443 if ( it.current()->isModified() && it.current()->views().count() )
444 ((Kate::View*)it.current()->views().first())->save();
445}
446
447void KateDocManager::saveDocumentList (TDEConfig* config)
448{
449 TQString prevGrp=config->group();
450 config->setGroup ("Open Documents");
451 TQString grp = config->group();
452
453 config->writeEntry ("Count", m_docList.count());
454
455 int i=0;
456 for ( Kate::Document *doc = m_docList.first(); doc; doc = m_docList.next() )
457 {
458 long docListPos = doc->documentListPosition();
459 config->setGroup(TQString("Document %1").arg((docListPos<0)?i:docListPos));
460 doc->writeSessionConfig(config);
461 config->setGroup(grp);
462
463 i++;
464 }
465
466 config->setGroup(prevGrp);
467}
468
469void KateDocManager::restoreDocumentList (TDEConfig* config)
470{
471 TQString prevGrp=config->group();
472 config->setGroup ("Open Documents");
473 TQString grp = config->group();
474
475 unsigned int count = config->readUnsignedNumEntry("Count", 0);
476
477 if (count == 0)
478 {
479 config->setGroup(prevGrp);
480 return;
481 }
482
483 TQProgressDialog *pd = new TQProgressDialog(
484 i18n("Reopening files from the last session..."),
485 TQString::null,
486 count,
487 0,
488 "openprog");
489
490 KWin::setOnDesktop(pd->winId(), KWin::currentDesktop());
491 pd->setCaption (KateApp::self()->makeStdCaption(i18n("Starting Up")));
492
493 bool first = true;
494 for (unsigned int i=0; i < count; i++)
495 {
496 config->setGroup(TQString("Document %1").arg(i));
497 Kate::Document *doc = 0;
498
499 if (first)
500 {
501 first = false;
502 doc = document (0);
503 }
504 else
505 doc = createDoc ();
506
507 doc->readSessionConfig(config);
508 config->setGroup (grp);
509
510 pd->setProgress(pd->progress()+1);
511 KateApp::self()->processEvents();
512 }
513
514 delete pd;
515
516 config->setGroup(prevGrp);
517}
518
519void KateDocManager::slotModifiedOnDisc (Kate::Document *doc, bool b, unsigned char reason)
520{
521 if (m_docInfos[doc])
522 {
523 m_docInfos[doc]->modifiedOnDisc = b;
524 m_docInfos[doc]->modifiedOnDiscReason = reason;
525 }
526}
527
528void KateDocManager::slotModChanged(Kate::Document *doc)
529{
530 saveMetaInfos(doc);
531}
532
536bool KateDocManager::loadMetaInfos(Kate::Document *doc, const KURL &url)
537{
538 if (!m_saveMetaInfos)
539 return false;
540
541 if (!m_metaInfos->hasGroup(url.prettyURL()))
542 return false;
543
544 TQCString md5;
545 bool ok = true;
546
547 if (computeUrlMD5(url, md5))
548 {
549 m_metaInfos->setGroup(url.prettyURL());
550 TQString old_md5 = m_metaInfos->readEntry("MD5");
551
552 if ((const char *)md5 == old_md5)
553 doc->readSessionConfig(m_metaInfos);
554 else
555 {
556 m_metaInfos->deleteGroup(url.prettyURL());
557 ok = false;
558 }
559
560 m_metaInfos->sync();
561 }
562
563 return ok && doc->url() == url;
564}
565
569void KateDocManager::saveMetaInfos(Kate::Document *doc)
570{
571 TQCString md5;
572
573 if (!m_saveMetaInfos)
574 return;
575
576 if (doc->isModified())
577 {
578// kdDebug (13020) << "DOC MODIFIED: no meta data saved" << endl;
579 return;
580 }
581
582 if (computeUrlMD5(doc->url(), md5))
583 {
584 m_metaInfos->setGroup(doc->url().prettyURL());
585 doc->writeSessionConfig(m_metaInfos);
586 m_metaInfos->writeEntry("MD5", (const char *)md5);
587 m_metaInfos->writeEntry("Time", TQDateTime::currentDateTime());
588 m_metaInfos->sync();
589 }
590}
591
592bool KateDocManager::computeUrlMD5(const KURL &url, TQCString &result)
593{
594 TQFile f(url.path());
595
596 if (f.open(IO_ReadOnly))
597 {
598 KMD5 md5;
599
600 if (!md5.update(f))
601 return false;
602
603 md5.hexDigest(result);
604 f.close();
605 }
606 else
607 return false;
608
609 return true;
610}
KateApp::mainWindow
KateMainWindow * mainWindow(uint n)
give back the window you want
Definition: kateapp.cpp:475
KateApp::self
static KateApp * self()
static accessor to avoid casting ;)
Definition: kateapp.cpp:114
KateApp::documentManager
KateDocManager * documentManager()
accessor to document manager
Definition: kateapp.cpp:372
KateApp::mainWindows
uint mainWindows() const
give back number of existing main windows
Definition: kateapp.cpp:470
Kate::DocumentManager
This interface provides access to the Kate Document Manager.
Definition: documentmanager.h:30

kate

Skip menu "kate"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kate

Skip menu "kate"
  • kate
  • libkonq
  • twin
  •   lib
Generated for kate by doxygen 1.9.4
This website is maintained by Timothy Pearson.