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

kate

katedocmanager.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
00003    Copyright (C) 2002 Joseph Wenninger <jowenn@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License version 2 as published by the Free Software Foundation.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "katedocmanager.h"
00021 #include "katedocmanager.moc"
00022 #include "kateapp.h"
00023 #include "katemainwindow.h"
00024 #include "kateviewmanager.h"
00025 #include "katedocmanageriface.h"
00026 #include "kateexternaltools.h"
00027 #include "kateviewspacecontainer.h"
00028 
00029 #include <kate/view.h>
00030 
00031 #include <tdetexteditor/encodinginterface.h>
00032 
00033 #include <tdeparts/factory.h>
00034 
00035 #include <tdelocale.h>
00036 #include <kdebug.h>
00037 #include <tdeconfig.h>
00038 #include <klibloader.h>
00039 #include <kmdcodec.h>
00040 #include <tdemessagebox.h>
00041 #include <kencodingfiledialog.h>
00042 #include <tdeio/job.h>
00043 #include <twin.h>
00044 
00045 #include <tqdatetime.h>
00046 #include <tqtextcodec.h>
00047 #include <tqprogressdialog.h>
00048 
00049 KateDocManager::KateDocManager (TQObject *parent)
00050  : TQObject (parent)
00051  , m_saveMetaInfos(true)
00052  , m_daysMetaInfos(0)
00053 {
00054   m_factory = (KParts::Factory *) KLibLoader::self()->factory ("libkatepart");
00055 
00056   m_documentManager = new Kate::DocumentManager (this);
00057   m_docList.setAutoDelete(true);
00058   m_docDict.setAutoDelete(false);
00059   m_docInfos.setAutoDelete(true);
00060 
00061   m_dcop = new KateDocManagerDCOPIface (this);
00062 
00063   m_metaInfos = new TDEConfig("metainfos", false, false, "appdata");
00064 
00065   createDoc ();
00066 }
00067 
00068 KateDocManager::~KateDocManager ()
00069 {
00070   // save config
00071   if (!m_docList.isEmpty())
00072     m_docList.at(0)->writeConfig(KateApp::self()->config());
00073 
00074   if (m_saveMetaInfos)
00075   {
00076     // saving meta-infos when file is saved is not enough, we need to do it once more at the end
00077     for (Kate::Document *doc = m_docList.first(); doc; doc = m_docList.next())
00078       saveMetaInfos(doc);
00079 
00080     // purge saved filesessions
00081     if (m_daysMetaInfos > 0)
00082     {
00083       TQStringList groups = m_metaInfos->groupList();
00084       TQDateTime *def = new TQDateTime(TQDate(1970, 1, 1));
00085       for (TQStringList::Iterator it = groups.begin(); it != groups.end(); ++it)
00086       {
00087         m_metaInfos->setGroup(*it);
00088         TQDateTime last = m_metaInfos->readDateTimeEntry("Time", def);
00089         if (last.daysTo(TQDateTime::currentDateTime()) > m_daysMetaInfos)
00090           m_metaInfos->deleteGroup(*it);
00091       }
00092       delete def;
00093     }
00094   }
00095 
00096   delete m_dcop;
00097   delete m_metaInfos;
00098 }
00099 
00100 KateDocManager *KateDocManager::self ()
00101 {
00102   return KateApp::self()->documentManager ();
00103 }
00104 
00105 Kate::Document *KateDocManager::createDoc ()
00106 {
00107   KTextEditor::Document *doc = (KTextEditor::Document *) m_factory->createPart (0, "", this, "", "KTextEditor::Document");
00108 
00109   m_docList.append((Kate::Document *)doc);
00110   m_docDict.insert (doc->documentNumber(), (Kate::Document *)doc);
00111   m_docInfos.insert (doc, new KateDocumentInfo ());
00112 
00113   if (m_docList.count() < 2)
00114     ((Kate::Document *)doc)->readConfig(KateApp::self()->config());
00115 
00116   emit documentCreated ((Kate::Document *)doc);
00117   emit m_documentManager->documentCreated ((Kate::Document *)doc);
00118 
00119   connect(doc,TQT_SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)),this,TQT_SLOT(slotModifiedOnDisc(Kate::Document *, bool, unsigned char)));
00120   return (Kate::Document *)doc;
00121 }
00122 
00123 void KateDocManager::deleteDoc (Kate::Document *doc)
00124 {
00125   uint id = doc->documentNumber();
00126   uint activeId = 0;
00127   if (m_currentDoc)
00128     activeId = m_currentDoc->documentNumber ();
00129 
00130   if (m_docList.count() < 2)
00131     doc->writeConfig(KateApp::self()->config());
00132 
00133   m_docInfos.remove (doc);
00134   m_docDict.remove (id);
00135   m_docList.remove (doc);
00136 
00137   emit documentDeleted (id);
00138   emit m_documentManager->documentDeleted (id);
00139 
00140   // ohh, current doc was deleted
00141   if (activeId == id)
00142   {
00143     // special case of documentChanged, no longer any doc here !
00144     m_currentDoc = 0;
00145 
00146     emit documentChanged ();
00147     emit m_documentManager->documentChanged ();
00148   }
00149 }
00150 
00151 Kate::Document *KateDocManager::document (uint n)
00152 {
00153   return m_docList.at(n);
00154 }
00155 
00156 Kate::Document *KateDocManager::activeDocument ()
00157 {
00158   return m_currentDoc;
00159 }
00160 
00161 void KateDocManager::setActiveDocument (Kate::Document *doc)
00162 {
00163   if (!doc)
00164     return;
00165 
00166   if (m_currentDoc && (m_currentDoc->documentNumber() == doc->documentNumber()))
00167     return;
00168 
00169   m_currentDoc = doc;
00170 
00171   emit documentChanged ();
00172   emit m_documentManager->documentChanged ();
00173 }
00174 
00175 Kate::Document *KateDocManager::firstDocument ()
00176 {
00177   return m_docList.first();
00178 }
00179 
00180 Kate::Document *KateDocManager::nextDocument ()
00181 {
00182   return m_docList.next();
00183 }
00184 
00185 Kate::Document *KateDocManager::documentWithID (uint id)
00186 {
00187   return m_docDict[id];
00188 }
00189 
00190 const KateDocumentInfo *KateDocManager::documentInfo (Kate::Document *doc)
00191 {
00192   return m_docInfos[doc];
00193 }
00194 
00195 int KateDocManager::findDocument (Kate::Document *doc)
00196 {
00197   return m_docList.find (doc);
00198 }
00199 
00200 uint KateDocManager::documents ()
00201 {
00202   return m_docList.count ();
00203 }
00204 
00205 int KateDocManager::findDocument ( KURL url )
00206 {
00207   TQPtrListIterator<Kate::Document> it(m_docList);
00208 
00209   for (; it.current(); ++it)
00210   {
00211     if ( it.current()->url() == url)
00212       return it.current()->documentNumber();
00213   }
00214   return -1;
00215 }
00216 
00217 Kate::Document *KateDocManager::findDocumentByUrl( KURL url )
00218 {
00219   for (TQPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
00220   {
00221     if ( it.current()->url() == url)
00222       return it.current();
00223   }
00224 
00225   return 0L;
00226 }
00227 
00228 bool KateDocManager::isOpen(KURL url)
00229 {
00230   // return just if we found some document with this url
00231   return findDocumentByUrl (url) != 0;
00232 }
00233 
00234 Kate::Document *KateDocManager::openURL (const KURL& url,const TQString &encoding, uint *id, bool isTempFile)
00235 {
00236   // special handling if still only the first initial doc is there
00237   if (!documentList().isEmpty() && (documentList().count() == 1) && (!documentList().at(0)->isModified() && documentList().at(0)->url().isEmpty()))
00238   {
00239     Kate::Document* doc = documentList().getFirst();
00240 
00241     doc->setEncoding(encoding);
00242 
00243     if (!loadMetaInfos(doc, url))
00244       doc->openURL (url);
00245 
00246     if (id)
00247       *id=doc->documentNumber();
00248 
00249     if ( isTempFile && !url.isEmpty() && url.isLocalFile() )
00250     {
00251       TQFileInfo fi( url.path() );
00252       if ( fi.exists() )
00253       {
00254         m_tempFiles[ doc->documentNumber() ] = qMakePair(url, fi.lastModified());
00255         kdDebug(13001)<<"temporary file will be deleted after use unless modified: "<<url.prettyURL()<<endl;
00256       }
00257     }
00258 
00259     connect(doc, TQT_SIGNAL(modStateChanged(Kate::Document *)), this, TQT_SLOT(slotModChanged(Kate::Document *)));
00260 
00261     emit initialDocumentReplaced();
00262 
00263     return doc;
00264   }
00265 
00266   Kate::Document *doc = findDocumentByUrl (url);
00267   if ( !doc )
00268   {
00269     doc = (Kate::Document *)createDoc ();
00270 
00271     doc->setEncoding(encoding.isNull() ? Kate::Document::defaultEncoding() : encoding);
00272 
00273     if (!loadMetaInfos(doc, url))
00274       doc->openURL (url);
00275   }
00276 
00277   if (id)
00278     *id=doc->documentNumber();
00279 
00280   if ( isTempFile && !url.isEmpty() && url.isLocalFile() )
00281   {
00282     TQFileInfo fi( url.path() );
00283     if ( fi.exists() )
00284     {
00285       m_tempFiles[ doc->documentNumber() ] = qMakePair(url, fi.lastModified());
00286       kdDebug(13001)<<"temporary file will be deleted after use unless modified: "<<url.prettyURL()<<endl;
00287     }
00288   }
00289 
00290   return doc;
00291 }
00292 
00293 bool KateDocManager::closeDocument(class Kate::Document *doc,bool closeURL)
00294 {
00295   if (!doc) return false;
00296 
00297   saveMetaInfos(doc);
00298   if (closeURL)
00299   if (!doc->closeURL()) return false;
00300 
00301   TQPtrList<Kate::View> closeList;
00302   uint documentNumber = doc->documentNumber();
00303 
00304   for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
00305   {
00306     KateApp::self()->mainWindow(i)->viewManager()->closeViews(documentNumber);
00307   }
00308 
00309   if ( closeURL && m_tempFiles.contains( documentNumber ) )
00310   {
00311     TQFileInfo fi( m_tempFiles[ documentNumber ].first.path() );
00312     if ( fi.lastModified() <= m_tempFiles[ documentNumber ].second /*||
00313          KMessageBox::questionYesNo( KateApp::self()->activeMainWindow(),
00314             i18n("The supposedly temporary file %1 has been modified. "
00315                 "Do you want to delete it anyway?").arg(m_tempFiles[ documentNumber ].first.prettyURL()),
00316             i18n("Delete File?") ) == KMessageBox::Yes*/ )
00317     {
00318       TDEIO::del( m_tempFiles[ documentNumber ].first, false, false );
00319       kdDebug(13001)<<"Deleted temporary file "<<m_tempFiles[ documentNumber ].first<<endl;
00320       m_tempFiles.remove( documentNumber );
00321     }
00322     else
00323       kdWarning(13001)<<"The supposedly temporary file "<<m_tempFiles[ documentNumber ].first.prettyURL()<<" have been modified since loaded, and has not been deleted."<<endl;
00324   }
00325 
00326   deleteDoc (doc);
00327 
00328   // never ever empty the whole document list
00329   if (m_docList.isEmpty())
00330     createDoc ();
00331 
00332   return true;
00333 }
00334 
00335 bool KateDocManager::closeDocument(uint n)
00336 {
00337   return closeDocument(document(n));
00338 }
00339 
00340 bool KateDocManager::closeDocumentWithID(uint id)
00341 {
00342   return closeDocument(documentWithID(id));
00343 }
00344 
00345 bool KateDocManager::closeAllDocuments(bool closeURL)
00346 {
00347   bool res = true;
00348 
00349   TQPtrList<Kate::Document> docs = m_docList;
00350 
00351   for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
00352   {
00353     KateApp::self()->mainWindow(i)->viewManager()->setViewActivationBlocked(true);
00354   }
00355 
00356   while (!docs.isEmpty() && res)
00357     if (! closeDocument(docs.at(0),closeURL) )
00358       res = false;
00359     else
00360       docs.remove ((uint)0);
00361 
00362   for (uint i=0; i < KateApp::self()->mainWindows (); i++ )
00363   {
00364     KateApp::self()->mainWindow(i)->viewManager()->setViewActivationBlocked(false);
00365 
00366     for (uint s=0; s < KateApp::self()->mainWindow(i)->viewManager()->containers()->count(); s++)
00367       KateApp::self()->mainWindow(i)->viewManager()->containers()->at(s)->activateView (m_docList.at(0)->documentNumber());
00368   }
00369 
00370   return res;
00371 }
00372 
00373 TQPtrList<Kate::Document> KateDocManager::modifiedDocumentList() {
00374   TQPtrList<Kate::Document> modified;
00375   for (TQPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it) {
00376     Kate::Document *doc = it.current();
00377     if (doc->isModified()) {
00378       modified.append(doc);
00379     }
00380   }
00381   return modified;
00382 }
00383 
00384 
00385 bool KateDocManager::queryCloseDocuments(KateMainWindow *w)
00386 {
00387   uint docCount = m_docList.count();
00388   for (TQPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
00389   {
00390     Kate::Document *doc = it.current();
00391 
00392     if (doc->url().isEmpty() && doc->isModified())
00393     {
00394       int msgres=KMessageBox::warningYesNoCancel( w,
00395                   i18n("<p>The document '%1' has been modified, but not saved."
00396                        "<p>Do you want to save your changes or discard them?").arg( doc->docName() ),
00397                     i18n("Close Document"), KStdGuiItem::save(), KStdGuiItem::discard() );
00398 
00399       if (msgres==KMessageBox::Cancel)
00400         return false;
00401 
00402       if (msgres==KMessageBox::Yes)
00403       {
00404         KEncodingFileDialog::Result r=KEncodingFileDialog::getSaveURLAndEncoding(
00405               KTextEditor::encodingInterface(doc)->encoding(),TQString::null,TQString::null,w,i18n("Save As"));
00406 
00407         doc->setEncoding( r.encoding );
00408 
00409         if (!r.URLs.isEmpty())
00410         {
00411           KURL tmp = r.URLs.first();
00412 
00413           if ( !doc->saveAs( tmp ) )
00414             return false;
00415         }
00416         else
00417           return false;
00418       }
00419     }
00420     else
00421     {
00422       if (!doc->queryClose())
00423         return false;
00424     }
00425   }
00426 
00427   // document count changed while queryClose, abort and notify user
00428   if (m_docList.count() > docCount)
00429   {
00430     KMessageBox::information (w,
00431                           i18n ("New file opened while trying to close Kate, closing aborted."),
00432                           i18n ("Closing Aborted"));
00433     return false;
00434   }
00435 
00436   return true;
00437 }
00438 
00439 
00440 void KateDocManager::saveAll()
00441 {
00442   for (TQPtrListIterator<Kate::Document> it(m_docList); it.current(); ++it)
00443     if ( it.current()->isModified() && it.current()->views().count() )
00444       ((Kate::View*)it.current()->views().first())->save();
00445 }
00446 
00447 void KateDocManager::saveDocumentList (TDEConfig* config)
00448 {
00449   TQString prevGrp=config->group();
00450   config->setGroup ("Open Documents");
00451   TQString grp = config->group();
00452 
00453   config->writeEntry ("Count", m_docList.count());
00454 
00455   int i=0;
00456   for ( Kate::Document *doc = m_docList.first(); doc; doc = m_docList.next() )
00457   {
00458     long docListPos = doc->documentListPosition();
00459     config->setGroup(TQString("Document %1").arg((docListPos<0)?i:docListPos));
00460     doc->writeSessionConfig(config);
00461     config->setGroup(grp);
00462 
00463     i++;
00464   }
00465 
00466   config->setGroup(prevGrp);
00467 }
00468 
00469 void KateDocManager::restoreDocumentList (TDEConfig* config)
00470 {
00471   TQString prevGrp=config->group();
00472   config->setGroup ("Open Documents");
00473   TQString grp = config->group();
00474 
00475   unsigned int count = config->readUnsignedNumEntry("Count", 0);
00476 
00477   if (count == 0)
00478   {
00479     config->setGroup(prevGrp);
00480     return;
00481   }
00482 
00483   TQProgressDialog *pd = new TQProgressDialog(
00484         i18n("Reopening files from the last session..."),
00485         TQString::null,
00486         count,
00487         0,
00488         "openprog");
00489   
00490   KWin::setOnDesktop(pd->winId(), KWin::currentDesktop());
00491   pd->setCaption (KateApp::self()->makeStdCaption(i18n("Starting Up")));
00492 
00493   bool first = true;
00494   for (unsigned int i=0; i < count; i++)
00495   {
00496     config->setGroup(TQString("Document %1").arg(i));
00497     Kate::Document *doc = 0;
00498 
00499     if (first)
00500     {
00501       first = false;
00502       doc = document (0);
00503     }
00504     else
00505       doc = createDoc ();
00506 
00507     doc->readSessionConfig(config);
00508     config->setGroup (grp);
00509 
00510     pd->setProgress(pd->progress()+1);
00511     KateApp::self()->processEvents();
00512   }
00513 
00514   delete pd;
00515 
00516   config->setGroup(prevGrp);
00517 }
00518 
00519 void KateDocManager::slotModifiedOnDisc (Kate::Document *doc, bool b, unsigned char reason)
00520 {
00521   if (m_docInfos[doc])
00522   {
00523     m_docInfos[doc]->modifiedOnDisc = b;
00524     m_docInfos[doc]->modifiedOnDiscReason = reason;
00525   }
00526 }
00527 
00528 void KateDocManager::slotModChanged(Kate::Document *doc)
00529 {
00530   saveMetaInfos(doc);
00531 }
00532 
00536 bool KateDocManager::loadMetaInfos(Kate::Document *doc, const KURL &url)
00537 {
00538   if (!m_saveMetaInfos)
00539     return false;
00540 
00541   if (!m_metaInfos->hasGroup(url.prettyURL()))
00542     return false;
00543 
00544   TQCString md5;
00545   bool ok = true;
00546 
00547   if (computeUrlMD5(url, md5))
00548   {
00549     m_metaInfos->setGroup(url.prettyURL());
00550     TQString old_md5 = m_metaInfos->readEntry("MD5");
00551 
00552     if ((const char *)md5 == old_md5)
00553       doc->readSessionConfig(m_metaInfos);
00554     else
00555     {
00556       m_metaInfos->deleteGroup(url.prettyURL());
00557       ok = false;
00558     }
00559 
00560     m_metaInfos->sync();
00561   }
00562 
00563   return ok && doc->url() == url;
00564 }
00565 
00569 void KateDocManager::saveMetaInfos(Kate::Document *doc)
00570 {
00571   TQCString md5;
00572 
00573   if (!m_saveMetaInfos)
00574     return;
00575 
00576   if (doc->isModified())
00577   {
00578 //     kdDebug (13020) << "DOC MODIFIED: no meta data saved" << endl;
00579     return;
00580   }
00581 
00582   if (computeUrlMD5(doc->url(), md5))
00583   {
00584     m_metaInfos->setGroup(doc->url().prettyURL());
00585     doc->writeSessionConfig(m_metaInfos);
00586     m_metaInfos->writeEntry("MD5", (const char *)md5);
00587     m_metaInfos->writeEntry("Time", TQDateTime::currentDateTime());
00588     m_metaInfos->sync();
00589   }
00590 }
00591 
00592 bool KateDocManager::computeUrlMD5(const KURL &url, TQCString &result)
00593 {
00594   TQFile f(url.path());
00595 
00596   if (f.open(IO_ReadOnly))
00597   {
00598     KMD5 md5;
00599 
00600     if (!md5.update(TQT_TQIODEVICE_OBJECT(f)))
00601       return false;
00602 
00603     md5.hexDigest(result);
00604     f.close();
00605   }
00606   else
00607     return false;
00608 
00609   return true;
00610 }
00611 
00612 // kate: space-indent on; indent-width 2; replace-tabs on;

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.7.1
This website is maintained by Timothy Pearson.