ScolaSync  1.0
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         sel=self.mainWindow.ui.tableView.selectedIndexes()
00091         for d in qApp.diskData:
00092             o=d.ownerByDb()
00093             mountPath=d.ensureMounted()
00094             item=QStandardItem(o)
00095             # on cherche à voir si la clé est déjà sélectionnée
00096             for modelIndex in sel:
00097                 if o == u"%s" %modelIndex.data(Qt.DisplayRole).toString():
00098                     break
00099             self._storListModel.appendRow(item)
00100             self.ownedUsbDictionary[o]=mountPath
00101         self._storListProxyModel.sort(0)
00102         self.checkWorkDirs()
00103 
00104     ##
00105     # 
00106     #         met à jour la possibilité de sélectionner les baladeurs dans la liste
00107     #         selon qu'ils ont ou pas un répertoire de travail, puis sélectionne
00108     #         si possible un baladeur, si aucun ne l'était avant.
00109     #         
00110     def checkWorkDirs(self):
00111         firstSelectable=None
00112         okSelected=None
00113         # on récupère la sélection courante à travers le proxy
00114         selection=self._ui.listChoixCle.selectionModel().selection()
00115         selection = self._storListProxyModel.mapSelectionToSource(selection)
00116         selectedRows=map(lambda x: x.row(), self._ui.listChoixCle.selectedIndexes())
00117         itemList=self._storListModel.findItems ("*",Qt.MatchWildcard)
00118         itemList.sort(key=lambda i: i.data(Qt.DisplayRole).toString())
00119         # parcours des items de la liste par ordre alphabétique
00120         # pour élire celui qui sera sélectionné initialement
00121         for item in itemList:
00122             index=self._storListModel.indexFromItem(item)
00123             o=u"%s" %item.data(Qt.DisplayRole).toString()
00124             testDir=os.path.join(self.ownedUsbDictionary[o],self.mainWindow.workdir)
00125             if os.path.isdir(testDir):
00126                 # si l'item concerne un disque qui contient le répertoire de
00127                 # travail, on le rend sélectionnable
00128                 item.setSelectable(True)
00129                 item.setEnabled(True)
00130                 # et si c'est le tout premier, on s'en souvient.
00131                 if firstSelectable == None:
00132                     firstSelectable=index
00133                 # on vérifie s'il était déjà dans la sélection
00134                 if index.row() in selectedRows:
00135                     okSelected=index
00136             else:
00137                 item.setSelectable(False)
00138                 item.setEnabled(False)
00139         if okSelected == None and firstSelectable != None:
00140             selection=QItemSelection(firstSelectable,firstSelectable)
00141             selection=self._storListProxyModel.mapSelectionFromSource(selection)
00142             self._ui.listChoixCle.selectionModel().select(selection, QItemSelectionModel.Select);
00143 
00144     ##
00145     # 
00146     #         @return le répertoire à partir duquel on peut commencer à faire
00147     #         un choix de fichier ou de sous-répertoire. Il dépend du baladeur
00148     #         sélectionné s'il y en a un et du nom du répertoire de travail.
00149     #         Si on n'arrive pas à déterminer ce répertoire, renvoie None
00150     #         
00151     def baseDir(self):
00152         mp=self.selectedDiskMountPoint()
00153         if mp:
00154             return os.path.join(mp,self.mainWindow.workdir)
00155         else:
00156             return None
00157 
00158     ##
00159     # 
00160     #         @return le point de montage du support sélectionné s'il y en a un
00161     #         
00162     def selectedDiskMountPoint(self):
00163         o=self.selectedDiskOwner()
00164         if o==None:
00165             return None
00166         else:
00167             return self.ownedUsbDictionary[o]
00168 
00169     ##
00170     # 
00171     #         @return le nom du propriétaire du disque sélectionné s'il y en a un,
00172     #         sinon None.
00173     #         
00174     def selectedDiskOwner(self):
00175         selection=self._ui.listChoixCle.selectionModel().selection()
00176         if len(selection)==0:
00177             return None
00178         selection = self._storListProxyModel.mapSelectionToSource(selection)
00179         return u"%s" %selection.indexes()[0].data(Qt.DisplayRole).toString()
00180                 
00181     ##
00182     # 
00183     #         changement du répertoire de travail
00184     #         
00185     def changeWd(self):
00186         newDir=u"%s" %self._ui.travailEdit.text().toUtf8()
00187         self.mainWindow.changeWd(newDir)
00188         self.checkWorkDirs()
00189 
00190     ##
00191     # 
00192     #         Facilite le choix de motifs de fichiers en recherchant dans
00193     #         les clés USB, modifie l'éditeur de ligne de texte et place le
00194     #         fichier choisi dans la liste
00195     #         @param kind type d'élément à choisir : "file" pour un fichier,
00196     #         "dir" pour un répertoire
00197     #         
00198     def choose(self, kind="file"):
00199         if kind == "file":
00200             func=QFileDialog.getOpenFileName
00201             msg=QApplication.translate("Dialog",
00202                                        "Choissez un fichier",
00203                                        encoding=QApplication.UnicodeUTF8)
00204         else:
00205             func=QFileDialog.getExistingDirectory
00206             msg=QApplication.translate("Dialog",
00207                                        "Choissez un répertoire",
00208                                        encoding=QApplication.UnicodeUTF8)
00209         cd=self.baseDir()
00210         if cd!=None:
00211             f = func (None, msg, cd)
00212             if f and len(f)>0:
00213                 path=f.remove(self.selectedDiskMountPoint()+"/")
00214                 self._ui.lineEdit.setText(path)
00215                 # par défaut, on ajoute le nouveau texte et on pourrait aller
00216                 # jusqu'à le sélectionner !
00217                 self.plus()
00218         else:
00219             titre=QApplication.translate("Dialog",
00220                                          "Aucune clé modèle sélectionnée",
00221                                          encoding=QApplication.UnicodeUTF8)
00222             msg=QApplication.translate("Dialog",
00223                                        "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),
00224                                        encoding=QApplication.UnicodeUTF8)
00225             msgBox=QMessageBox.warning(None, titre, msg)
00226         
00227     ##
00228     # 
00229     #         Facilite le choix de motifs de répertoires en recherchant dans
00230     #         les clés USB, modifie l'éditeur de ligne de texte et place le
00231     #         répertoire choisi dans la liste
00232     #         
00233     def choose_dir(self):
00234         self.choose(kind="dir")
00235         
00236     ##
00237     # 
00238     #         Fonction de rappel quand un item de la liste est activé
00239     #         @param item désignation de l'item activé
00240     #         
00241     def activate(self, item):
00242         self._ui.minusButton.setEnabled(True)
00243         
00244     ##
00245     # 
00246     #         Permet de choisir et d'ajouter un nouveau fichier ou répertoire à
00247     #         supprimer
00248     #         
00249     def plus(self):
00250         text=self._ui.lineEdit.text()
00251         if len(text)>0 :
00252             self.append(text)
00253         
00254     ##
00255     # 
00256     #         Permet de retirer de la liste des fichiers à supprimer ceux qu'on
00257     #         a sélectionnés
00258     #         
00259     def minus(self):
00260         sel=self._ui.listView.selectedIndexes()
00261         sel1=map(self._fileListProxyModel.mapToSource,sel)
00262         rows=map(lambda x: x.row(), sel1)
00263         rows.sort("descending")
00264         for r in rows:
00265             self._fileListModel.removeRow(r)
00266         sel=self._ui.listView.selectedIndexes()
00267         if len(sel)==0:
00268             self._ui.minusButton.setEnabled(False)
00269         
00270     ##
00271     # 
00272     #         Ajoute un chemin avec ou sans jokers à la liste des chemins à supprimer
00273     #         @param path le chemin
00274     #         
00275     def append(self, path):
00276         f=self._fileListModel.findItems(path)
00277         if len(f)==0:
00278             item=QStandardItem(path)
00279             self._fileListModel.appendRow(item)
00280             self._fileListProxyModel.sort(0)
00281         else:
00282             print path, "est déjà sélectionné"
00283 
00284     ##
00285     # 
00286     #         renvoie la liste des chemins sélectionés
00287     #         @return une liste de chemins, sous forme de QStrings
00288     #         
00289     def pathList(self):
00290         itemList=self._fileListModel.findItems("*",Qt.MatchWildcard)
00291         result=map(lambda x: x.text(), itemList)
00292         if len(result)==0: return result
00293         mp=self.selectedDiskMountPoint()+"/"
00294         result=map(lambda x: x.replace(mp,"",1), result)
00295         return result
00296         
00297 
 Tout Classes Espaces de nommage Fichiers Fonctions Variables