Filebrowser: mark copy to collection as experimental.
[nephilim.git] / nephilim / plugins / Filebrowser.py
blob642f764c2d6eafc5ab869cdccd6c9d02e583e2b0
2 # Copyright (C) 2009 Anton Khirnov <wyskas@gmail.com>
4 # Nephilim 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 3 of the License, or
7 # (at your option) any later version.
9 # Nephilim 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.
14 # You should have received a copy of the GNU General Public License
15 # along with Nephilim. If not, see <http://www.gnu.org/licenses/>.
18 from PyQt4 import QtGui, QtCore
19 from PyQt4.QtCore import QVariant
20 import os
21 import shutil
23 from ..plugin import Plugin
25 class Filebrowser(Plugin):
26 o = None
27 def _load(self):
28 self.o = wgFilebrowser(self)
30 def _unload(self):
31 self.o = None
33 def info(self):
34 return 'A file browser that allows adding files not in collection.'
36 def _get_dock_widget(self):
37 return self._create_dock(self.o)
39 class wgFilebrowser(QtGui.QWidget):
40 view = None
41 model = None
42 path = None
43 plugin = None
44 logger = None
46 class FileView(QtGui.QListView):
47 "context menu"
48 menu = None
49 plugin = None
50 logger = None
52 def __init__(self, model, plugin):
53 QtGui.QListView.__init__(self)
54 self.plugin = plugin
55 self.logger = plugin.logger
57 self.setModel(model)
58 self.setRootIndex(self.model().index(os.path.expanduser('~')))
59 self.setSelectionMode(QtGui.QTreeWidget.ExtendedSelection)
61 self.menu = QtGui.QMenu('file')
62 self.menu.addAction('&Make file(s) readable for MPD.', self.selection_make_readable)
63 self.menu.addAction('***EXPERIMENTAL DON\'T USE*** &Copy to collection.', self.selection_copy_to_collection)
65 self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
66 self.connect(self, QtCore.SIGNAL('customContextMenuRequested(const QPoint &)'), self.show_context_menu)
68 def show_context_menu(self, pos):
69 if not self.indexAt(pos).isValid():
70 return
71 self.menu.popup(self.mapToGlobal(pos))
73 def selection_make_readable(self):
74 for index in self.selectedIndexes():
75 filepath = self.model().filePath(index)
76 if os.path.isdir(filepath):
77 perm = 0755
78 else:
79 perm = 0644
81 self.logger.info('Changind permissions of %s to %d.'%(filepath, perm))
82 try:
83 os.chmod(filepath, perm)
84 except OSError, e:
85 self.logger.error('Can\'t change permissions: %s.'%e)
87 def selection_copy_to_collection(self):
88 target_paths = []
89 for index in self.selectedIndexes():
90 filepath = unicode(self.model().filePath(index))
91 self.logger.info('Copying %s to collection.'%filepath)
92 path_base = os.path.basename(filepath)
93 try:
94 if os.path.isdir(filepath):
95 shutil.copytree(filepath, '%s/%s'%(self.plugin.settings().value('MPD/music_dir').toString(), path_base))
96 else:
97 shutil.copy(filepath, unicode(self.plugin.settings().value('MPD/music_dir').toString()))
98 target_paths.append(path_base)
99 except (OSError, IOError), e:
100 self.logger.error('Error copying to collection: %s.'%e)
102 self.plugin.mpclient().update_db(target_paths)
105 def __init__(self, plugin):
106 QtGui.QWidget.__init__(self)
107 self.plugin = plugin
108 self.logger = plugin.logger
110 self.model = QtGui.QDirModel()
111 self.model.setFilter(QtCore.QDir.AllDirs|QtCore.QDir.AllEntries)
112 self.model.setSorting(QtCore.QDir.DirsFirst)
114 self.view = self.FileView(self.model, self.plugin)
115 self.connect(self.view, QtCore.SIGNAL('activated(const QModelIndex&)'), self.item_activated)
117 self.path = QtGui.QLineEdit(self.model.filePath(self.view.rootIndex()))
118 self.connect(self.path, QtCore.SIGNAL('returnPressed()'), self.path_changed)
120 self.setLayout(QtGui.QVBoxLayout())
121 self.layout().setSpacing(0)
122 self.layout().setMargin(0)
123 self.layout().addWidget(self.path)
124 self.layout().addWidget(self.view)
126 def item_activated(self, index):
127 if self.model.hasChildren(index):
128 self.view.setRootIndex(index)
129 self.path.setText(self.model.filePath(index))
130 else:
131 if not 'file://' in self.plugin.mpclient().urlhandlers():
132 self.logger.error('file:// handler not available. Connect via unix domain sockets.')
133 return
134 paths = []
135 for index in self.view.selectedIndexes():
136 paths.append(u'file://' + unicode(self.model.filePath(index)))
137 self.logger.info('Adding %d song to playlist.'%len(paths))
138 self.plugin.mpclient().add(paths)
140 def path_changed(self):
141 if os.path.isdir(self.path.text()):
142 self.view.setRootIndex(self.model.index(self.path.text()))