Import LinuxCNC source tree
This commit is contained in:
407
share/qtvcp/panels/copy/copy_handler.py
Normal file
407
share/qtvcp/panels/copy/copy_handler.py
Normal file
@@ -0,0 +1,407 @@
|
||||
############################
|
||||
# **** IMPORT SECTION **** #
|
||||
############################
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
from qtpy.QtCore import *
|
||||
from qtpy.QtGui import *
|
||||
from qtpy.QtWidgets import *
|
||||
from qtvcp.widgets.file_manager import FileManager as FM
|
||||
from qtvcp.core import Info
|
||||
###########################################
|
||||
# **** instantiate libraries section **** #
|
||||
###########################################
|
||||
INFO = Info()
|
||||
|
||||
###################################
|
||||
# **** HANDLER CLASS SECTION **** #
|
||||
###################################
|
||||
|
||||
class HandlerClass:
|
||||
|
||||
########################
|
||||
# **** INITIALIZE **** #
|
||||
########################
|
||||
# widgets allows access to widgets from the qtvcp files
|
||||
# at this point the widgets and hal pins are not instantiated
|
||||
def __init__(self, halcomp,widgets,paths):
|
||||
self.w = widgets
|
||||
self.paths = paths
|
||||
self.help = HelpDialog()
|
||||
|
||||
##########################################
|
||||
# Special Functions called from QTVCP
|
||||
##########################################
|
||||
|
||||
# at this point:
|
||||
# the widgets are instantiated.
|
||||
# the HAL pins are built but HAL is not set ready
|
||||
def initialized__(self):
|
||||
self.w.setWindowTitle(' QtVCP Builtin Screen Code Copier')
|
||||
self.w.filemanager.showList(True)
|
||||
self.w.filemanager.model.setNameFilters([''])
|
||||
self.w.filemanager.cb.hide()
|
||||
self.w.filemanager.addButton.hide()
|
||||
self.w.filemanager.delButton.hide()
|
||||
self.w.filemanager.loadButton.hide()
|
||||
self.w.filemanager.copy_control.hide()
|
||||
self.w.filemanager.user_path = os.path.expanduser('~/linuxcnc/configs')
|
||||
if os.path.exists(self.paths.RIPCONFIGDIR):
|
||||
self.w.filemanager._jumpList.update([('RIP',self.paths.RIPCONFIGDIR)])
|
||||
self.w.filemanager.addAction('RIP')
|
||||
self.w.filemanager._jumpList.update([('Desktop',os.path.expanduser('~/Desktop'))])
|
||||
self.w.filemanager.addAction('Desktop')
|
||||
|
||||
self.w.filemanager.updateDirectoryView(self.w.filemanager.user_path)
|
||||
self.list_screen_files()
|
||||
self.w.comboBox.currentIndexChanged.connect(self.selectionchange)
|
||||
self.w.lineEdit.setText(self.w.comboBox.currentText())
|
||||
|
||||
########################
|
||||
# callbacks #
|
||||
########################
|
||||
def selectionchange(self,i):
|
||||
self.w.lineEdit.setText(self.w.comboBox.currentText())
|
||||
|
||||
#######################
|
||||
# callbacks from form #
|
||||
#######################
|
||||
def applyClicked(self):
|
||||
basename = self.w.lineEdit.text()
|
||||
if basename == '': basename = self.w.comboBox.currentText()
|
||||
|
||||
# VCP panel
|
||||
if self.w.radiobutton_vcp.isChecked():
|
||||
path = os.path.join(self.paths.PANELDIR, self.w.comboBox.currentText())
|
||||
|
||||
# vismach
|
||||
elif self.w.radiobutton_vismach.isChecked():
|
||||
self.copyVismachFiles(self.paths.VISMACHDIR, self.w.filemanager.textLine.text(),
|
||||
basename, self.w.comboBox.currentText() )
|
||||
|
||||
# check for vismach object directory
|
||||
objname = self.w.comboBox.currentText().strip('.py')
|
||||
objname = objname + '_obj'
|
||||
objpath = os.path.join(self.paths.VISMACHDIR, objname)
|
||||
objbasename = basename.strip('.py') + '_obj'
|
||||
if os.path.exists(objpath):
|
||||
self.copyVismachFiles(self.paths.VISMACHDIR, self.w.filemanager.textLine.text(),
|
||||
objbasename, objname )
|
||||
return
|
||||
|
||||
# screen
|
||||
else:
|
||||
path = os.path.join(self.paths.SCREENDIR, self.w.comboBox.currentText())
|
||||
|
||||
self.copyFilesWithCheck(path, self.w.filemanager.textLine.text(),
|
||||
basename, self.w.comboBox.currentText() )
|
||||
|
||||
def updateCombo(self, value):
|
||||
rbtn = self.w.sender()
|
||||
if rbtn.isChecked() == True:
|
||||
self.w.groupBoxType.setEnabled(False)
|
||||
if rbtn == self.w.radiobutton_vcp:
|
||||
self.list_vcp_files()
|
||||
elif rbtn == self.w.radiobutton_vismach:
|
||||
self.list_vismach_files()
|
||||
else:
|
||||
self.list_screen_files()
|
||||
self.w.groupBoxType.setEnabled(True)
|
||||
|
||||
def helpClicked(self):
|
||||
self.help.showDialog()
|
||||
|
||||
#####################
|
||||
# general functions #
|
||||
#####################
|
||||
|
||||
def list_screen_files(self):
|
||||
self.w.comboBox.clear()
|
||||
for i in sorted(self.paths.find_screen_dirs()):
|
||||
self.w.comboBox.addItem(i)
|
||||
|
||||
def list_vcp_files(self):
|
||||
self.w.comboBox.clear()
|
||||
for i in sorted(self.paths.find_panel_dirs()):
|
||||
self.w.comboBox.addItem(i)
|
||||
|
||||
def list_vismach_files(self):
|
||||
self.w.comboBox.clear()
|
||||
for i in sorted(self.paths.find_vismach_files()):
|
||||
if '.py' in i:
|
||||
self.w.comboBox.addItem(i)
|
||||
|
||||
def makedirs(self, dest):
|
||||
if not os.path.exists(dest):
|
||||
os.makedirs(dest)
|
||||
|
||||
def copyVismachFiles(self, src, dest, baseName, fileName):
|
||||
rtn = self.confirmDialog(dest, baseName)
|
||||
if not rtn: return
|
||||
|
||||
fromPath = os.path.join(src, fileName)
|
||||
toPath = os.path.join(dest, baseName)
|
||||
# make any needed directory
|
||||
if not os.path.exists(os.path.dirname(toPath)):
|
||||
self.makedirs(os.path.dirname(toPath))
|
||||
|
||||
if not os.path.exists(toPath):
|
||||
if os.path.isfile(fromPath):
|
||||
shutil.copy(fromPath, toPath)
|
||||
# probably vismach object folder
|
||||
elif os.path.isdir(fromPath):
|
||||
shutil.copytree(fromPath, toPath)
|
||||
|
||||
def copyFilesWithCheck(self, src, dest, baseName, srcDirName):
|
||||
|
||||
# make a copy of the user pick destination path
|
||||
ndest = os.path.join(dest)
|
||||
|
||||
# check for lack of standard folders in path
|
||||
folder = ''
|
||||
if self.w.radiobutton_vcp.isChecked():
|
||||
folder = 'panels'
|
||||
elif self.w.radiobutton_screen.isChecked():
|
||||
folder = 'screens'
|
||||
if not folder in dest:
|
||||
r = self.confirmPathDialog('qtvcp/' + folder)
|
||||
if r:
|
||||
if not 'qtvcp' in dest:
|
||||
dest = os.path.join(dest, 'qtvcp')
|
||||
if not folder in dest:
|
||||
dest = os.path.join(dest, folder)
|
||||
# overwrite with the new path
|
||||
ndest = dest
|
||||
if os.path.exists(dest):
|
||||
self.w.filemanager.updateDirectoryView(dest)
|
||||
|
||||
# confirm user wants to copy
|
||||
rtn = self.confirmDialog(ndest, baseName)
|
||||
if not rtn: return
|
||||
|
||||
# add in the basename
|
||||
ndest = os.path.join(ndest, baseName)
|
||||
|
||||
# make any needed initial directory
|
||||
if not os.path.exists(os.path.dirname(ndest)):
|
||||
self.makedirs(os.path.dirname(ndest))
|
||||
|
||||
# update the file manager path
|
||||
if os.path.exists(dest):
|
||||
self.w.filemanager.updateDirectoryView(dest)
|
||||
|
||||
# walk the folder and copy everything
|
||||
for path, dirs, filenames in os.walk(src):
|
||||
if dirs == []:
|
||||
destDir = path.replace(src,ndest)
|
||||
self.makedirs(destDir)
|
||||
else:
|
||||
for directory in dirs:
|
||||
destDir = path.replace(src,ndest)
|
||||
self.makedirs(os.path.join(destDir, directory))
|
||||
|
||||
# files
|
||||
for sfile in filenames:
|
||||
if sfile == 'resources.py': continue
|
||||
|
||||
# if source directory name is in file name, rename it.
|
||||
if srcDirName in os.path.splitext(sfile)[0]:
|
||||
dfile = sfile.replace(srcDirName, baseName)
|
||||
else:
|
||||
dfile = sfile
|
||||
|
||||
# use original or subclassed handler?
|
||||
if self.w.checkBoxSubclassHandler.isChecked() and self.w.radiobutton_screen.isChecked():
|
||||
if not '_handler.py' in sfile and not '.ui' in sfile:
|
||||
continue
|
||||
if '_handler.py' in sfile:
|
||||
# substitute subclass handler.py for original handler
|
||||
here = os.path.dirname(os.path.realpath(__file__))
|
||||
srcFile = os.path.join(here, 'subclass_handler.py')
|
||||
destFile = os.path.join(path.replace(src, ndest), dfile)
|
||||
shutil.copy(srcFile, destFile)
|
||||
continue
|
||||
|
||||
srcFile = os.path.join(path, sfile)
|
||||
destFile = os.path.join(path.replace(src, ndest), dfile)
|
||||
|
||||
shutil.copy(srcFile, destFile)
|
||||
|
||||
# last confirm before copying -check for file overwriting
|
||||
def confirmDialog(self, srcPath, name):
|
||||
dest = os.path.join(srcPath, name)
|
||||
info = 'Copy {} Code?'.format(name)
|
||||
if os.path.exists(dest):
|
||||
title = "Confirm: Will Overwrite Existing Files!"
|
||||
else:
|
||||
title = 'Please Confirm:'
|
||||
rtn = self.w.messageDialog_.showdialog(
|
||||
title,
|
||||
more_info=info,
|
||||
details=' To Folder:\n {}'.format(dest),
|
||||
display_type='YESNO',
|
||||
icon=QMessageBox.Information, pinname=None,
|
||||
focus_text=None,
|
||||
focus_color=None,
|
||||
play_alert=None,
|
||||
nblock=False,
|
||||
use_exec =True)
|
||||
if not rtn:
|
||||
return False
|
||||
return True
|
||||
|
||||
# confirm that qtvcp/screens or panels is not needed in path
|
||||
def confirmPathDialog(self, srcPath):
|
||||
dest = os.path.join(srcPath)
|
||||
info = "Destination does not have {} folders in path. This is the usual way for qtvcp to find them. Do you wish to add the folders".format(srcPath)
|
||||
title = 'Add {} to Path?'.format(srcPath)
|
||||
rtn = self.w.messageDialog_.showdialog(
|
||||
title,
|
||||
more_info=info,
|
||||
details=' To Folder:\n {}'.format(dest),
|
||||
display_type='YESNO',
|
||||
icon=QMessageBox.Information, pinname=None,
|
||||
focus_text=None,
|
||||
focus_color=None,
|
||||
play_alert=None,
|
||||
nblock=False,
|
||||
use_exec =True)
|
||||
if not rtn:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class HelpDialog(QDialog):
|
||||
def __init__(self, parent=None):
|
||||
super(HelpDialog, self).__init__(parent)
|
||||
self._title = 'Copy Help'
|
||||
self.setWindowFlags(self.windowFlags() | Qt.Tool |
|
||||
Qt.Dialog | Qt.WindowStaysOnTopHint |
|
||||
Qt.WindowSystemMenuHint)
|
||||
self.currentHelpPage=-1
|
||||
self.setMinimumWidth(400)
|
||||
self.setMinimumHeight(400)
|
||||
self.helpPages = ['copy_help1.html','copy_help2.html',
|
||||
'copy_help3.html', 'copy_help4.html']
|
||||
|
||||
self.buildWidget()
|
||||
|
||||
def buildWidget(self):
|
||||
|
||||
l = QVBoxLayout()
|
||||
t = QTextEdit('Qtvcp Copy Help')
|
||||
t.setReadOnly(True)
|
||||
l.addWidget(t)
|
||||
|
||||
buttons = QDialogButtonBox()
|
||||
|
||||
closebutton = QPushButton()
|
||||
closebutton.setIconSize(QSize(38, 38))
|
||||
closebutton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/standardbutton-cancel-128.png'))
|
||||
closebutton.clicked.connect(lambda : self.close())
|
||||
|
||||
nextbutton = QPushButton()
|
||||
nextbutton.setIconSize(QSize(38, 38))
|
||||
nextbutton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png'))
|
||||
nextbutton.clicked.connect(lambda : self.next(t,True))
|
||||
|
||||
previousbutton = QPushButton()
|
||||
previousbutton.setIconSize(QSize(38, 38))
|
||||
previousbutton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/left-32.png'))
|
||||
previousbutton.clicked.connect(lambda : self.next(t,False))
|
||||
|
||||
self.pageStepUpbutton = QPushButton()
|
||||
self.pageStepUpbutton.setIconSize(QSize(38, 38))
|
||||
self.pageStepUpbutton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/up-32.png'))
|
||||
self.pageStepUpbutton.clicked.connect(lambda : self.pageStep(t,False))
|
||||
|
||||
self.pageStepDwnbutton = QPushButton()
|
||||
self.pageStepDwnbutton.setIconSize(QSize(38, 38))
|
||||
self.pageStepDwnbutton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/down-32.png'))
|
||||
self.pageStepDwnbutton.clicked.connect(lambda : self.pageStep(t,True))
|
||||
|
||||
bBox = QDialogButtonBox(buttons)
|
||||
#bBox.addButton(self.pageStepUpbutton, QDialogButtonBox.ActionRole)
|
||||
#bBox.addButton(self.pageStepDwnbutton, QDialogButtonBox.ActionRole)
|
||||
bBox.addButton(previousbutton, QDialogButtonBox.ActionRole)
|
||||
bBox.addButton(nextbutton, QDialogButtonBox.ActionRole)
|
||||
bBox.addButton(closebutton, QDialogButtonBox.DestructiveRole)
|
||||
bBox.rejected.connect(self.reject)
|
||||
|
||||
l.addWidget(bBox)
|
||||
self.setLayout(l)
|
||||
|
||||
try:
|
||||
self.next(t)
|
||||
except Exception as e:
|
||||
t.setText('Qtvcp Copy Help file Unavailable:\n\n{}'.format(e))
|
||||
|
||||
def next(self,t,direction=None):
|
||||
if direction is None:
|
||||
self.currentHelpPage = 0
|
||||
elif direction:
|
||||
self.currentHelpPage +=1
|
||||
if self.currentHelpPage > len(self.helpPages)-1:
|
||||
self.currentHelpPage = len(self.helpPages)-1
|
||||
else:
|
||||
self.currentHelpPage -=1
|
||||
if self.currentHelpPage < 0:
|
||||
self.currentHelpPage = 0
|
||||
try:
|
||||
pagePath = os.path.join( os.path.dirname(__file__), self.helpPages[self.currentHelpPage])
|
||||
file = QFile(pagePath)
|
||||
file.open(QFile.ReadOnly)
|
||||
html = file.readAll()
|
||||
html = str(html, encoding='utf8')
|
||||
html = html.replace("../images/probe_icons/","{}/probe_icons/".format(INFO.IMAGE_PATH))
|
||||
t.setHtml(html)
|
||||
if t.verticalScrollBar().isVisible():
|
||||
t.verticalScrollBar().setPageStep(20)
|
||||
self.pageStepDwnbutton.show()
|
||||
self.pageStepUpbutton.show()
|
||||
else:
|
||||
self.pageStepDwnbutton.hide()
|
||||
self.pageStepUpbutton.hide()
|
||||
|
||||
except Exception as e:
|
||||
t.setText('Qtvcp Copy file Unavailable:\n\n{}'.format(e))
|
||||
if direction is None:
|
||||
return
|
||||
self.show()
|
||||
|
||||
def pageStep(self, t, state):
|
||||
if state:
|
||||
t.verticalScrollBar().triggerAction (QAbstractSlider.SliderPageStepAdd)
|
||||
else:
|
||||
t.verticalScrollBar().triggerAction (QAbstractSlider.SliderPageStepSub)
|
||||
|
||||
|
||||
def showDialog(self):
|
||||
self.setWindowTitle(self._title);
|
||||
retval = self.exec_()
|
||||
|
||||
#####################
|
||||
# KEY BINDING CALLS #
|
||||
#####################
|
||||
|
||||
###########################
|
||||
# **** closing event **** #
|
||||
###########################
|
||||
|
||||
##############################
|
||||
# required class boiler code #
|
||||
##############################
|
||||
|
||||
def __getitem__(self, item):
|
||||
return getattr(self, item)
|
||||
def __setitem__(self, item, value):
|
||||
return setattr(self, item, value)
|
||||
|
||||
|
||||
################################
|
||||
# required handler boiler code #
|
||||
################################
|
||||
|
||||
def get_handlers(halcomp,widgets,paths):
|
||||
return [HandlerClass(halcomp,widgets,paths)]
|
||||
Reference in New Issue
Block a user