# chooseInSticks.py

Aller à la documentation de ce fichier.

    00001 # -*- coding: utf-8 -*-
    00002 # $Id: chooseInSticks.py 47 2011-06-13 10:20:14Z georgesk $
    00003
    00004 licenceEn="""
    00005     file chooseInSticks.py
    00006     this file is part of the project scolasync
    00007
    00008     Copyright (C) 2010 Georges Khaznadar <georgesk@ofset.org>
    00009
    00010     This program is free software: you can redistribute it and/or modify
    00011     it under the terms of the GNU General Public License as published by
    00012     the Free Software Foundation, either version3 of the License, or
    00013     (at your option) any later version.
    00014
    00015     This program is distributed in the hope that it will be useful,
    00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
    00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00018     GNU General Public License for more details.
    00019
    00020     You should have received a copy of the GNU General Public License
    00021     along with this program.  If not, see <http://www.gnu.org/licenses/>.
    00022 """
    00023
    00024 from PyQt4.QtCore import *
    00025 from PyQt4.QtGui import *
    00026 import os.path
    00027
    00028 import Ui_chooseInSticks
    00029
    00030 ##
    00031 #
    00032 #     Un dialogue pour choisir un ensemble de fichiers à copier depuis une clé USB.
    00033 #
    00034 class chooseDialog(QDialog):
    00035     ##
    00036     #
    00037     #         Le constructeur
    00038     #         @param parent un mainWindow, qui est censé contenir des données
    00039     #         telles que parent.workdir, ...
    00040     #         @param title1 le titre du dialogue
    00041     #         @param title2 le titre pour la série de fichiers/modèles
    00042     #         @param ok le texte du bouton OK
    00043     #
    00044     def __init__(self,parent = None, title1="", title2="", ok="OK"):
    00045         QDialog.__init__(self,parent)
    00046         self.mainWindow=parent
    00047         self._ui=Ui_chooseInSticks.Ui_Dialog()
    00048         self._ui.setupUi(self)
    00049         ## mise en place des titres personnalisés
    00050         self.setWindowTitle(title1)
    00051         self._ui.groupBox.setTitle(title2)
    00052         ## mise en place du bouton personnalisé
    00053         okButton=self._ui.buttonBox.button(QDialogButtonBox.Ok)
    00054         self._ui.buttonBox.removeButton(okButton)
    00055         self._ui.buttonBox.addButton(QPushButton(ok),
    00056                                      QDialogButtonBox.AcceptRole)
    00057         ## création de la structure de liste pour les fichiers
    00058         self._fileListModel=QStandardItemModel()
    00059         self._fileListProxyModel = QSortFilterProxyModel()
    00060         self._fileListProxyModel.setSourceModel(self._fileListModel)
    00061         self._ui.listView.setModel(self._fileListProxyModel)
    00062         self._fileListProxyModel.setDynamicSortFilter(True)
    00063         ## création de la structure de liste pour les noms de baladeurs
    00064         self._storListModel=QStandardItemModel()
    00065         self._storListProxyModel = QSortFilterProxyModel()
    00066         self._storListProxyModel.setSourceModel(self._storListModel)
    00067         self._ui.listChoixCle.setModel(self._storListProxyModel)
    00068         self._storListProxyModel.setDynamicSortFilter(True)
    00069         ## peuplement de la zone des noms de baladeurs
    00070         self.ownedUsbDictionary={}
    00071         self.listStorages()
    00072         ##
    00073         self._ui.minusButton.setEnabled(False)
    00074         self._ui.travailEdit.setText(self.mainWindow.workdir)
    00075         QObject.connect(self._ui.plusButton, SIGNAL("clicked()"), self.plus)
    00076         QObject.connect(self._ui.chooseButton, SIGNAL("clicked()"), self.choose)
    00077         QObject.connect(self._ui.chooseButton_dir, SIGNAL("clicked()"), self.choose_dir)
    00078         QObject.connect(self._ui.minusButton, SIGNAL("clicked()"), self.minus)
    00079         QObject.connect(self._ui.listView, SIGNAL("clicked(QModelIndex)"), self.activate)
    00080         QObject.connect(self._ui.travailEdit, SIGNAL("editingFinished()"), self.changeWd)
    00081
    00082
    00083     ##
    00084     #
    00085     #         Met en place la liste des noms de baladeurs connectés en tenant compte
    00086     #         du nom de répertoire de travail et d'un baladeur éventuellement
    00087     #         sélectionné dans la fenêtre principale
    00088     #
    00089     def listStorages(self):
    00090         from mainWindow import globalDiskData
    00091         sel=self.mainWindow.ui.tableView.selectedIndexes()
    00092         for d in globalDiskData:
    00093             o=d.ownerByDb()
    00094             mountPath=d.ensureMounted()
    00095             item=QStandardItem(o)
    00096             # on cherche à voir si la clé est déjà sélectionnée
    00097             for modelIndex in sel:
    00098                 if o == u"%s" %modelIndex.data(Qt.DisplayRole).toString():
    00099                     break
    00100             self._storListModel.appendRow(item)
    00101             self.ownedUsbDictionary[o]=mountPath
    00102         self._storListProxyModel.sort(0)
    00103         self.checkWorkDirs()
    00104
    00105     ##
    00106     #
    00107     #         met à jour la possibilité de sélectionner les baladeurs dans la liste
    00108     #         selon qu'ils ont ou pas un répertoire de travail, puis sélectionne
    00109     #         si possible un baladeur, si aucun ne l'était avant.
    00110     #
    00111     def checkWorkDirs(self):
    00112         firstSelectable=None
    00113         okSelected=None
    00114         # on récupère la sélection courante à travers le proxy
    00115         selection=self._ui.listChoixCle.selectionModel().selection()
    00116         selection = self._storListProxyModel.mapSelectionToSource(selection)
    00117         selectedRows=map(lambda x: x.row(), self._ui.listChoixCle.selectedIndexes())
    00118         for item in self._storListModel.findItems ("*",Qt.MatchWildcard):
    00119             index=self._storListModel.indexFromItem(item)
    00120             o=u"%s" %item.data(Qt.DisplayRole).toString()
    00121             testDir=os.path.join(self.ownedUsbDictionary[o],self.mainWindow.workdir)
    00122             if os.path.isdir(testDir):
    00123                 # si l'item concerne un disque qui contient le répertoire de
    00124                 # travail, on le rend sélectionnable
    00125                 item.setSelectable(True)
    00126                 item.setEnabled(True)
    00127                 # et si c'est le tout premier, on s'en souvient.
    00128                 if firstSelectable == None:
    00129                     firstSelectable=index
    00130                 # on vérifie s'il était déjà dans la sélection
    00131                 if index.row() in selectedRows:
    00132                     okSelected=index
    00133             else:
    00134                 item.setSelectable(False)
    00135                 item.setEnabled(False)
    00136         if okSelected == None and firstSelectable != None:
    00137             selection=QItemSelection(firstSelectable,firstSelectable)
    00138             selection=self._storListProxyModel.mapSelectionFromSource(selection)
    00139             self._ui.listChoixCle.selectionModel().select(selection, QItemSelectionModel.Select);
    00140
    00141     ##
    00142     #
    00143     #         @return le répertoire à partir duquel on peut commencer à faire
    00144     #         un choix de fichier ou de sous-répertoire. Il dépend du baladeur
    00145     #         sélectionné s'il y en a un et du nom du répertoire de travail.
    00146     #         Si on n'arrive pas à déterminer ce répertoire, renvoie None
    00147     #
    00148     def baseDir(self):
    00149         mp=self.selectedDiskMountPoint()
    00150         if mp:
    00151             return os.path.join(mp,self.mainWindow.workdir)
    00152         else:
    00153             return None
    00154
    00155     ##
    00156     #
    00157     #         @return le point de montage du support sélectionné s'il y en a un
    00158     #
    00159     def selectedDiskMountPoint(self):
    00160         o=self.selectedDiskOwner()
    00161         if o==None:
    00162             return None
    00163         else:
    00164             return self.ownedUsbDictionary[o]
    00165
    00166     ##
    00167     #
    00168     #         @return le nom du propriétaire du disque sélectionné s'il y en a un,
    00169     #         sinon None.
    00170     #
    00171     def selectedDiskOwner(self):
    00172         selection=self._ui.listChoixCle.selectionModel().selection()
    00173         if len(selection)==0:
    00174             return None
    00175         selection = self._storListProxyModel.mapSelectionToSource(selection)
    00176         return u"%s" %selection.indexes()[0].data(Qt.DisplayRole).toString()
    00177
    00178     ##
    00179     #
    00180     #         changement du répertoire de travail
    00181     #
    00182     def changeWd(self):
    00183         newDir=u"%s" %self._ui.travailEdit.text().toUtf8()
    00184         self.mainWindow.changeWd(newDir)
    00185         self.checkWorkDirs()
    00186
    00187     ##
    00188     #
    00189     #         Facilite le choix de motifs de fichiers en recherchant dans
    00190     #         les clés USB, modifie l'éditeur de ligne de texte et place le
    00191     #         fichier choisi dans la liste
    00192     #         @param kind type d'élément à choisir : "file" pour un fichier,
    00193     #         "dir" pour un répertoire
    00194     #
    00195     def choose(self, kind="file"):
    00196         if kind == "file":
    00197             func=QFileDialog.getOpenFileName
    00198             msg=QApplication.translate("Dialog",
    00199                                        "Choissez un fichier",
    00200                                        encoding=QApplication.UnicodeUTF8)
    00201         else:
    00202             func=QFileDialog.getExistingDirectory
    00203             msg=QApplication.translate("Dialog",
    00204                                        "Choissez un répertoire",
    00205                                        encoding=QApplication.UnicodeUTF8)
    00206         cd=self.baseDir()
    00207         if cd!=None:
    00208             f = func (None, msg, cd)
    00209             if f and len(f)>0:
    00210                 path=f.remove(self.selectedDiskMountPoint()+"/")
    00211                 self._ui.lineEdit.setText(path)
    00212                 # par défaut, on ajoute le nouveau texte et on pourrait aller
    00213                 # jusqu'à le sélectionner !
    00214                 self.plus()
    00215         else:
    00216             titre=QApplication.translate("Dialog",
    00217                                          "Aucune clé modèle sélectionnée",
    00218                                          encoding=QApplication.UnicodeUTF8)
    00219             msg=QApplication.translate("Dialog",
    00220                                        "Veuillez choisir une clé modèle<br>parmi les clés connectées en cliquant<br>sur une ligne du tableau, pour<br>bénéficier de l'aide au choix de fichiers.<br><br>Cette clé doit contenir au moins<br>un répertoire « {workdir} ».".format(workdir=self.mainWindow.workdir),
    00221                                        encoding=QApplication.UnicodeUTF8)
    00222             msgBox=QMessageBox.warning(None, titre, msg)
    00223
    00224     ##
    00225     #
    00226     #         Facilite le choix de motifs de répertoires en recherchant dans
    00227     #         les clés USB, modifie l'éditeur de ligne de texte et place le
    00228     #         répertoire choisi dans la liste
    00229     #
    00230     def choose_dir(self):
    00231         self.choose(kind="dir")
    00232
    00233     ##
    00234     #
    00235     #         Fonction de rappel quand un item de la liste est activé
    00236     #         @param item désignation de l'item activé
    00237     #
    00238     def activate(self, item):
    00239         self._ui.minusButton.setEnabled(True)
    00240
    00241     ##
    00242     #
    00243     #         Permet de choisir et d'ajouter un nouveau fichier ou répertoire à
    00244     #         supprimer
    00245     #
    00246     def plus(self):
    00247         text=self._ui.lineEdit.text()
    00248         if len(text)>0 :
    00249             self.append(text)
    00250
    00251     ##
    00252     #
    00253     #         Permet de retirer de la liste des fichiers à supprimer ceux qu'on
    00254     #         a sélectionnés
    00255     #
    00256     def minus(self):
    00257         sel=self._ui.listView.selectedIndexes()
    00258         sel1=map(self._fileListProxyModel.mapToSource,sel)
    00259         rows=map(lambda x: x.row(), sel1)
    00260         rows.sort("descending")
    00261         for r in rows:
    00262             self._fileListModel.removeRow(r)
    00263         sel=self._ui.listView.selectedIndexes()
    00264         if len(sel)==0:
    00265             self._ui.minusButton.setEnabled(False)
    00266
    00267     ##
    00268     #
    00269     #         Ajoute un chemin avec ou sans jokers à la liste des chemins à supprimer
    00270     #         @param path le chemin
    00271     #
    00272     def append(self, path):
    00273         f=self._fileListModel.findItems(path)
    00274         if len(f)==0:
    00275             item=QStandardItem(path)
    00276             self._fileListModel.appendRow(item)
    00277             self._fileListProxyModel.sort(0)
    00278         else:
    00279             print path, "est déjà sélectionné"
    00280
    00281     ##
    00282     #
    00283     #         renvoie la liste des chemins sélectionés
    00284     #         @return une liste de chemins, sous forme de QStrings
    00285     #
    00286     def pathList(self):
    00287         itemList=self._fileListModel.findItems("*",Qt.MatchWildcard)
    00288         result=map(lambda x: x.text(), itemList)
    00289         if len(result)==0: return result
    00290         mp=self.selectedDiskMountPoint()+"/"
    00291         result=map(lambda x: x.replace(mp,"",1), result)
    00292         return result
    00293
    00294