uimain.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. from ui import Ui_MainWindow
  2. from PyQt5 import QtCore, QtGui, QtWidgets
  3. import platform
  4. from icopy2xls import Mover
  5. import os
  6. import xlrd
  7. from icopy2xls.FilesOpen import FilesOpen
  8. import json
  9. from time import sleep
  10. class MainWindow(Ui_MainWindow):
  11. """ BaangtUI : Logic implementation file for uidesign
  12. """
  13. switch_window = QtCore.pyqtSignal(str)
  14. def __init__(self):
  15. ''' Init the super class '''
  16. super().__init__()
  17. def setupUi(self, MainWindow, directory=None):
  18. ''' Setup the UI for super class and Implement the
  19. logic here we want to do with User Interface
  20. '''
  21. super().setupUi(MainWindow)
  22. self.row_list = []
  23. self.filters = {}
  24. self.sheet_headers = []
  25. self.sourceFiles = []
  26. self.sourceBrowsePushButton.clicked.connect(self.sourceBrowsePathSlot)
  27. self.destinationBrowsePushButton.clicked.connect(self.destinationBrowsePathSlot)
  28. self.filterButton.clicked.connect(self.filterDialog)
  29. self.runButton.clicked.connect(self.runMain)
  30. self.openResultFilePushButton.clicked.connect(self.openResultFile)
  31. self.loadJsonFile()
  32. def sourceBrowsePathSlot(self):
  33. """ Browse Folder Containing *.xlsx file for execution. And
  34. globals.json file for Test specific settings
  35. """
  36. # get path from pathLineEdit
  37. basepath = self.sourcePathLineEdit.text()
  38. if not basepath:
  39. basepath = "./"
  40. options = QtWidgets.QFileDialog.Options()
  41. options |= QtWidgets.QFileDialog.DontUseNativeDialog
  42. dirName = QtWidgets.QFileDialog.getOpenFileNames(
  43. None,
  44. "Select File ",
  45. basepath,
  46. options=options,
  47. filter="Excel (*.xlsx *.xls)"
  48. )
  49. if dirName:
  50. # self.pathLineEdit.insert(dirName)
  51. self.setupBasePath(dirName, "source")
  52. def destinationBrowsePathSlot(self):
  53. """ Browse Folder Containing *.xlsx file for execution. And
  54. globals.json file for Test specific settings
  55. """
  56. # get path from pathLineEdit
  57. basepath = self.destinationPathLineEdit.text()
  58. if not basepath:
  59. basepath = "./"
  60. options = QtWidgets.QFileDialog.Options()
  61. options |= QtWidgets.QFileDialog.DontUseNativeDialog
  62. dirName = QtWidgets.QFileDialog.getOpenFileName(
  63. None,
  64. "Select File ",
  65. basepath,
  66. options=options,
  67. filter="Excel (*.xlsx *.xls)"
  68. )
  69. if dirName:
  70. # self.pathLineEdit.insert(dirName)
  71. self.setupBasePath(dirName, "destination")
  72. def setupBasePath(self, dirPath="", typ=""):
  73. """ Setup Base path of Execution as per directory Path"""
  74. if not dirPath:
  75. # Set up base path to Baangt directory
  76. # Based on current File path ../../../
  77. dirPath = os.path.dirname(os.path.dirname(
  78. os.path.dirname(os.path.dirname(__file__))
  79. ))
  80. if not dirPath:
  81. dirPath = os.path.abspath(os.curdir)
  82. if typ == "source":
  83. self.sourcePathLineEdit.insert(dirPath)
  84. self.sourceFiles = dirPath
  85. else:
  86. self.destinationPathLineEdit.insert(dirPath)
  87. else:
  88. if typ == "source":
  89. self.sourcePathLineEdit.setText(", ".join(dirPath[0]))
  90. self.sourceFiles = dirPath[0]
  91. else:
  92. self.destinationPathLineEdit.setText(dirPath[0])
  93. self.statusbar.showMessage(f"Current {typ} Path: {dirPath} ", 2000)
  94. if typ == "source":
  95. self.getSheetsSource(dirPath[0][0])
  96. else:
  97. self.getSheetsDestination(dirPath[0])
  98. def getSheetsSource(self, dirName):
  99. """ Scan for *.xlsx files and *.json files and
  100. update the testRunComboBox and settingsComboBox items
  101. """
  102. wb = xlrd.open_workbook(dirName)
  103. Sheets = wb.sheet_names()
  104. self.sourceSheetComboBox.clear()
  105. # Add files in Combo Box
  106. self.sourceSheetComboBox.addItems(Sheets)
  107. # set default selection to 0
  108. if len(Sheets) > 0:
  109. self.sourceSheetComboBox.setCurrentIndex(0)
  110. selectedSheet = self.sourceSheetComboBox.currentText()
  111. self.statusbar.showMessage("Sheet: {}".format(selectedSheet), 3000)
  112. def getSheetsDestination(self, dirName):
  113. """ Scan for *.xlsx files and *.json files and
  114. update the testRunComboBox and settingsComboBox items
  115. """
  116. wb = xlrd.open_workbook(dirName)
  117. Sheets = wb.sheet_names()
  118. self.destinationSheetComboBox.clear()
  119. # Add files in Combo Box
  120. self.destinationSheetComboBox.addItems(Sheets)
  121. # set default selection to 0
  122. if len(Sheets) > 0:
  123. self.destinationSheetComboBox.setCurrentIndex(0)
  124. selectedSheet = self.destinationSheetComboBox.currentText()
  125. self.statusbar.showMessage("Sheet: {}".format(selectedSheet), 3000)
  126. def filterDialog(self):
  127. self.row_list = []
  128. self.update_headers()
  129. self.filter_dialog = QtWidgets.QDialog(self.centralwidget)
  130. self.filter_dialog.setWindowTitle("Filters")
  131. self.vlay = QtWidgets.QVBoxLayout()
  132. hori = QtWidgets.QHBoxLayout()
  133. hori.setSpacing(10)
  134. add_button = QtWidgets.QPushButton("Add", self.filter_dialog)
  135. add_button.setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(114, 159, 207);")
  136. sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
  137. sizePolicy.setHorizontalStretch(0)
  138. sizePolicy.setVerticalStretch(0)
  139. sizePolicy.setHeightForWidth(add_button.sizePolicy().hasHeightForWidth())
  140. add_button.setSizePolicy(sizePolicy)
  141. save_button = QtWidgets.QPushButton("Save", self.filter_dialog)
  142. save_button.setStyleSheet("color: rgb(255, 255, 255); background-color: rgb(138, 226, 52);")
  143. sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
  144. sizePolicy.setHorizontalStretch(0)
  145. sizePolicy.setVerticalStretch(0)
  146. sizePolicy.setHeightForWidth(save_button.sizePolicy().hasHeightForWidth())
  147. save_button.setSizePolicy(sizePolicy)
  148. hori.addWidget(add_button)
  149. hori.addWidget(save_button)
  150. self.vlay.addLayout(hori)
  151. self.filter_dialog.setLayout(self.vlay)
  152. add_button.clicked.connect(self.add_row)
  153. save_button.clicked.connect(self.save_filters)
  154. for data in self.filters:
  155. if not data:
  156. continue
  157. self.update_filterDialog(data, self.filters[data])
  158. self.filter_dialog.exec_()
  159. def update_headers(self):
  160. source_file = self.sourceFiles
  161. if isinstance(source_file, list):
  162. source_file = source_file[0]
  163. if source_file:
  164. wb = xlrd.open_workbook(source_file)
  165. sht = wb.sheet_by_name(self.sourceSheetComboBox.currentText())
  166. self.sheet_headers = [s.value for s in sht.row(0)]
  167. def update_filterDialog(self, key, value):
  168. for val in value:
  169. hr = QtWidgets.QHBoxLayout()
  170. hr.setSpacing(10)
  171. cb = QtWidgets.QComboBox()
  172. cb.setMinimumSize(QtCore.QSize(200, 0))
  173. cb.setMaximumSize(QtCore.QSize(250, 16777215))
  174. cb.setStyleSheet("background-color: rgb(255, 255, 255);")
  175. line = QtWidgets.QLineEdit()
  176. line.setMinimumSize(QtCore.QSize(300, 0))
  177. line.setMaximumSize(QtCore.QSize(350, 16777215))
  178. line.setStyleSheet("background-color: rgb(255, 255, 255);")
  179. cb.addItems(self.sheet_headers)
  180. cb.setCurrentIndex(self.sheet_headers.index(key))
  181. line.setText(val)
  182. hr.addWidget(cb)
  183. hr.addWidget(line)
  184. removeButton = QtWidgets.QPushButton()
  185. removeButton.setText("-")
  186. removeButton.clicked.connect(lambda: self.remove_row([cb, line, hr, removeButton]))
  187. sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
  188. sizePolicy.setHorizontalStretch(0)
  189. sizePolicy.setVerticalStretch(0)
  190. sizePolicy.setHeightForWidth(self.mainGroupBox.sizePolicy().hasHeightForWidth())
  191. removeButton.setSizePolicy(sizePolicy)
  192. hr.addWidget(removeButton)
  193. self.vlay.addLayout(hr)
  194. self.row_list.append([cb, line, hr, removeButton])
  195. def add_row(self):
  196. hr = QtWidgets.QHBoxLayout()
  197. hr.setSpacing(10)
  198. cb = QtWidgets.QComboBox()
  199. cb.setMinimumSize(QtCore.QSize(200, 0))
  200. cb.setMaximumSize(QtCore.QSize(250, 16777215))
  201. cb.setStyleSheet("background-color: rgb(255, 255, 255);")
  202. cb.addItems(self.sheet_headers)
  203. line = QtWidgets.QLineEdit()
  204. line.setMinimumSize(QtCore.QSize(300, 0))
  205. line.setMaximumSize(QtCore.QSize(350, 16777215))
  206. line.setStyleSheet("background-color: rgb(255, 255, 255);")
  207. hr.addWidget(cb)
  208. hr.addWidget(line)
  209. removeButton = QtWidgets.QPushButton()
  210. removeButton.setText("-")
  211. removeButton.clicked.connect(lambda: self.remove_row([cb, line, hr, removeButton]))
  212. sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
  213. sizePolicy.setHorizontalStretch(0)
  214. sizePolicy.setVerticalStretch(0)
  215. sizePolicy.setHeightForWidth(self.mainGroupBox.sizePolicy().hasHeightForWidth())
  216. removeButton.setSizePolicy(sizePolicy)
  217. hr.addWidget(removeButton)
  218. self.vlay.addLayout(hr)
  219. self.row_list.append([cb, line, hr, removeButton])
  220. def remove_row(self, last):
  221. key = last[0].currentText()
  222. if key in self.filters:
  223. self.filters[key].remove(last[1].text())
  224. if not self.filters[key]:
  225. del self.filters[key]
  226. for l in last:
  227. l.deleteLater()
  228. if last in self.row_list:
  229. self.row_list.remove(last)
  230. def save_filters(self):
  231. filters = {}
  232. if self.row_list:
  233. for row in self.row_list:
  234. key = row[0].currentText()
  235. if key not in filters:
  236. filters[key] = [row[1].text()]
  237. else:
  238. filters[key].append(row[1].text())
  239. self.filters = filters
  240. self.filter_dialog.close()
  241. def runMain(self):
  242. source, source_sheet, destination, destination_sheet = self.check_fields()
  243. if not source and not source_sheet and not destination and not destination_sheet:
  244. pass
  245. else:
  246. self.statusbar.showMessage("Running...", 3000)
  247. lines = self.linesInput.text()
  248. mover = Mover(source, source_sheet, destination, destination_sheet, lines)
  249. mover.move(self.filters, self.addMissingCheckBox.isChecked())
  250. self.statusbar.showMessage("Completed...", 3000)
  251. self.saveJsonFile(
  252. source, source_sheet, destination, destination_sheet,
  253. lines, self.filters, self.addMissingCheckBox.isChecked()
  254. )
  255. def check_fields(self):
  256. source = self.sourceFiles
  257. source_sheet = self.sourceSheetComboBox.currentText()
  258. destination = self.destinationPathLineEdit.text()
  259. destination_sheet = self.destinationSheetComboBox.currentText()
  260. if not source:
  261. self.statusbar.showMessage(f"Source file path is invalid! Please check", 5000)
  262. elif not source_sheet:
  263. self.statusbar.showMessage(f"Source sheet name is invalid! Please check", 5000)
  264. elif not destination:
  265. self.statusbar.showMessage(f"Destination file path is invalid! Please check", 5000)
  266. elif not destination_sheet:
  267. self.statusbar.showMessage(f"Destination sheet name is invalid! Please check", 5000)
  268. return source, source_sheet, destination, destination_sheet
  269. def openResultFile(self):
  270. destinationFile = self.destinationPathLineEdit.text()
  271. if destinationFile:
  272. if os.path.exists(destinationFile):
  273. FilesOpen.openResultFile(destinationFile)
  274. else:
  275. self.statusbar.showMessage(f"File doesn't exist : {destinationFile}")
  276. else:
  277. self.statusbar.showMessage(f"No destination File selected")
  278. def saveJsonFile(self, source, source_sht, dest, dest_sht, lines, filters, addMissing):
  279. path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "settings.json")
  280. js = {"source": source, "source_sheet": source_sht,
  281. "destination": dest, "destination_sheet": dest_sht,
  282. "lines": lines, "filters": filters, "addMissingColumn": addMissing}
  283. with open(path, 'w') as file:
  284. file.write(json.dumps(js))
  285. def loadJsonFile(self):
  286. path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "settings.json")
  287. if not os.path.exists(path):
  288. return
  289. js = json.load(open(path))
  290. self.sourceFiles = js["source"]
  291. self.sourcePathLineEdit.setText(", ".join(self.sourceFiles))
  292. self.getSheetsSource(self.sourceFiles[0])
  293. index_source = self.sourceSheetComboBox.findText(js["source_sheet"], QtCore.Qt.MatchFixedString)
  294. if index_source >= 0:
  295. self.sourceSheetComboBox.setCurrentIndex(index_source)
  296. self.destinationPathLineEdit.setText(js["destination"])
  297. self.getSheetsDestination(js["destination"])
  298. index_destination = self.destinationSheetComboBox.findText(js["destination_sheet"], QtCore.Qt.MatchFixedString)
  299. if index_destination >= 0:
  300. self.destinationSheetComboBox.setCurrentIndex(index_destination)
  301. self.linesInput.setText(js["lines"])
  302. self.filters = js["filters"]
  303. self.addMissingCheckBox.setChecked(js["addMissingColumn"])
  304. class MainController:
  305. def __init__(self):
  306. self.widget = QtWidgets.QWidget()
  307. self.window = QtWidgets.QMainWindow()
  308. self.main = MainWindow()
  309. def show_main(self):
  310. self.main = MainWindow()
  311. self.main.setupUi(self.window)
  312. self.window.show()
  313. if __name__ == "__main__":
  314. import sys
  315. app = QtWidgets.QApplication(sys.argv)
  316. if platform.system() == "Linux":
  317. QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
  318. elif platform.system() == "Darwin":
  319. QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create('Windows'))
  320. controller = MainController()
  321. controller.show_main()
  322. sys.exit(app.exec_())