]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/places/placespanel.cpp
Places Panel: Provide dialog for editing places
[dolphin.git] / src / panels / places / placespanel.cpp
1 /***************************************************************************
2 * Copyright (C) 2008-2012 by Peter Penz <peter.penz19@gmail.com> *
3 * *
4 * Based on KFilePlacesView from kdelibs: *
5 * Copyright (C) 2007 Kevin Ottens <ervin@kde.org> *
6 * Copyright (C) 2007 David Faure <faure@kde.org> *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
22 ***************************************************************************/
23
24 #include "placespanel.h"
25
26 #include <KConfigGroup>
27 #include <KDirNotify>
28 #include <KIcon>
29 #include <KIO/Job>
30 #include <KIO/JobUiDelegate>
31 #include <KLocale>
32 #include <kitemviews/kitemlistcontainer.h>
33 #include <kitemviews/kitemlistcontroller.h>
34 #include <kitemviews/kstandarditemlistview.h>
35 #include <KMenu>
36 #include <KMessageBox>
37 #include <KNotification>
38 #include "placesitemeditdialog.h"
39 #include "placesitemlistgroupheader.h"
40 #include "placesitemmodel.h"
41 #include <views/draganddrophelper.h>
42 #include <QVBoxLayout>
43 #include <QShowEvent>
44
45 PlacesPanel::PlacesPanel(QWidget* parent) :
46 Panel(parent),
47 m_controller(0),
48 m_model(0)
49 {
50 }
51
52 PlacesPanel::~PlacesPanel()
53 {
54 }
55
56 bool PlacesPanel::urlChanged()
57 {
58 return true;
59 }
60
61 void PlacesPanel::showEvent(QShowEvent* event)
62 {
63 if (event->spontaneous()) {
64 Panel::showEvent(event);
65 return;
66 }
67
68 if (!m_controller) {
69 // Postpone the creating of the controller to the first show event.
70 // This assures that no performance and memory overhead is given when the folders panel is not
71 // used at all and stays invisible.
72 m_model = new PlacesItemModel(this);
73 m_model->setGroupedSorting(true);
74 m_model->setSortRole("group");
75
76 KStandardItemListView* view = new KStandardItemListView();
77 view->setGroupHeaderCreator(new KItemListGroupHeaderCreator<PlacesItemListGroupHeader>());
78
79 m_controller = new KItemListController(m_model, view, this);
80 m_controller->setSelectionBehavior(KItemListController::SingleSelection);
81 connect(m_controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int)));
82 connect(m_controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int)));
83 connect(m_controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF)));
84 connect(m_controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF)));
85
86 KItemListContainer* container = new KItemListContainer(m_controller, this);
87 container->setEnabledFrame(false);
88
89 QVBoxLayout* layout = new QVBoxLayout(this);
90 layout->setMargin(0);
91 layout->addWidget(container);
92 }
93
94 Panel::showEvent(event);
95 }
96
97 void PlacesPanel::slotItemActivated(int index)
98 {
99 const KUrl url = m_model->data(index).value("url").value<KUrl>();
100 if (!url.isEmpty()) {
101 emit placeActivated(url);
102 }
103 }
104
105 void PlacesPanel::slotItemMiddleClicked(int index)
106 {
107 const KUrl url = m_model->data(index).value("url").value<KUrl>();
108 if (!url.isEmpty()) {
109 emit placeMiddleClicked(url);
110 }
111 }
112
113 void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
114 {
115 const QHash<QByteArray, QVariant> data = m_model->data(index);
116 const QString label = data.value("text").toString();
117
118 KMenu menu(this);
119
120 QAction* emptyTrashAction = 0;
121 QAction* addAction = 0;
122 QAction* mainSeparator = 0;
123 QAction* editAction = 0;
124 QAction* tearDownAction = 0;
125 QAction* ejectAction = 0;
126
127 const bool isDevice = !data.value("udi").toString().isEmpty();
128 if (isDevice) {
129 ejectAction = m_model->ejectAction(index);
130 if (ejectAction) {
131 ejectAction->setParent(&menu);
132 menu.addAction(ejectAction);
133 }
134
135 tearDownAction = m_model->tearDownAction(index);
136 if (tearDownAction) {
137 tearDownAction->setParent(&menu);
138 menu.addAction(tearDownAction);
139 }
140
141 if (tearDownAction || ejectAction) {
142 mainSeparator = menu.addSeparator();
143 }
144 } else {
145 if (data.value("url").value<KUrl>() == KUrl("trash:/")) {
146 emptyTrashAction = menu.addAction(KIcon("trash-empty"), i18nc("@action:inmenu", "Empty Trash"));
147 KConfig trashConfig("trashrc", KConfig::SimpleConfig);
148 emptyTrashAction->setEnabled(!trashConfig.group("Status").readEntry("Empty", true));
149 menu.addSeparator();
150 }
151 addAction = menu.addAction(KIcon("document-new"), i18nc("@item:inmenu", "Add Entry..."));
152 mainSeparator = menu.addSeparator();
153 editAction = menu.addAction(KIcon("document-properties"), i18nc("@item:inmenu", "Edit Entry '%1'...", label));
154 }
155
156 if (!addAction) {
157 addAction = menu.addAction(KIcon("document-new"), i18nc("@item:inmenu", "Add Entry..."));
158 }
159
160 QAction* hideAction = menu.addAction(i18nc("@item:inmenu", "Hide Entry '%1'", label));
161 hideAction->setCheckable(true);
162 //hideEntry->setChecked(data.value("hidden").toBool());
163
164 QAction* showAllAction = 0;
165 if (m_model->hiddenCount() > 0) {
166 if (!mainSeparator) {
167 mainSeparator = menu.addSeparator();
168 }
169 showAllAction = menu.addAction(i18nc("@item:inmenu", "Show All Entries"));
170 showAllAction->setCheckable(true);
171 //showAllEntries->setChecked(showAll)
172 }
173
174 QAction* removeAction = 0;
175 if (!isDevice) {
176 removeAction = menu.addAction(KIcon("edit-delete"), i18nc("@item:inmenu", "Remove Entry '%1'", label));
177 }
178
179 menu.addSeparator();
180 foreach (QAction* action, customContextMenuActions()) {
181 menu.addAction(action);
182 }
183
184 QAction* action = menu.exec(pos.toPoint());
185 if (!action) {
186 return;
187 }
188
189 if (action == emptyTrashAction) {
190 emptyTrash();
191 } else if (action == addAction) {
192 addEntry();
193 } else if (action == editAction) {
194 editEntry(index);
195 } else if (action == removeAction) {
196 } else if (action == hideAction) {
197 } else if (action == showAllAction) {
198 } else if (action == tearDownAction) {
199 } else if (action == ejectAction) {
200 }
201 }
202
203 void PlacesPanel::slotViewContextMenuRequested(const QPointF& pos)
204 {
205 KMenu menu(this);
206
207 QAction* addAction = menu.addAction(KIcon("document-new"), i18nc("@item:inmenu", "Add Entry..."));
208 menu.addSeparator();
209 foreach (QAction* action, customContextMenuActions()) {
210 menu.addAction(action);
211 }
212
213 QAction* action = menu.exec(pos.toPoint());
214 if (action == addAction) {
215 addEntry();
216 }
217 }
218
219 void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent)
220 {
221 Q_UNUSED(parent);
222 DragAndDropHelper::dropUrls(KFileItem(), dest, event);
223 }
224
225 void PlacesPanel::slotTrashUpdated(KJob* job)
226 {
227 if (job->error()) {
228 // TODO: Show error-string inside Dolphin, don't use job->ui->showErrorMessage().
229 }
230 org::kde::KDirNotify::emitFilesAdded("trash:/");
231 }
232
233 void PlacesPanel::emptyTrash()
234 {
235 const QString text = i18nc("@info", "Do you really want to empty the Trash? All items will be deleted.");
236 const bool del = KMessageBox::warningContinueCancel(window(),
237 text,
238 QString(),
239 KGuiItem(i18nc("@action:button", "Empty Trash"),
240 KIcon("user-trash"))
241 ) == KMessageBox::Continue;
242 if (del) {
243 QByteArray packedArgs;
244 QDataStream stream(&packedArgs, QIODevice::WriteOnly);
245 stream << int(1);
246 KIO::Job *job = KIO::special(KUrl("trash:/"), packedArgs);
247 KNotification::event("Trash: emptied", QString() , QPixmap() , 0, KNotification::DefaultEvent);
248 job->ui()->setWindow(parentWidget());
249 connect(job, SIGNAL(result(KJob*)), SLOT(slotTrashUpdated(KJob*)));
250 }
251 }
252
253 void PlacesPanel::addEntry()
254 {
255 QPointer<PlacesItemEditDialog> dialog = new PlacesItemEditDialog(this);
256 dialog->setCaption(i18nc("@title:window", "Add Places Entry"));
257 dialog->setAllowGlobal(true);
258 if (dialog->exec() == QDialog::Accepted) {
259 // TODO
260 }
261
262 delete dialog;
263 }
264
265 void PlacesPanel::editEntry(int index)
266 {
267 const QHash<QByteArray, QVariant> data = m_model->data(index);
268
269 QPointer<PlacesItemEditDialog> dialog = new PlacesItemEditDialog(this);
270 dialog->setCaption(i18nc("@title:window", "Edit Places Entry"));
271 dialog->setIcon(data.value("iconName").toString());
272 dialog->setText(data.value("text").toString());
273 dialog->setUrl(data.value("url").value<KUrl>());
274 dialog->setAllowGlobal(true);
275 if (dialog->exec() == QDialog::Accepted) {
276 // TODO
277 }
278
279 delete dialog;
280 }
281
282 #include "placespanel.moc"