• 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 
49 KateDocManager::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 
68 KateDocManager::~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 
100 KateDocManager *KateDocManager::self ()
101 {
102  return KateApp::self()->documentManager ();
103 }
104 
105 Kate::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 
123 void 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 
151 Kate::Document *KateDocManager::document (uint n)
152 {
153  return m_docList.at(n);
154 }
155 
156 Kate::Document *KateDocManager::activeDocument ()
157 {
158  return m_currentDoc;
159 }
160 
161 void 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 
175 Kate::Document *KateDocManager::firstDocument ()
176 {
177  return m_docList.first();
178 }
179 
180 Kate::Document *KateDocManager::nextDocument ()
181 {
182  return m_docList.next();
183 }
184 
185 Kate::Document *KateDocManager::documentWithID (uint id)
186 {
187  return m_docDict[id];
188 }
189 
190 const KateDocumentInfo *KateDocManager::documentInfo (Kate::Document *doc)
191 {
192  return m_docInfos[doc];
193 }
194 
195 int KateDocManager::findDocument (Kate::Document *doc)
196 {
197  return m_docList.find (doc);
198 }
199 
200 uint KateDocManager::documents ()
201 {
202  return m_docList.count ();
203 }
204 
205 int 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 
217 Kate::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 
228 bool KateDocManager::isOpen(KURL url)
229 {
230  // return just if we found some document with this url
231  return findDocumentByUrl (url) != 0;
232 }
233 
234 Kate::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 
293 bool 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 
335 bool KateDocManager::closeDocument(uint n)
336 {
337  return closeDocument(document(n));
338 }
339 
340 bool KateDocManager::closeDocumentWithID(uint id)
341 {
342  return closeDocument(documentWithID(id));
343 }
344 
345 bool 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 
373 TQPtrList<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 
385 bool 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 
440 void 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 
447 void 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 
469 void 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 
519 void 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 
528 void KateDocManager::slotModChanged(Kate::Document *doc)
529 {
530  saveMetaInfos(doc);
531 }
532 
536 bool 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 
569 void 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 
592 bool 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.1
This website is maintained by Timothy Pearson.