krecentdocument.cpp
00001 /* -*- c++ -*- 00002 * Copyright (C)2000 Daniel M. Duley <mosfet@kde.org> 00003 * 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 00016 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 00019 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00021 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00022 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00023 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00024 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00025 * SUCH DAMAGE. 00026 * 00027 */ 00028 #include <krecentdocument.h> 00029 #include <ksimpleconfig.h> 00030 #include <kstandarddirs.h> 00031 #include <kapplication.h> 00032 #include <kurl.h> 00033 #include <kdebug.h> 00034 #include <kmimetype.h> 00035 #include <kdesktopfile.h> 00036 #include <qdir.h> 00037 #include <qfileinfo.h> 00038 #include <qtextstream.h> 00039 #include <qstringlist.h> 00040 #include <qregexp.h> 00041 00042 #include <sys/types.h> 00043 #include <utime.h> 00044 00045 QString KRecentDocument::recentDocumentDirectory() 00046 { 00047 // need to change this path, not sure where 00048 return locateLocal("data", QString::fromLatin1("RecentDocuments/")); 00049 } 00050 00051 QStringList KRecentDocument::recentDocuments() 00052 { 00053 QDir d(recentDocumentDirectory(), "*.desktop", QDir::Time, 00054 QDir::Files | QDir::Readable | QDir::Hidden); 00055 00056 if (!d.exists()) 00057 d.mkdir(recentDocumentDirectory()); 00058 00059 QStringList list = d.entryList(); 00060 QStringList fullList; 00061 00062 for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { 00063 QString pathDesktop = d.absFilePath( *it ); 00064 KDesktopFile tmpDesktopFile( pathDesktop, false); 00065 KURL urlDesktopFile(tmpDesktopFile.readURL()); 00066 if( urlDesktopFile.isLocalFile() && !QFile(urlDesktopFile.path()).exists()) 00067 d.remove(pathDesktop); 00068 else 00069 fullList.append( pathDesktop ); 00070 } 00071 00072 return fullList; 00073 } 00074 00075 void KRecentDocument::add(const KURL& url) 00076 { 00077 KRecentDocument::add(url, qApp->argv()[0]); // ### argv[0] might not match the service filename! 00078 } 00079 00080 void KRecentDocument::add(const KURL& url, const QString& desktopEntryName) 00081 { 00082 if ( url.isLocalFile() && !KGlobal::dirs()->relativeLocation("tmp", url.path()).startsWith("/")) 00083 return; 00084 00085 QString openStr = url.url(); 00086 openStr.replace( QRegExp("\\$"), "$$" ); // Desktop files with type "Link" are $-variable expanded 00087 00088 kdDebug(250) << "KRecentDocument::add for " << openStr << endl; 00089 KConfig *config = KGlobal::config(); 00090 QString oldGrp = config->group(); 00091 config->setGroup(QString::fromLatin1("RecentDocuments")); 00092 bool useRecent = config->readBoolEntry(QString::fromLatin1("UseRecent"), true); 00093 int maxEntries = config->readNumEntry(QString::fromLatin1("MaxEntries"), 10); 00094 00095 config->setGroup(oldGrp); 00096 if(!useRecent) 00097 return; 00098 00099 QString path = recentDocumentDirectory(); 00100 00101 QString dStr = path + url.fileName(); 00102 00103 QString ddesktop = dStr + QString::fromLatin1(".desktop"); 00104 00105 int i=1; 00106 // check for duplicates 00107 while(QFile::exists(ddesktop)){ 00108 // see if it points to the same file and application 00109 KSimpleConfig tmp(ddesktop); 00110 tmp.setDesktopGroup(); 00111 if(tmp.readEntry(QString::fromLatin1("X-KDE-LastOpenedWith")) 00112 == desktopEntryName) 00113 { 00114 utime(QFile::encodeName(ddesktop), NULL); 00115 return; 00116 } 00117 // if not append a (num) to it 00118 ++i; 00119 if ( i > maxEntries ) 00120 break; 00121 ddesktop = dStr + QString::fromLatin1("[%1].desktop").arg(i); 00122 } 00123 00124 QDir dir(path); 00125 // check for max entries, delete oldest files if exceeded 00126 QStringList list = dir.entryList(QDir::Files | QDir::Hidden, QDir::Time | QDir::Reversed); 00127 i = list.count(); 00128 if(i > maxEntries-1){ 00129 QStringList::Iterator it; 00130 it = list.begin(); 00131 while(i > maxEntries-1){ 00132 QFile::remove(dir.absPath() + QString::fromLatin1("/") + (*it)); 00133 --i, ++it; 00134 } 00135 } 00136 00137 // create the applnk 00138 KSimpleConfig conf(ddesktop); 00139 conf.setDesktopGroup(); 00140 conf.writeEntry( QString::fromLatin1("Type"), QString::fromLatin1("Link") ); 00141 conf.writePathEntry( QString::fromLatin1("URL"), openStr ); 00142 // If you change the line below, change the test in the above loop 00143 conf.writeEntry( QString::fromLatin1("X-KDE-LastOpenedWith"), desktopEntryName ); 00144 QString name = url.fileName(); 00145 if (name.isEmpty()) 00146 name = openStr; 00147 conf.writeEntry( QString::fromLatin1("Name"), name ); 00148 conf.writeEntry( QString::fromLatin1("Icon"), KMimeType::iconForURL( url ) ); 00149 } 00150 00151 void KRecentDocument::add(const QString &openStr, bool isUrl) 00152 { 00153 if( isUrl ) { 00154 add( KURL( openStr ) ); 00155 } else { 00156 KURL url; 00157 url.setPath( openStr ); 00158 add( url ); 00159 } 00160 } 00161 00162 void KRecentDocument::clear() 00163 { 00164 QStringList list = recentDocuments(); 00165 QDir dir; 00166 for(QStringList::Iterator it = list.begin(); it != list.end() ; ++it) 00167 dir.remove(*it); 00168 } 00169 00170 int KRecentDocument::maximumItems() 00171 { 00172 KConfig *config = KGlobal::config(); 00173 KConfigGroupSaver sa(config, QString::fromLatin1("RecentDocuments")); 00174 return config->readNumEntry(QString::fromLatin1("MaxEntries"), 10); 00175 } 00176 00177