autostart.cpp
00001 /* 00002 * 00003 * This file is part of the KDE libraries 00004 * Copyright (c) 2001 Waldo Bastian <bastian@kde.org> 00005 * 00006 * $Id: autostart.cpp 534738 2006-04-27 18:04:45Z lunakl $ 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Library General Public 00010 * License version 2 as published by the Free Software Foundation. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Library General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Library General Public License 00018 * along with this library; see the file COPYING.LIB. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 * Boston, MA 02110-1301, USA. 00021 **/ 00022 00023 #include "autostart.h" 00024 00025 #include <kconfig.h> 00026 #include <kdesktopfile.h> 00027 #include <kglobal.h> 00028 #include <kstandarddirs.h> 00029 00030 class AutoStartItem 00031 { 00032 public: 00033 QString name; 00034 QString service; 00035 QString startAfter; 00036 int phase; 00037 }; 00038 00039 class AutoStartList: public QPtrList<AutoStartItem> 00040 { 00041 public: 00042 AutoStartList() { } 00043 }; 00044 00045 AutoStart::AutoStart( bool new_startup ) 00046 : m_newStartup( new_startup ), m_phase( new_startup ? -1 : 0), m_phasedone(false) 00047 { 00048 m_startList = new AutoStartList; 00049 m_startList->setAutoDelete(true); 00050 KGlobal::dirs()->addResourceType("autostart", "share/autostart"); 00051 } 00052 00053 AutoStart::~AutoStart() 00054 { 00055 delete m_startList; 00056 } 00057 00058 void 00059 AutoStart::setPhase(int phase) 00060 { 00061 if (phase > m_phase) 00062 { 00063 m_phase = phase; 00064 m_phasedone = false; 00065 } 00066 } 00067 00068 void AutoStart::setPhaseDone() 00069 { 00070 m_phasedone = true; 00071 } 00072 00073 static QString extractName(QString path) 00074 { 00075 int i = path.findRev('/'); 00076 if (i >= 0) 00077 path = path.mid(i+1); 00078 i = path.findRev('.'); 00079 if (i >= 0) 00080 path = path.left(i); 00081 return path; 00082 } 00083 00084 static bool startCondition(const QString &condition) 00085 { 00086 if (condition.isEmpty()) 00087 return true; 00088 00089 QStringList list = QStringList::split(':', condition, true); 00090 if (list.count() < 4) 00091 return true; 00092 if (list[0].isEmpty() || list[2].isEmpty()) 00093 return true; 00094 00095 KConfig config(list[0], true, false); 00096 if (!list[1].isEmpty()) 00097 config.setGroup(list[1]); 00098 00099 bool defaultValue = (list[3].lower() == "true"); 00100 00101 return config.readBoolEntry(list[2], defaultValue); 00102 } 00103 00104 void 00105 AutoStart::loadAutoStartList() 00106 { 00107 QStringList files = KGlobal::dirs()->findAllResources("autostart", "*.desktop", false, true); 00108 00109 for(QStringList::ConstIterator it = files.begin(); 00110 it != files.end(); 00111 ++it) 00112 { 00113 KDesktopFile config(*it, true); 00114 if (!startCondition(config.readEntry("X-KDE-autostart-condition"))) 00115 continue; 00116 if (!config.tryExec()) 00117 continue; 00118 if (config.readBoolEntry("Hidden", false)) 00119 continue; 00120 00121 if (config.hasKey("OnlyShowIn")) 00122 { 00123 if (!config.readListEntry("OnlyShowIn", ';').contains("KDE")) 00124 continue; 00125 } 00126 if (config.hasKey("NotShowIn")) 00127 { 00128 if (config.readListEntry("NotShowIn", ';').contains("KDE")) 00129 continue; 00130 } 00131 00132 AutoStartItem *item = new AutoStartItem; 00133 item->name = extractName(*it); 00134 item->service = *it; 00135 item->startAfter = config.readEntry("X-KDE-autostart-after"); 00136 if( m_newStartup ) 00137 { 00138 item->phase = config.readNumEntry("X-KDE-autostart-phase", 2); 00139 if (item->phase < 0) 00140 item->phase = 0; 00141 } 00142 else 00143 { 00144 item->phase = config.readNumEntry("X-KDE-autostart-phase", 1); 00145 if (item->phase < 1) 00146 item->phase = 1; 00147 } 00148 m_startList->append(item); 00149 } 00150 } 00151 00152 QString 00153 AutoStart::startService() 00154 { 00155 if (m_startList->isEmpty()) 00156 return 0; 00157 00158 while(!m_started.isEmpty()) 00159 { 00160 00161 // Check for items that depend on previously started items 00162 QString lastItem = m_started[0]; 00163 for(AutoStartItem *item = m_startList->first(); 00164 item; item = m_startList->next()) 00165 { 00166 if (item->phase == m_phase 00167 && item->startAfter == lastItem) 00168 { 00169 m_started.prepend(item->name); 00170 QString service = item->service; 00171 m_startList->remove(); 00172 return service; 00173 } 00174 } 00175 m_started.remove(m_started.begin()); 00176 } 00177 00178 // Check for items that don't depend on anything 00179 AutoStartItem *item; 00180 for(item = m_startList->first(); 00181 item; item = m_startList->next()) 00182 { 00183 if (item->phase == m_phase 00184 && item->startAfter.isEmpty()) 00185 { 00186 m_started.prepend(item->name); 00187 QString service = item->service; 00188 m_startList->remove(); 00189 return service; 00190 } 00191 } 00192 00193 // Just start something in this phase 00194 for(item = m_startList->first(); 00195 item; item = m_startList->next()) 00196 { 00197 if (item->phase == m_phase) 00198 { 00199 m_started.prepend(item->name); 00200 QString service = item->service; 00201 m_startList->remove(); 00202 return service; 00203 } 00204 } 00205 00206 return 0; 00207 }

