PageRenderTime 197ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/plottotable/guiController.py

https://gitlab.com/dilipv46/plot-to-table-2016
Python | 426 lines | 374 code | 39 blank | 13 comment | 17 complexity | d02a09d3c134fea678a197024b320720 MD5 | raw file
  1. from __future__ import division
  2. from functools import partial
  3. from PyQt4 import QtGui,QtCore # Import the PyQt4 module we'll need
  4. from subprocess import call
  5. import os # For listing directory methods
  6. import sys # We need sys so that we can pass argv to QApplication
  7. import time
  8. import gui # This file holds our MainWindow and all design related things
  9. import plottotable
  10. from generateTables import getTables, printTables
  11. from utils import mergeOutput, clean, plotCSV
  12. multicrop_images_dir = "multicrop-output/"
  13. multicrop_ext_images_dir = "multicrop-ext-output/"
  14. csv_output_dir = "csv-output/"
  15. pdf_output_dir = "pdf-output/"
  16. fold_path = pdf_output_dir
  17. # it also keeps events etc that we defined in Qt Designer
  18. index =0
  19. list_path = []
  20. layout_pic_area = QtGui.QVBoxLayout()
  21. layout_pic_hold = QtGui.QVBoxLayout()
  22. is_default_pic_displayed = 0
  23. class MyDialog(QtGui.QDialog):
  24. def __init__(self, parent=None):
  25. super(MyDialog, self).__init__()
  26. self.setWindowTitle('Processing files...')
  27. self.resize(300, 70)
  28. self.openButton = QtGui.QPushButton('Start')
  29. self.textBrowser = QtGui.QLabel(self)
  30. self.textBrowser.setText("Click start to start processing")
  31. self.verticalLayout = QtGui.QHBoxLayout(self)
  32. self.verticalLayout.addWidget(self.openButton)
  33. self.verticalLayout.addWidget(self.textBrowser)
  34. def iteratorthis(self,fileName, form):
  35. self.openButton.setEnabled(False)
  36. empty_layouts(form)
  37. QtGui.qApp.processEvents()
  38. self.textBrowser.setText("Extracting Plot images from input PDF...")
  39. QtGui.qApp.processEvents()
  40. plottotable.process_pdf(fileName)
  41. number_of_plots = 0
  42. for ff in sorted(os.listdir(multicrop_images_dir)):
  43. if ff.endswith('.ppm'):
  44. number_of_plots += 1
  45. if number_of_plots == 0:
  46. self.close()
  47. showdialog("No plots found in Input PDF")
  48. else:
  49. self.textBrowser.setText(str(number_of_plots) + " Plots extracted")
  50. QtGui.qApp.processEvents()
  51. file_number = 1
  52. error = 0
  53. for f in sorted(os.listdir(multicrop_images_dir)):
  54. error = 0
  55. # Processing image
  56. error = getTables(f)
  57. if not error == -1:
  58. # converting all PDF outputs to PNG
  59. convert_pdfs_to_png(f)
  60. # Showing all image thumbnails in left pane
  61. showimage_thumbnails(form,layout_pic_area, f)
  62. self.textBrowser.setText("Processed " + str(file_number) + " of " + str(number_of_plots))
  63. QtGui.qApp.processEvents()
  64. if error == -1:
  65. showdialog("Could not generate data for some of the extracted plots")
  66. QtGui.qApp.processEvents()
  67. self.close()
  68. class QLabel_new(QtGui.QLabel):
  69. def __init__(self, parent = None):
  70. QtGui.QLabel.__init__(self, parent)
  71. def mousePressEvent(self, ev):
  72. highlight_handler()
  73. self.setFrameStyle(QtGui.QFrame.Panel)
  74. self.setLineWidth(5)
  75. self.emit(QtCore.SIGNAL('clicked()'))
  76. class ClickHandler():
  77. def __init__(self, time):
  78. self.timer = QtCore.QTimer()
  79. self.timer.setInterval(time)
  80. self.timer.setSingleShot(True)
  81. self.timer.timeout.connect(self.timeout)
  82. self.click_count = 0
  83. def timeout(self):
  84. if self.click_count == 1:
  85. # print('Single click')
  86. self.emit(QtCore.SIGNAL('clicked()'))
  87. elif self.click_count > 1:
  88. print('Double click')
  89. self.click_count = 0
  90. def __call__(self):
  91. self.click_count += 1
  92. if not self.timer.isActive():
  93. self.timer.start()
  94. class ExampleApp(QtGui.QMainWindow, gui.Ui_MainWindow):
  95. def __init__(self):
  96. # Explaining super is out of the scope of this article
  97. # So please google it if you're not familar with it
  98. # Simple reason why we use it here is that it allows us to
  99. # access variables, methods etc in the design.py file
  100. super(self.__class__, self).__init__()
  101. self.setupUi(self) # This is defined in design.py file automatically
  102. self.showMaximized()
  103. self.setWindowTitle('plot2table')
  104. def browse_folder(self):
  105. self.listWidget.clear() # In case there are any existing elements in the list
  106. directory = QtGui.QFileDialog.getExistingDirectory(self,
  107. "Pick a folder")
  108. # execute getExistingDirectory dialog and set the directory variable to be equal
  109. # to the user selected directory
  110. if directory: # if user didn't pick a directory don't continue
  111. for file_name in os.listdir(directory): # for all files, if any, in the directory
  112. self.listWidget.addItem(file_name) # add file to the listWidget
  113. def add_pic_to_display(self,event,name,checked = False):
  114. global layout_pic_hold
  115. disp_contents = QtGui.QWidget(self.pic_hold)
  116. layout = QtGui.QVBoxLayout(disp_contents)
  117. layout_pic_hold = layout
  118. self.pic_hold.setWidget(disp_contents)
  119. name = (name.split('.'))[0]
  120. path = fold_path + name
  121. print "reached "+path
  122. for ff in sorted(os.listdir(path)):
  123. if ff.endswith('.jpeg') or ff.endswith('.png'):
  124. label = QtGui.QLabel()
  125. pixmap = QtGui.QPixmap(path+'/'+ff)
  126. # pixmap = pixmap.scaledToWidth(self.pic_hold.frameGeometry().width(),self.pic_hold.frameGeometry().height(),QtCore.Qt.KeepAspectRatio, transformMode = QtCore.Qt.SmoothTransformation)
  127. pixmap = pixmap.scaledToWidth(self.pic_hold.frameGeometry().width()-150, QtCore.Qt.SmoothTransformation)
  128. label.setPixmap(pixmap)
  129. label.setAlignment(QtCore.Qt.AlignCenter)
  130. layout.addWidget(label)
  131. def actOpen(self,form,layout):
  132. # opening file chooser
  133. try:
  134. path = plottotable.__file__[:-12]
  135. path += "test-inputs/"
  136. fileName = QtGui.QFileDialog.getOpenFileName(self,
  137. "Choose Input File", path,
  138. "All Files (*.pdf)")
  139. except Exception,e:
  140. print str(e)
  141. fileName = QtGui.QFileDialog.getOpenFileName(self,
  142. "Choose Input File", '',
  143. "All Files (*.pdf)")
  144. if not len(fileName) == 0:
  145. global index
  146. index= 0
  147. global list_path
  148. list_path = []
  149. global is_default_pic_displayed
  150. is_default_pic_displayed = 0
  151. dialogTextBrowser = MyDialog(self)
  152. # Creating dialog for image processing
  153. dialogTextBrowser.connect(dialogTextBrowser.openButton, QtCore.SIGNAL('clicked()'), partial(dialogTextBrowser.iteratorthis,fileName, form))
  154. dialogTextBrowser.exec_()
  155. def actPrint(self,form,layout):
  156. selected_images = []
  157. for i in range(layout.count()):
  158. item = layout.itemAt(i)
  159. if item is not None:
  160. widget = item.widget()
  161. if type(widget) is QtGui.QCheckBox:
  162. if widget.isChecked():
  163. print "--"+str(int(i/2)+1)+" checked --\n"
  164. print list_path[(int(i/2))]+"\n"
  165. selected_images.append(list_path[int(i/2)])
  166. if len(list_path) == 0:
  167. showdialog("Please upload Input PDF first")
  168. else:
  169. if len(selected_images) == 0:
  170. showdialog("Please select at least one image")
  171. else:
  172. mergeOutput(selected_images, "./print.pdf")
  173. dialog = QtGui.QPrintDialog()
  174. if dialog.exec_() == QtGui.QDialog.Accepted:
  175. self.editor.document().print_(dialog.printer())
  176. def empty_layouts(form):
  177. global layout_pic_hold
  178. global layout_pic_area
  179. layout = layout_pic_area
  180. clearLayout(layout)
  181. layout = layout_pic_hold
  182. clearLayout(layout)
  183. def clearLayout(layout):
  184. while layout.count():
  185. child = layout.takeAt(0)
  186. if child.widget() is not None:
  187. child.widget().deleteLater()
  188. elif child.layout() is not None:
  189. clearLayout(child.layout())
  190. def convert_pdfs_to_png(_file):
  191. # for subdir, dirs, files in os.walk(fold_path):
  192. # for _file in files:
  193. # if _file.endswith('.pdf'):
  194. name = _file.split('.')[0]
  195. pdf_file = name + ".pdf"
  196. os.mkdir(fold_path + name)
  197. call(["pdftoppm","-png","-r","300",fold_path+pdf_file, fold_path+name+'/new'])
  198. def showimage_thumbnails(form,layout, _file):
  199. jpeg_file = _file.split('.')[0] + ".jpeg"
  200. print fold_path + jpeg_file
  201. add_pic_to_thumbnails(form, jpeg_file, layout)
  202. def add_pic_to_thumbnails(form, name, layout):
  203. global index
  204. global list_path
  205. global is_default_pic_displayed
  206. index = index +1
  207. label = QLabel_new()
  208. path = fold_path + name
  209. pixmap = QtGui.QPixmap(path)
  210. list_path.append(name)
  211. form.connect(label, QtCore.SIGNAL('clicked()'), partial(form.add_pic_to_display,form,name))
  212. pixmap = pixmap.scaledToWidth(form.pic_area.frameGeometry().width()-40, QtCore.Qt.SmoothTransformation)
  213. label.setPixmap(pixmap)
  214. layout.addWidget(label)
  215. box = QtGui.QCheckBox()
  216. box.setText(' '+str(index))
  217. layout.addWidget(box)
  218. if(is_default_pic_displayed==0) :
  219. label.emit(QtCore.SIGNAL('clicked()'))
  220. label.setFrameStyle(QtGui.QFrame.Panel)
  221. label.setLineWidth(5)
  222. is_default_pic_displayed = 1
  223. def selected_pdfs(form,layout):
  224. global index
  225. selected_images = []
  226. for i in range(layout.count()):
  227. item = layout.itemAt(i)
  228. if item is not None:
  229. widget = item.widget()
  230. if type(widget) is QtGui.QCheckBox:
  231. if widget.isChecked():
  232. print "--"+str(int(i/2)+1)+" checked --\n"
  233. print list_path[(int(i/2))]+"\n"
  234. selected_images.append(list_path[int(i/2)])
  235. if len(list_path) == 0:
  236. showdialog("Please upload Input PDF first")
  237. else:
  238. if len(selected_images) == 0:
  239. showdialog("Please select at least one image.")
  240. else:
  241. fileName = QtGui.QFileDialog.getSaveFileName(form,
  242. "Choose Path and File name", '',
  243. "All Files (*.pdf)")
  244. mergeOutput(selected_images, fileName)
  245. def plot_data(form,layout):
  246. global index
  247. selected_images = []
  248. for i in range(layout.count()):
  249. item = layout.itemAt(i)
  250. if item is not None:
  251. widget = item.widget()
  252. if type(widget) is QtGui.QCheckBox:
  253. if widget.isChecked():
  254. print "--"+str(int(i/2)+1)+" checked --\n"
  255. print list_path[(int(i/2))]+"\n"
  256. selected_images.append(list_path[int(i/2)])
  257. if len(list_path) == 0:
  258. showdialog("Please upload Input PDF first")
  259. else:
  260. if len(selected_images) == 0:
  261. showdialog("Please select at least one image.")
  262. else:
  263. for img in selected_images:
  264. plotCSV(img)
  265. def pdf_help(form):
  266. disp_contents = QtGui.QWidget(form.pic_hold)
  267. layout = QtGui.QVBoxLayout(disp_contents)
  268. layout_pic_hold = layout
  269. form.pic_hold.setWidget(disp_contents)
  270. path = plottotable.__file__[:-12]
  271. path += "user-manual/"
  272. for ff in sorted(os.listdir(path)):
  273. if ff.endswith('.jpeg') or ff.endswith('.png'):
  274. label = QtGui.QLabel()
  275. pixmap = QtGui.QPixmap(path+'/'+ff)
  276. # pixmap = pixmap.scaledToWidth(form.pic_hold.frameGeometry().width(),form.pic_hold.frameGeometry().height(),QtCore.Qt.KeepAspectRatio, transformMode = QtCore.Qt.SmoothTransformation)
  277. pixmap = pixmap.scaledToWidth(form.pic_hold.frameGeometry().width()-150, QtCore.Qt.SmoothTransformation)
  278. label.setPixmap(pixmap)
  279. label.setAlignment(QtCore.Qt.AlignCenter)
  280. layout.addWidget(label)
  281. def showdialog(text):
  282. msg = QtGui.QMessageBox()
  283. msg.setIcon(QtGui.QMessageBox.Warning)
  284. msg.setText(text)
  285. msg.setWindowTitle("Note")
  286. msg.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
  287. msg.exec_()
  288. def highlight_handler():
  289. layout = layout_pic_area
  290. for i in range(layout.count()):
  291. item = layout.itemAt(i)
  292. if item is not None:
  293. widget = item.widget()
  294. if type(widget) is QLabel_new:
  295. widget.setFrameStyle(QtGui.QFrame.NoFrame)
  296. def main():
  297. global layout_pic_area
  298. app = QtGui.QApplication(sys.argv) # A new instance of QApplication
  299. form = ExampleApp() # We set the form to be our ExampleApp (design)
  300. form.pic_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
  301. scrollContents = QtGui.QWidget()
  302. layout = QtGui.QVBoxLayout(scrollContents)
  303. layout_pic_area = layout
  304. form.pic_area.setWidget(scrollContents)
  305. layout.setAlignment(QtCore.Qt.AlignTop)
  306. p = scrollContents.palette()
  307. p.setColor(scrollContents.backgroundRole(), QtCore.Qt.white)
  308. scrollContents.setPalette(p)
  309. q = form.widget_4.palette()
  310. q.setColor(form.widget_4.backgroundRole(), QtCore.Qt.red)
  311. form.widget_4.setPalette(q)
  312. # Utility panel and File buttons
  313. try:
  314. form.open_btn.clicked.connect(partial(form.actOpen,form,layout))
  315. form.connect(form.actionOpen, QtCore.SIGNAL('triggered()'), partial(form.actOpen,form,layout))
  316. except Exception,e:
  317. print str(e)
  318. showdialog("Could not Open Input PDF")
  319. try:
  320. form.save_btn.clicked.connect(partial(selected_pdfs,form,layout))
  321. form.connect(form.actionPlot, QtCore.SIGNAL('triggered()'), partial(plot_data,form,layout))
  322. except Exception,e:
  323. print str(e)
  324. showdialog("Could not Save selected files")
  325. try:
  326. form.plot_btn.clicked.connect(partial(plot_data,form,layout))
  327. form.connect(form.actionSave, QtCore.SIGNAL('triggered()'), partial(selected_pdfs,form,layout))
  328. except Exception,e:
  329. print str(e)
  330. showdialog("Could not Plot selected files")
  331. try:
  332. form.print_btn.clicked.connect(partial(form.actPrint,form,layout))
  333. form.connect(form.actionPrint, QtCore.SIGNAL('triggered()'), partial(form.actPrint,form,layout))
  334. except Exception,e:
  335. print str(e)
  336. showdialog("Could not Print selected files")
  337. # Help buttons
  338. try:
  339. form.connect(form.actionusermanual, QtCore.SIGNAL('triggered()'), partial(pdf_help,form))
  340. except Exception,e:
  341. print str(e)
  342. showdialog("Could not load User Manual")
  343. form.show() # Show the form
  344. _exit = app.exec_() # and execute the app
  345. # Exit code
  346. clean()
  347. sys.exit(_exit)