1/***************************************************************************
2 * Copyright (C) 2008 by Montel Laurent <montel@kde.org> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program 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 *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
18 ***************************************************************************/
19
20#include "katesessionapplet.h"
21#include <QStyleOptionGraphicsItem>
22#include <QTreeView>
23#include <QVBoxLayout>
24#include <QGraphicsGridLayout>
25#include <KStandardDirs>
26#include <KIconLoader>
27#include <KInputDialog>
28#include <KMessageBox>
29#include <KStandardGuiItem>
30#include <QGraphicsProxyWidget>
31#include <QListWidgetItem>
32#include <QStandardItemModel>
33#include <KIcon>
34#include <KToolInvocation>
35#include <KDirWatch>
36#include <QGraphicsLinearLayout>
37#include <KGlobalSettings>
38#include <KUrl>
39#include <KStringHandler>
40#include <QFile>
41#include <KConfigDialog>
42
43
44bool katesessions_compare_sessions(const QString &s1, const QString &s2) {
45 return KStringHandler::naturalCompare(s1,s2)==-1;
46}
47
48
49KateSessionApplet::KateSessionApplet(QObject *parent, const QVariantList &args)
50 : Plasma::PopupApplet(parent, args), m_listView( 0 ), m_config(0)
51{
52 KDirWatch *dirwatch = new KDirWatch( this );
53 QStringList lst = KGlobal::dirs()->findDirs( "data", "kate/sessions/" );
54 for ( int i = 0; i < lst.count(); i++ )
55 {
56 dirwatch->addDir( lst[i] );
57 }
58 connect( dirwatch, SIGNAL(dirty(QString)), this, SLOT(slotUpdateSessionMenu()) );
59 setPopupIcon( "kate" );
60 setHasConfigurationInterface(true);
61 setAspectRatioMode(Plasma::IgnoreAspectRatio);
62}
63
64KateSessionApplet::~KateSessionApplet()
65{
66 delete m_listView;
67}
68
69QWidget *KateSessionApplet::widget()
70{
71 if ( !m_listView )
72 {
73 m_listView= new QTreeView();
74 m_listView->setAttribute(Qt::WA_NoSystemBackground);
75 m_listView->setEditTriggers( QAbstractItemView::NoEditTriggers );
76 m_listView->setRootIsDecorated(false);
77 m_listView->setHeaderHidden(true);
78 m_listView->setMouseTracking(true);
79
80 m_kateModel = new QStandardItemModel(this);
81 m_listView->setModel(m_kateModel);
82 m_listView->setMouseTracking(true);
83
84 initSessionFiles();
85
86 connect(m_listView, SIGNAL(activated(QModelIndex)),
87 this, SLOT(slotOnItemClicked(QModelIndex)));
88 }
89 return m_listView;
90}
91
92
93void KateSessionApplet::slotUpdateSessionMenu()
94{
95 m_kateModel->clear();
96 m_sessions.clear();
97 m_fullList.clear();
98 initSessionFiles();
99}
100
101void KateSessionApplet::initSessionFiles()
102{
103 // Obtain list of items previously configured as hidden
104 const QStringList hideList = config().readEntry("hideList", QStringList());
105
106 // Construct a full list of items (m_fullList) so we can display them
107 // in the config dialog, but leave out the hidden stuff for m_kateModel
108 // that is actually displayed
109 int index=0;
110 QStandardItem *item = new QStandardItem();
111 item->setData(i18n("Start Kate (no arguments)"), Qt::DisplayRole);
112 item->setData( KIcon( "kate" ), Qt::DecorationRole );
113 item->setData( index++, Index );
114 m_fullList << item->data(Qt::DisplayRole).toString();
115 if (!hideList.contains(item->data(Qt::DisplayRole).toString())) {
116 m_kateModel->appendRow(item);
117 }
118
119 item = new QStandardItem();
120 item->setData( i18n("New Kate Session"), Qt::DisplayRole);
121 item->setData( KIcon( "document-new" ), Qt::DecorationRole );
122 item->setData( index++, Index );
123 m_fullList << item->data(Qt::DisplayRole).toString();
124 if (!hideList.contains(item->data(Qt::DisplayRole).toString())) {
125 m_kateModel->appendRow(item);
126 }
127
128 item = new QStandardItem();
129 item->setData( i18n("New Anonymous Session"), Qt::DisplayRole);
130 item->setData( index++, Index );
131 item->setData( KIcon( "document-new" ), Qt::DecorationRole );
132 m_fullList << item->data(Qt::DisplayRole).toString();
133 if (!hideList.contains(item->data(Qt::DisplayRole).toString())) {
134 m_kateModel->appendRow(item);
135 }
136
137 const QStringList list = KGlobal::dirs()->findAllResources( "data", "kate/sessions/*.katesession", KStandardDirs::NoDuplicates );
138 KUrl url;
139 for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it)
140 {
141 url.setPath(*it);
142 QString name=url.fileName();
143 name = QUrl::fromPercentEncoding(QFile::encodeName(url.fileName()));
144 name.chop(12);///.katesession==12
145/* KConfig _config( *it, KConfig::SimpleConfig );
146 KConfigGroup config(&_config, "General" );
147 QString name = config.readEntry( "Name" );*/
148 m_sessions.append( name );
149 }
150 qSort(m_sessions.begin(),m_sessions.end(),katesessions_compare_sessions);
151 for(QStringList::ConstIterator it=m_sessions.constBegin();it!=m_sessions.constEnd();++it)
152 {
153 m_fullList << *it;
154 if (!hideList.contains(*it)) {
155 item = new QStandardItem();
156 item->setData(*it, Qt::DisplayRole);
157 item->setData( index++, Index );
158 m_kateModel->appendRow( item);
159 }
160 }
161}
162
163void KateSessionApplet::slotOnItemClicked(const QModelIndex &index)
164{
165 hidePopup();
166 int id = index.data(Index).toInt();
167 QStringList args;
168
169 // If a new session is requested we try to ask for a name.
170 if ( id == 1 )
171 {
172 bool ok = false;
173 QString name = KInputDialog::getText( i18n("Session Name"),
174 i18n("Please enter a name for the new session"),
175 QString(),
176 &ok );
177 if ( ! ok )
178 return;
179
180 if ( name.isEmpty() && KMessageBox::questionYesNo( 0,
181 i18n("An unnamed session will not be saved automatically. "
182 "Do you want to create such a session?"),
183 i18n("Create anonymous session?"),
184 KStandardGuiItem::yes(), KStandardGuiItem::cancel(),
185 "kate_session_button_create_anonymous" ) == KMessageBox::No )
186 return;
187
188 if ( m_sessions.contains( name ) &&
189 KMessageBox::warningYesNo( 0,
190 i18n("You already have a session named %1. Do you want to open that session?", name ),
191 i18n("Session exists") ) == KMessageBox::No )
192 return;
193 if (name.isEmpty())
194 args <<"-startanon";
195 else
196 args <<"-n"<<"--start"<< name;
197 }
198
199 else if ( id == 2 )
200 args << "--startanon";
201
202 else if ( id > 2 )
203 args <<"-n"<< "--start"<<m_sessions[ id-3 ];
204
205 KToolInvocation::kdeinitExec("kate", args);
206}
207
208void KateSessionApplet::createConfigurationInterface(KConfigDialog *parent)
209{
210 const QStringList hideList = config().readEntry("hideList", QStringList());
211 m_config = new KateSessionConfigInterface(m_fullList,
212 hideList);
213 parent->addPage(m_config, i18n("Sessions"),
214 "preferences-desktop-notification",
215 i18n("Sessions to show"));
216 connect(parent, SIGNAL(applyClicked()), this, SLOT(slotSaveConfig()));
217 connect(parent, SIGNAL(okClicked()), this, SLOT(slotSaveConfig()));
218}
219
220void KateSessionApplet::slotSaveConfig()
221{
222 config().writeEntry("hideList", m_config->hideList());
223}
224
225void KateSessionApplet::configChanged()
226{
227 // refresh menu from config
228 slotUpdateSessionMenu();
229}
230
231KateSessionConfigInterface::KateSessionConfigInterface(const QStringList& all, const QStringList& hidden)
232{
233 m_all = all;
234 m_config.setupUi(this);
235 for (int i=0; i < m_all.size(); i++) {
236 QListWidgetItem *item = new QListWidgetItem(m_all[i]);
237 item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
238 if (hidden.contains(item->text())) {
239 item->setCheckState(Qt::Unchecked);
240 m_config.itemList->addItem(item);
241 } else {
242 item->setCheckState(Qt::Checked);
243 m_config.itemList->addItem(item);
244 }
245 }
246}
247
248QStringList KateSessionConfigInterface::hideList() const
249{
250 QStringList hideList;
251 const int numberOfItem = m_config.itemList->count();
252 for (int i=0; i< numberOfItem; ++i) {
253 QListWidgetItem *item = m_config.itemList->item(i);
254 if (item->checkState() == Qt::Unchecked)
255 hideList << m_config.itemList->item(i)->text();
256 }
257 return hideList;
258}
259
260#include "katesessionapplet.moc"
261