Tizen 2.1 base
[platform/upstream/hplip.git] / ui4 / filetable.py
1 # -*- coding: utf-8 -*-
2 #
3 # (c) Copyright 2001-2009 Hewlett-Packard Development Company, L.P.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # Authors: Don Welch
20 #
21
22
23 # Std Lib
24 import sys
25 import os.path
26 import os
27
28 # Local
29 from base.g import *
30 from base import utils, magic
31 from prnt import cups
32 from base.codes import *
33 from ui_utils import *
34
35 # Qt
36 from PyQt4.QtCore import *
37 from PyQt4.QtGui import *
38
39 # Other UI
40 from mimetypesdialog import MimeTypesDialog
41
42
43 FILETABLE_TYPE_PRINT = 0
44 FILETABLE_TYPE_FAX = 1
45
46
47
48 class FileTable(QWidget):
49     def __init__(self, parent):
50         QWidget.__init__(self, parent)
51         self.parent = parent
52
53         self.initUi()
54         self.file_list = []
55         self.typ = FILETABLE_TYPE_PRINT
56         self.selected_filename = None
57         self.fax_add_callback = None
58         self.allowable_mime_types = cups.getAllowableMIMETypes()
59
60         self.user_settings = UserSettings()
61         self.user_settings.load()
62         self.user_settings.debug()
63
64         self.working_dir = self.user_settings.working_dir #user_conf.workingDirectory()
65
66
67
68     def initUi(self):
69         self.gridlayout = QGridLayout(self)
70         self.gridlayout.setObjectName("gridlayout")
71         self.FileTable = QTableWidget(self)
72         self.FileTable.setObjectName("FileTable")
73         self.gridlayout.addWidget(self.FileTable,0,0,1,6)
74         self.AddFileButton = QPushButton(self)
75         self.AddFileButton.setObjectName("AddFileButton")
76         self.gridlayout.addWidget(self.AddFileButton,1,0,1,1)
77         self.RemoveFileButton = QPushButton(self)
78         self.RemoveFileButton.setObjectName("RemoveFileButton")
79         self.gridlayout.addWidget(self.RemoveFileButton,1,1,1,1)
80         self.MoveFileUpButton = QPushButton(self)
81         self.MoveFileUpButton.setObjectName("MoveFileUpButton")
82         self.gridlayout.addWidget(self.MoveFileUpButton,1,2,1,1)
83         self.MoveFileDownButton = QPushButton(self)
84         self.MoveFileDownButton.setObjectName("MoveFileDownButton")
85         self.gridlayout.addWidget(self.MoveFileDownButton,1,3,1,1)
86         spacerItem = QSpacerItem(91,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
87         self.gridlayout.addItem(spacerItem,1,4,1,1)
88         self.ShowTypesButton = QPushButton(self)
89         self.ShowTypesButton.setObjectName("ShowTypesButton")
90         self.gridlayout.addWidget(self.ShowTypesButton,1,5,1,1)
91         self.AddFileButton.setText(self.__tr("Add..."))
92         self.AddFileButton.setIcon(QIcon(load_pixmap('list_add', '16x16')))
93         self.connect(self.AddFileButton, SIGNAL("clicked()"), self.AddFileButton_clicked)
94         self.RemoveFileButton.setIcon(QIcon(load_pixmap('list_remove', '16x16')))
95         self.RemoveFileButton.setText(self.__tr("Remove"))
96         self.connect(self.RemoveFileButton, SIGNAL("clicked()"), self.RemoveFileButton_clicked)
97         self.MoveFileUpButton.setText(self.__tr("Move Up"))
98         self.MoveFileUpButton.setIcon(QIcon(load_pixmap('up', '16x16')))
99         self.connect(self.MoveFileUpButton, SIGNAL("clicked()"), self.MoveFileUpButton_clicked)
100         self.MoveFileDownButton.setText(self.__tr("Move Down"))
101         self.MoveFileDownButton.setIcon(QIcon(load_pixmap('down', '16x16')))
102         self.connect(self.MoveFileDownButton, SIGNAL("clicked()"), self.MoveFileDownButton_clicked)
103         self.ShowTypesButton.setText(self.__tr("Show Valid Types..."))
104         self.ShowTypesButton.setIcon(QIcon(load_pixmap('mimetypes', '16x16')))
105         self.connect(self.ShowTypesButton, SIGNAL("clicked()"), self.ShowTypesButton_clicked)
106         self.FileTable.setContextMenuPolicy(Qt.CustomContextMenu)
107         self.connect(self.FileTable, SIGNAL("customContextMenuRequested(const QPoint &)"),
108             self.FileTable_customContextMenuRequested)
109         self.headers = [self.__tr("Name"), self.__tr("Type"), self.__tr("Folder/Path")]
110
111         self.FileTable.setSortingEnabled(False)
112         self.connect(self.FileTable, SIGNAL("itemSelectionChanged()"), self.FileTable_itemSelectionChanged)
113
114
115     def setWorkingDir(self, d):
116         if os.path.exists(d):
117             self.working_dir = d
118
119
120     def getWorkingDir(self):
121         if self.file_list:
122             self.working_dir = os.path.pathname(self.file_list[0][0])
123             #user_conf.setWorkingDirectory(self.working_dir)
124             self.user_settings.working_dir = self.working_dir
125             self.user_settings.save()
126
127         return self.working_dir
128
129
130     def setType(self, t):
131         self.typ = t
132         if self.typ == FILETABLE_TYPE_FAX:
133             self.headers = [self.__tr("Name"), self.__tr("Type"), self.__tr("Pages")]
134             if log.is_debug():
135                 self.headers.append(self.__tr("File"))
136
137
138     def setFaxCallback(self, callback):
139         self.fax_add_callback = callback
140
141
142     def isNotEmpty(self):
143         return len(self.file_list)
144
145
146     def FileTable_itemSelectionChanged(self):
147         self.selected_filename = self.currentFilename()
148         self.setUpDownButtons()
149
150
151     def updateUi(self, show_add_file_if_empty=True):
152         self.FileTable.clear()
153         self.FileTable.setRowCount(len(self.file_list))
154         self.FileTable.setColumnCount(0)
155
156         if self.file_list:
157             self.emit(SIGNAL("isNotEmpty"))
158             QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
159             try:
160                 selected = None
161                 self.FileTable.setColumnCount(len(self.headers))
162                 self.FileTable.setHorizontalHeaderLabels(self.headers)
163                 flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled
164
165                 for row, f in enumerate(self.file_list):
166                     filename, mime_type, mime_type_desc, title, num_pages = f
167                     col = 0
168
169                     if self.typ == FILETABLE_TYPE_FAX:
170                         if title:
171                             i = QTableWidgetItem(title)
172                         else:
173                             i = QTableWidgetItem(os.path.basename(filename))
174                     else: # FILETABLE_TYPE_PRINT
175                         # Filename (basename)
176                         i = QTableWidgetItem(os.path.basename(filename))
177
178                     i.setData(Qt.UserRole, QVariant(filename))
179                     i.setFlags(flags)
180
181                     if self.selected_filename is not None and \
182                         self.selected_filename == filename:
183                         selected = i
184
185                     self.FileTable.setItem(row, col, i)
186                     col += 1
187
188                     # MIME type
189                     i = QTableWidgetItem(mime_type_desc)
190                     i.setFlags(flags)
191                     self.FileTable.setItem(row, col, i)
192                     col += 1
193
194                     if self.typ == FILETABLE_TYPE_PRINT:
195                         # path/folder
196                         i = QTableWidgetItem(os.path.dirname(filename))
197                         i.setFlags(flags)
198                         self.FileTable.setItem(row, col, i)
199                         col += 1
200
201                     if self.typ == FILETABLE_TYPE_FAX:
202                         # num pages
203                         if num_pages < 1:
204                             i = QTableWidgetItem(self.__tr("(unknown)"))
205                         else:
206                             i = QTableWidgetItem(unicode(num_pages))
207                         i.setFlags(flags)
208                         self.FileTable.setItem(row, col, i)
209                         col += 1
210
211                         if self.typ == FILETABLE_TYPE_FAX and log.is_debug():
212                             i = QTableWidgetItem(filename)
213                             i.setFlags(flags)
214                             self.FileTable.setItem(row, col, i)
215
216
217                 self.FileTable.resizeColumnsToContents()
218
219                 if selected is None:
220                     selected = self.FileTable.item(0, 0)
221
222                 selected.setSelected(True)
223                 self.FileTable.setCurrentItem(selected)
224
225             finally:
226                 QApplication.restoreOverrideCursor()
227
228             self.RemoveFileButton.setEnabled(True)
229             self.RemoveFileButton.setIcon(QIcon(load_pixmap('list_remove', '16x16')))
230
231             self.setUpDownButtons()
232
233         else:
234             self.emit(SIGNAL("isEmpty"))
235             self.RemoveFileButton.setEnabled(False)
236             self.setUpDownButtons()
237
238             if show_add_file_if_empty:
239                 self.AddFileButton.emit(SIGNAL("clicked()"))
240
241
242     def setUpDownButtons(self):
243         if self.file_list:
244             i = self.FileTable.currentRow()
245
246             if len(self.file_list) > 1 and i != len(self.file_list)-1:
247                 self.MoveFileDownButton.setEnabled(True)
248             else:
249                 self.MoveFileDownButton.setEnabled(False)
250
251             if len(self.file_list) > 1 and i != 0:
252                 self.MoveFileUpButton.setEnabled(True)
253             else:
254                 self.MoveFileUpButton.setEnabled(False)
255
256         else:
257             self.MoveFileDownButton.setEnabled(False)
258             self.MoveFileUpButton.setEnabled(False)
259
260
261     def AddFileButton_clicked(self):
262         if self.typ == FILETABLE_TYPE_PRINT:
263             s = self.__tr("Select File(s) to Print")
264         else:
265             s = self.__tr("Select File(s) to Send")
266
267         files = list(QFileDialog.getOpenFileNames(self, s,
268             self.working_dir, self.__tr("All files (*)")))
269
270         files = [unicode(f) for f in files]
271
272         if files:
273             self.addFileList(files)
274
275             if self.typ == FILETABLE_TYPE_PRINT:
276                 self.updateUi(False)
277
278
279     def addFileList(self, file_list):
280         for f in file_list:
281             self.addFileFromUI(f)
282
283
284     def addFileFromUI(self, f, title='', num_pages=0):
285         f = os.path.abspath(os.path.expanduser(f))
286         log.debug("Trying to add file: %s" % f)
287
288         if os.path.exists(f) and os.access(f, os.R_OK):
289             mime_type = magic.mime_type(f)
290             mime_type_desc = mime_type
291             log.debug("File type of file %s: %s" % (f, mime_type))
292
293             try:
294                 mime_type_desc = MIME_TYPES_DESC[mime_type][0]
295             except KeyError:
296                 if self.typ == FILETABLE_TYPE_PRINT:
297                     FailureUI(self, self.__tr("<b>You are trying to add a file '%1' that cannot be directly printed with this utility.</b><p>To print this file, use the print command in the application that created it.<p>Note: Click <i>Show Valid Types...</i> to view a list of compatible file types that can be directly printed from this utility.").arg(f),
298                         self.__tr("HP Device Manager"))
299                 else:
300                     FailureUI(self, self.__tr("<b>You are trying to add a file '%1' that cannot be directly faxed with this utility.</b><p>To fax this file, use the print command in the application that created it (using the appropriate fax print queue).<p>Note: Click <i>Show Valid Types...</i> to view a list of compatible file types that can be directly added to the fax file list in this utility.").arg(f),
301                         self.__tr("HP Device Manager"))
302             else:
303                 if self.typ == FILETABLE_TYPE_PRINT:
304                     self.addFile(f, mime_type, mime_type_desc, title, num_pages)
305                 else:
306                     self.fax_add_callback(f)
307         else:
308             FailureUI(self, self.__tr("<b>Unable to add file '%1' to file list (file not found or insufficient permissions).</b><p>Check the file name and try again.").arg(f),
309                 self.__tr("HP Device Manager"))
310
311
312     def addFile(self, f, mime_type, mime_type_desc, title, num_pages):
313         log.debug("Adding file %s (%s,%s,%s,%d)" % (f, mime_type, mime_type_desc, title, num_pages))
314         self.file_list.append((f, mime_type, mime_type_desc, title, num_pages))
315         self.updateUi()
316         self.emit(SIGNAL("fileListChanged"))
317
318
319     def currentFilename(self):
320         i = self.FileTable.item(self.FileTable.currentRow(), 0)
321         if i is None:
322             return None
323         return i.data(Qt.UserRole).toString()
324
325
326     def RemoveFileButton_clicked(self):
327         filename = self.currentFilename()
328         if filename is None:
329             return
330
331         return self.removeFile(filename)
332
333
334     def removeFile(self, filename):
335         temp = self.file_list[:]
336         index = 0
337         for f, mime_type, mime_type_desc, title, num_pages in temp:
338             if f == filename:
339                 del self.file_list[index]
340                 self.emit(SIGNAL("fileListChanged"))
341                 self.updateUi(False)
342                 break
343             index += 1
344
345
346     def removeFileByMIMEType(self, mime_type):
347         temp = self.file_list[:]
348         index = 0
349         for filename, m, mime_type_desc, title, num_pages in temp:
350             if m == mime_type:
351                 del self.file_list[index]
352                 self.emit(SIGNAL("fileListChanged"))
353                 self.updateUi(False)
354                 break
355             index += 1
356
357
358     def isMIMETypeInList(self, mime_type):
359         for filename, m, mime_type_desc, title, num_pages in self.file_list:
360             if m == mime_type:
361                 return True
362
363         return False
364
365
366     def ShowTypesButton_clicked(self):
367         x = {}
368         for a in self.allowable_mime_types:
369             x[a] = MIME_TYPES_DESC.get(a, ('Unknown', 'n/a'))
370
371         dlg = MimeTypesDialog(x, self)
372         dlg.exec_()
373
374
375     def MoveFileUpButton_clicked(self):
376         filename = self.currentFilename()
377         if filename is None:
378             return
379
380         utils.list_move_up(self.file_list, filename, self.__compareFilenames)
381         self.updateUi()
382
383
384     def MoveFileDownButton_clicked(self):
385         filename = self.currentFilename()
386         if filename is None:
387             return
388
389         utils.list_move_down(self.file_list, filename, self.__compareFilenames)
390         self.updateUi()
391
392
393     def __compareFilenames(self, a, b):
394         return a[0] == b
395
396
397     def FileTable_customContextMenuRequested(self, p):
398         print p
399
400
401     def __tr(self,s,c = None):
402         return qApp.translate("FileTable",s,c)
403
404
405