src/eric7/Project/Project.py

branch
server
changeset 10610
bb0149571d94
parent 10605
b6f5e27daeb5
child 10631
00f5aae565a3
equal deleted inserted replaced
10605:b6f5e27daeb5 10610:bb0149571d94
511 self.translationsRoot = "" # the translations prefix 511 self.translationsRoot = "" # the translations prefix
512 self.name = "" 512 self.name = ""
513 self.opened = False 513 self.opened = False
514 self.subdirs = [] 514 self.subdirs = []
515 # record the project dir as a relative path (i.e. empty path) 515 # record the project dir as a relative path (i.e. empty path)
516 self.otherssubdirs = []
517 self.vcs = None 516 self.vcs = None
518 self.vcsRequested = False 517 self.vcsRequested = False
519 self.dbgVirtualEnv = "" 518 self.dbgVirtualEnv = ""
520 self.dbgCmdline = "" 519 self.dbgCmdline = ""
521 self.dbgWd = "" 520 self.dbgWd = ""
979 self.recent = [] 978 self.recent = []
980 Preferences.Prefs.rsettings.sync() 979 Preferences.Prefs.rsettings.sync()
981 rp = Preferences.Prefs.rsettings.value(recentNameProject) 980 rp = Preferences.Prefs.rsettings.value(recentNameProject)
982 if rp is not None: 981 if rp is not None:
983 for f in rp: 982 for f in rp:
984 if pathlib.Path(f).exists(): 983 if (
984 FileSystemUtilities.isRemoteFileName(f)
985 and (
986 not self.__remoteServer.isServerConnected()
987 or self.__remotefsInterface.exists(f)
988 )
989 ) or pathlib.Path(f).exists():
985 self.recent.append(f) 990 self.recent.append(f)
986 991
987 def __saveRecent(self): 992 def __saveRecent(self):
988 """ 993 """
989 Private method to save the list of recently opened filenames. 994 Private method to save the list of recently opened filenames.
1191 dn = ( 1196 dn = (
1192 self.__remotefsInterface.dirname(fn) 1197 self.__remotefsInterface.dirname(fn)
1193 if FileSystemUtilities.isRemoteFileName(fn) 1198 if FileSystemUtilities.isRemoteFileName(fn)
1194 else os.path.dirname(fn) 1199 else os.path.dirname(fn)
1195 ) 1200 )
1196 if dn and dn not in self.otherssubdirs:
1197 self.otherssubdirs.append(dn)
1198 1201
1199 return res 1202 return res
1200 1203
1201 def __writeProject(self, fn=None): 1204 def __writeProject(self, fn=None):
1202 """ 1205 """
2017 self.__pdata["OTHERS"].append(newfn) 2020 self.__pdata["OTHERS"].append(newfn)
2018 self.othersAdded(newfn, updateModel) 2021 self.othersAdded(newfn, updateModel)
2019 dirty = True 2022 dirty = True
2020 else: 2023 else:
2021 updateModel and self.repopulateItem(newfn) 2024 updateModel and self.repopulateItem(newfn)
2022 if newdir not in self.otherssubdirs:
2023 self.otherssubdirs.append(newdir)
2024 2025
2025 if dirty: 2026 if dirty:
2026 self.setDirty(True) 2027 self.setDirty(True)
2027 2028
2028 @pyqtSlot() 2029 @pyqtSlot()
2055 ) 2056 )
2056 if not FileSystemUtilities.samepath( 2057 if not FileSystemUtilities.samepath(
2057 self.__remotefsInterface.dirname(fn) 2058 self.__remotefsInterface.dirname(fn)
2058 if isRemote 2059 if isRemote
2059 else os.path.dirname(fn), 2060 else os.path.dirname(fn),
2060 target 2061 target,
2061 ): 2062 ):
2062 try: 2063 try:
2063 if isRemote: 2064 if isRemote:
2064 if not self.__remotefsInterface.isdir(target): 2065 if not self.__remotefsInterface.isdir(target):
2065 self.__remotefsInterface.makedirs(target) 2066 self.__remotefsInterface.makedirs(target)
2066 else: 2067 else:
2067 if not os.path.isdir(target): 2068 if not os.path.isdir(target):
2068 os.makedirs(target) 2069 os.makedirs(target)
2069 2070
2070 if ( 2071 if (not isRemote and os.path.exists(targetfile)) or (
2071 not isRemote and os.path.exists(targetfile)
2072 ) or (
2073 isRemote and self.__remotefsInterface.exists(targetfile) 2072 isRemote and self.__remotefsInterface.exists(targetfile)
2074 ): 2073 ):
2075 res = EricMessageBox.yesNo( 2074 res = EricMessageBox.yesNo(
2076 self.ui, 2075 self.ui,
2077 self.tr("Add File"), 2076 self.tr("Add File"),
2120 @param target target directory 2119 @param target target directory
2121 @type str 2120 @type str
2122 @param quiet flag indicating quiet operations 2121 @param quiet flag indicating quiet operations
2123 @type bool 2122 @type bool
2124 """ 2123 """
2125 # TODO: adapt to remote server
2126 # get all relevant filename patterns 2124 # get all relevant filename patterns
2127 patterns = [] 2125 patterns = []
2128 ignorePatterns = [] 2126 ignorePatterns = []
2129 for pattern, patterntype in self.__pdata["FILETYPES"].items(): 2127 for pattern, patterntype in self.__pdata["FILETYPES"].items():
2130 if patterntype == filetype: 2128 if patterntype == filetype:
2153 ), 2151 ),
2154 ) 2152 )
2155 return 2153 return
2156 2154
2157 if not FileSystemUtilities.samepath(target, source) and not ( 2155 if not FileSystemUtilities.samepath(target, source) and not (
2158 (not isRemote and os.path.isdir(target)) or ( 2156 (not isRemote and os.path.isdir(target))
2159 isRemote and self.__remotefsInterface.isdir(target) 2157 or (isRemote and self.__remotefsInterface.isdir(target))
2160 )
2161 ): 2158 ):
2162 try: 2159 try:
2163 if isRemote: 2160 if isRemote:
2164 self.__remotefsInterface.makedirs(target) 2161 self.__remotefsInterface.makedirs(target)
2165 else: 2162 else:
2187 if isRemote 2184 if isRemote
2188 else os.path.join(target, os.path.basename(file)) 2185 else os.path.join(target, os.path.basename(file))
2189 ) 2186 )
2190 if not FileSystemUtilities.samepath(target, source): 2187 if not FileSystemUtilities.samepath(target, source):
2191 try: 2188 try:
2192 if ( 2189 if (not isRemote and os.path.exists(targetfile)) or (
2193 not isRemote and os.path.exists(targetfile)
2194 ) or (
2195 isRemote and self.__remotefsInterface.exists(targetfile) 2190 isRemote and self.__remotefsInterface.exists(targetfile)
2196 ): 2191 ):
2197 res = EricMessageBox.yesNo( 2192 res = EricMessageBox.yesNo(
2198 self.ui, 2193 self.ui,
2199 self.tr("Add Directory"), 2194 self.tr("Add Directory"),
2206 if not res: 2201 if not res:
2207 continue 2202 continue
2208 # don't overwrite, carry on with next file 2203 # don't overwrite, carry on with next file
2209 2204
2210 if isRemote: 2205 if isRemote:
2211 self.__remotefsInterface.shutilCopy(file,target ) 2206 self.__remotefsInterface.shutilCopy(file, target)
2212 else: 2207 else:
2213 shutil.copy(file, target) 2208 shutil.copy(file, target)
2214 except OSError: 2209 except OSError:
2215 continue 2210 continue
2216 self.appendFile(targetfile) 2211 self.appendFile(targetfile)
2227 @param source source directory 2222 @param source source directory
2228 @type str 2223 @type str
2229 @param target target directory 2224 @param target target directory
2230 @type str 2225 @type str
2231 """ 2226 """
2232 # TODO: adapt to remote server
2233 # first perform the addition of source 2227 # first perform the addition of source
2234 self.__addSingleDirectory(filetype, source, target, True) 2228 self.__addSingleDirectory(filetype, source, target, True)
2235 2229
2236 ignore_patterns = [ 2230 ignore_patterns = [
2237 ".svn", 2231 ".svn",
2278 @param fileTypeFilter filter to be used by the add directory dialog 2272 @param fileTypeFilter filter to be used by the add directory dialog
2279 @type str 2273 @type str
2280 @param startdir start directory for the selection dialog 2274 @param startdir start directory for the selection dialog
2281 @type str 2275 @type str
2282 """ 2276 """
2283 # TODO: adapt to remote server
2284 from .AddDirectoryDialog import AddDirectoryDialog 2277 from .AddDirectoryDialog import AddDirectoryDialog
2285 2278
2286 if not startdir: 2279 if not startdir:
2287 startdir = self.ppath 2280 startdir = self.ppath
2288 2281
2319 Public method to add a file/directory to the OTHERS project data. 2312 Public method to add a file/directory to the OTHERS project data.
2320 2313
2321 @param fn file name or directory name to add 2314 @param fn file name or directory name to add
2322 @type str 2315 @type str
2323 """ 2316 """
2324 # TODO: adapt to remote server
2325 if fn: 2317 if fn:
2318 separator = (
2319 self.__remotefsInterface.separator()
2320 if FileSystemUtilities.isRemoteFileName(fn)
2321 else os.sep
2322 )
2323
2326 # if it is below the project directory, make it relative to that 2324 # if it is below the project directory, make it relative to that
2327 fn = self.getRelativePath(fn) 2325 fn = self.getRelativePath(fn)
2328 2326
2329 # if it ends with the directory separator character, remove it 2327 # if it ends with the directory separator character, remove it
2330 if fn.endswith(os.sep): 2328 if fn.endswith(separator):
2331 fn = fn[:-1] 2329 fn = fn[:-1]
2332 2330
2333 if fn not in self.__pdata["OTHERS"]: 2331 if fn not in self.__pdata["OTHERS"]:
2334 self.__pdata["OTHERS"].append(fn) 2332 self.__pdata["OTHERS"].append(fn)
2335 self.othersAdded(fn) 2333 self.othersAdded(fn)
2336 self.setDirty(True) 2334 self.setDirty(True)
2337 2335
2338 if os.path.isdir(fn) and fn not in self.otherssubdirs:
2339 self.otherssubdirs.append(fn)
2340
2341 def renameMainScript(self, oldfn, newfn): 2336 def renameMainScript(self, oldfn, newfn):
2342 """ 2337 """
2343 Public method to rename the main script. 2338 Public method to rename the main script.
2344 2339
2345 @param oldfn old filename 2340 @param oldfn old filename
2365 @param newfn new filename of the file 2360 @param newfn new filename of the file
2366 @type str 2361 @type str
2367 @return flag indicating success 2362 @return flag indicating success
2368 @rtype bool 2363 @rtype bool
2369 """ 2364 """
2370 # TODO: adapt to remote server 2365 isRemote = FileSystemUtilities.isRemoteFileName(oldfn)
2366
2371 fn = self.getRelativePath(oldfn) 2367 fn = self.getRelativePath(oldfn)
2372 isSourceFile = fn in self.__pdata["SOURCES"] 2368 isSourceFile = fn in self.__pdata["SOURCES"]
2373 2369
2374 if newfn is None: 2370 if newfn is None:
2375 newfn = EricFileDialog.getSaveFileName( 2371 newfn = EricFileDialog.getSaveFileName(
2381 ) 2377 )
2382 if not newfn: 2378 if not newfn:
2383 return False 2379 return False
2384 newfn = FileSystemUtilities.toNativeSeparators(newfn) 2380 newfn = FileSystemUtilities.toNativeSeparators(newfn)
2385 2381
2386 if os.path.exists(newfn): 2382 if (not isRemote and os.path.exists(newfn)) or (
2383 isRemote and self.__remotefsInterface.exists(newfn)
2384 ):
2387 res = EricMessageBox.yesNo( 2385 res = EricMessageBox.yesNo(
2388 self.ui, 2386 self.ui,
2389 self.tr("Rename File"), 2387 self.tr("Rename File"),
2390 self.tr( 2388 self.tr(
2391 """<p>The file <b>{0}</b> already exists.""" 2389 """<p>The file <b>{0}</b> already exists."""
2395 ) 2393 )
2396 if not res: 2394 if not res:
2397 return False 2395 return False
2398 2396
2399 try: 2397 try:
2400 os.rename(oldfn, newfn) 2398 if isRemote:
2399 self.__remotefsInterface.rename(oldfn, newfn)
2400 else:
2401 os.rename(oldfn, newfn)
2401 except OSError as msg: 2402 except OSError as msg:
2402 EricMessageBox.critical( 2403 EricMessageBox.critical(
2403 self.ui, 2404 self.ui,
2404 self.tr("Rename File"), 2405 self.tr("Rename File"),
2405 self.tr( 2406 self.tr(
2424 @type str 2425 @type str
2425 @param isSourceFile flag indicating that this is a source file 2426 @param isSourceFile flag indicating that this is a source file
2426 even if it doesn't have the source extension 2427 even if it doesn't have the source extension
2427 @type bool 2428 @type bool
2428 """ 2429 """
2429 # TODO: adapt to remote server 2430 if FileSystemUtilities.isRemoteFileName(oldname):
2431 oldDirName = self.__remotefsInterface.dirname(oldname)
2432 newDirName = self.__remotefsInterface.dirname(newname)
2433 else:
2434 oldDirName = os.path.dirname(oldname)
2435 newDirName = os.path.dirname(newname)
2436
2430 fn = self.getRelativePath(oldname) 2437 fn = self.getRelativePath(oldname)
2431 if os.path.dirname(oldname) == os.path.dirname(newname): 2438 if oldDirName == newDirName:
2432 if self.__isInPdata(oldname): 2439 if self.__isInPdata(oldname):
2433 self.removeFile(oldname, False) 2440 self.removeFile(oldname, False)
2434 self.appendFile(newname, isSourceFile, False) 2441 self.appendFile(newname, isSourceFile, False)
2435 self.__model.renameItem(fn, newname) 2442 self.__model.renameItem(fn, newname)
2436 else: 2443 else:
2447 @param start prefix 2454 @param start prefix
2448 @type str 2455 @type str
2449 @return list of files starting with a common prefix 2456 @return list of files starting with a common prefix
2450 @rtype list of str 2457 @rtype list of str
2451 """ 2458 """
2452 # TODO: adapt to remote server 2459 isRemote = FileSystemUtilities.isRemoteFileName(self.ppath)
2460
2453 filelist = [] 2461 filelist = []
2454 start = self.getRelativePath(start) 2462 start = self.getRelativePath(start)
2455 for fileCategory in [ 2463 for fileCategory in [
2456 c for c in self.getFileCategories() if c != "TRANSLATIONS" 2464 c for c in self.getFileCategories() if c != "TRANSLATIONS"
2457 ]: 2465 ]:
2458 for entry in self.__pdata[fileCategory][:]: 2466 for entry in self.__pdata[fileCategory][:]:
2459 if entry.startswith(start): 2467 if entry.startswith(start):
2460 filelist.append(os.path.join(self.ppath, entry)) 2468 filelist.append(
2469 self.__remotefsInterface.join(self.ppath, entry)
2470 if isRemote
2471 else os.path.join(self.ppath, entry)
2472 )
2461 return filelist 2473 return filelist
2462 2474
2463 def __reorganizeFiles(self): 2475 def __reorganizeFiles(self):
2464 """ 2476 """
2465 Private method to reorganize files stored in the project. 2477 Private method to reorganize files stored in the project.
2466 """ 2478 """
2467 reorganized = False 2479 reorganized = False
2468 2480 isRemote = FileSystemUtilities.isRemoteFileName(self.ppath)
2469 # init data store for the reorganization 2481
2482 # initialize data store for the reorganization
2470 newPdata = {} 2483 newPdata = {}
2471 for fileCategory in self.getFileCategories(): 2484 for fileCategory in self.getFileCategories():
2472 newPdata[fileCategory] = [] 2485 newPdata[fileCategory] = []
2473 2486
2474 # iterate over all files checking for a reassignment 2487 # iterate over all files checking for a reassignment
2475 for fileCategory in self.getFileCategories(): 2488 for fileCategory in self.getFileCategories():
2476 for fn in self.__pdata[fileCategory][:]: 2489 for fn in self.__pdata[fileCategory][:]:
2477 filetype = fileCategory 2490 filetype = fileCategory
2478 bfn = os.path.basename(fn) 2491 bfn = (
2492 self.__remotefsInterface.basename(fn)
2493 if isRemote
2494 else os.path.basename(fn)
2495 )
2479 for pattern in sorted(self.__pdata["FILETYPES"], reverse=True): 2496 for pattern in sorted(self.__pdata["FILETYPES"], reverse=True):
2480 if fnmatch.fnmatch(bfn, pattern): 2497 if fnmatch.fnmatch(bfn, pattern):
2481 filetype = self.__pdata["FILETYPES"][pattern] 2498 filetype = self.__pdata["FILETYPES"][pattern]
2482 break 2499 break
2483 2500
2502 @param olddn original directory name 2519 @param olddn original directory name
2503 @type str 2520 @type str
2504 @param newdn new directory name 2521 @param newdn new directory name
2505 @type str 2522 @type str
2506 """ 2523 """
2524 isRemote = FileSystemUtilities.isRemoteFileName(self.ppath)
2525
2507 olddn = self.getRelativePath(olddn) 2526 olddn = self.getRelativePath(olddn)
2508 newdn = self.getRelativePath(newdn) 2527 newdn = self.getRelativePath(newdn)
2509 for fileCategory in [ 2528 for fileCategory in [
2510 c for c in self.getFileCategories() if c != "TRANSLATIONS" 2529 c for c in self.getFileCategories() if c != "TRANSLATIONS"
2511 ]: 2530 ]:
2512 for entry in self.__pdata[fileCategory][:]: 2531 for entry in self.__pdata[fileCategory][:]:
2513 if entry.startswith(olddn): 2532 if entry.startswith(olddn):
2514 entry = entry.replace(olddn, newdn) 2533 entry = entry.replace(olddn, newdn)
2515 self.appendFile( 2534 self.appendFile(
2516 os.path.join(self.ppath, entry), fileCategory == "SOURCES" 2535 self.__remotefsInterface.join(self.ppath, entry)
2536 if isRemote
2537 else os.path.join(self.ppath, entry),
2538 fileCategory == "SOURCES",
2517 ) 2539 )
2518 self.setDirty(True) 2540 self.setDirty(True)
2519 2541
2520 def moveDirectory(self, olddn, newdn): 2542 def moveDirectory(self, olddn, newdn):
2521 """ 2543 """
2537 if fileCategory not in typeStrings: 2559 if fileCategory not in typeStrings:
2538 typeStrings.append(fileCategory) 2560 typeStrings.append(fileCategory)
2539 self.__pdata[fileCategory].remove(entry) 2561 self.__pdata[fileCategory].remove(entry)
2540 entry = entry.replace(olddn, newdn) 2562 entry = entry.replace(olddn, newdn)
2541 self.__pdata[fileCategory].append(entry) 2563 self.__pdata[fileCategory].append(entry)
2542 if fileCategory == "OTHERS": 2564 if fileCategory != "OTHERS" and newdn not in self.subdirs:
2543 if newdn not in self.otherssubdirs: 2565 self.subdirs.append(newdn)
2544 self.otherssubdirs.append(newdn)
2545 else:
2546 if newdn not in self.subdirs:
2547 self.subdirs.append(newdn)
2548 if typeStrings: 2566 if typeStrings:
2549 # the directory is controlled by the project 2567 # the directory is controlled by the project
2550 self.setDirty(True) 2568 self.setDirty(True)
2551 self.__model.removeItem(olddn) 2569 self.__model.removeItem(olddn)
2552 typeString = typeStrings[0] 2570 typeString = typeStrings[0]
2584 The directory is not deleted from the project directory. 2602 The directory is not deleted from the project directory.
2585 2603
2586 @param dn directory name to be removed from the project 2604 @param dn directory name to be removed from the project
2587 @type str 2605 @type str
2588 """ 2606 """
2607 separator = (
2608 self.__remotefsInterface.separator()
2609 if FileSystemUtilities.isRemoteFileName(self.ppath)
2610 else os.sep
2611 )
2612
2589 dirty = False 2613 dirty = False
2590 dn = self.getRelativePath(dn) 2614 dn = self.getRelativePath(dn)
2591 for entry in self.__pdata["OTHERS"][:]: 2615 for entry in self.__pdata["OTHERS"][:]:
2592 if entry.startswith(dn): 2616 if entry.startswith(dn):
2593 self.__pdata["OTHERS"].remove(entry) 2617 self.__pdata["OTHERS"].remove(entry)
2594 dirty = True 2618 dirty = True
2595 dn2 = dn if dn.endswith(os.sep) else dn + os.sep 2619 dn2 = dn if dn.endswith(separator) else dn + separator
2596 for fileCategory in [c for c in self.getFileCategories() if c != "OTHERS"]: 2620 for fileCategory in [c for c in self.getFileCategories() if c != "OTHERS"]:
2597 for entry in self.__pdata[fileCategory][:]: 2621 for entry in self.__pdata[fileCategory][:]:
2598 if entry.startswith(dn2): 2622 if entry.startswith(dn2):
2599 self.__pdata[fileCategory].remove(entry) 2623 self.__pdata[fileCategory].remove(entry)
2600 dirty = True 2624 dirty = True
2611 @type str 2635 @type str
2612 @return flag indicating success 2636 @return flag indicating success
2613 @rtype bool 2637 @rtype bool
2614 """ 2638 """
2615 try: 2639 try:
2616 os.remove(os.path.join(self.ppath, fn)) 2640 if FileSystemUtilities.isRemoteFileName(self.ppath):
2617 path, ext = os.path.splitext(fn) 2641 self.__remotefsInterface.remove(
2618 if ext == ".ui": 2642 self.__remotefsInterface.join(self.ppath, fn)
2619 fn2 = os.path.join(self.ppath, "{0}.h".format(fn))
2620 if os.path.isfile(fn2):
2621 os.remove(fn2)
2622 head, tail = os.path.split(path)
2623 for ext in [".pyc", ".pyo"]:
2624 fn2 = os.path.join(self.ppath, path + ext)
2625 if os.path.isfile(fn2):
2626 os.remove(fn2)
2627 pat = os.path.join(
2628 self.ppath, head, "__pycache__", "{0}.*{1}".format(tail, ext)
2629 ) 2643 )
2630 for f in glob.glob(pat): 2644 filepath = self.__remotefsInterface.splitext(fn)[0]
2631 os.remove(f) 2645 head, tail = self.__remotefsInterface.split(filepath)
2646 for ext in [".pyc", ".pyo"]:
2647 fn2 = self.__remotefsInterface.join(self.ppath, filepath + ext)
2648 if self.__remotefsInterface.isfile(fn2):
2649 self.__remotefsInterface.remove(fn2)
2650 pat = self.__remotefsInterface.join(
2651 self.ppath, head, "__pycache__", "{0}.*{1}".format(tail, ext)
2652 )
2653 for f in self.__remotefsInterface.glob(pat):
2654 self.__remotefsInterface.remove(f)
2655 else:
2656 os.remove(os.path.join(self.ppath, fn))
2657 filepath = os.path.splitext(fn)[0]
2658 head, tail = os.path.split(filepath)
2659 for ext in [".pyc", ".pyo"]:
2660 fn2 = os.path.join(self.ppath, filepath + ext)
2661 if os.path.isfile(fn2):
2662 os.remove(fn2)
2663 pat = os.path.join(
2664 self.ppath, head, "__pycache__", "{0}.*{1}".format(tail, ext)
2665 )
2666 for f in glob.glob(pat):
2667 os.remove(f)
2632 except OSError as err: 2668 except OSError as err:
2633 EricMessageBox.critical( 2669 EricMessageBox.critical(
2634 self.ui, 2670 self.ui,
2635 self.tr("Delete file"), 2671 self.tr("Delete File"),
2636 self.tr( 2672 self.tr(
2637 "<p>The selected file <b>{0}</b> could not be" 2673 "<p>The selected file <b>{0}</b> could not be"
2638 " deleted.</p><p>Reason: {1}</p>" 2674 " deleted.</p><p>Reason: {1}</p>"
2639 ).format(fn, str(err)), 2675 ).format(fn, str(err)),
2640 ) 2676 )
2641 return False 2677 return False
2642 2678
2643 self.removeFile(fn) 2679 self.removeFile(fn)
2644 if ext == ".ui":
2645 self.removeFile(fn + ".h")
2646 return True 2680 return True
2647 2681
2648 def deleteDirectory(self, dn): 2682 def deleteDirectory(self, dn):
2649 """ 2683 """
2650 Public method to delete a directory from the project directory. 2684 Public method to delete a directory from the project directory.
2652 @param dn directory name to be removed from the project 2686 @param dn directory name to be removed from the project
2653 @type str 2687 @type str
2654 @return flag indicating success 2688 @return flag indicating success
2655 @rtype bool 2689 @rtype bool
2656 """ 2690 """
2657 if not os.path.isabs(dn): 2691 dn = self.getAbsolutePath(dn)
2658 dn = os.path.join(self.ppath, dn)
2659 try: 2692 try:
2660 shutil.rmtree(dn, ignore_errors=True) 2693 if FileSystemUtilities.isRemoteFileName(dn):
2694 self.__remotefsInterface.shutilRmtree(dn, ignore_errors=True)
2695 else:
2696 shutil.rmtree(dn, ignore_errors=True)
2661 except OSError as err: 2697 except OSError as err:
2662 EricMessageBox.critical( 2698 EricMessageBox.critical(
2663 self.ui, 2699 self.ui,
2664 self.tr("Delete directory"), 2700 self.tr("Delete Directory"),
2665 self.tr( 2701 self.tr(
2666 "<p>The selected directory <b>{0}</b> could not be" 2702 "<p>The selected directory <b>{0}</b> could not be"
2667 " deleted.</p><p>Reason: {1}</p>" 2703 " deleted.</p><p>Reason: {1}</p>"
2668 ).format(dn, str(err)), 2704 ).format(dn, str(err)),
2669 ) 2705 )
2693 Public slot to built a new project. 2729 Public slot to built a new project.
2694 2730
2695 This method displays the new project dialog and initializes 2731 This method displays the new project dialog and initializes
2696 the project object with the data entered. 2732 the project object with the data entered.
2697 """ 2733 """
2734 # assume remote project without VCS if connected to server
2698 from eric7.VCS.CommandOptionsDialog import VcsCommandOptionsDialog 2735 from eric7.VCS.CommandOptionsDialog import VcsCommandOptionsDialog
2699 2736
2700 from .PropertiesDialog import PropertiesDialog 2737 from .PropertiesDialog import PropertiesDialog
2701 2738
2702 if not self.checkDirty(): 2739 if not self.checkDirty():
2703 return 2740 return
2704 2741
2705 dlg = PropertiesDialog(self, new=True) 2742 isRemote = self.__remoteServer.isServerConnected()
2743
2744 dlg = PropertiesDialog(self, new=True, isRemote=isRemote)
2706 if dlg.exec() == QDialog.DialogCode.Accepted: 2745 if dlg.exec() == QDialog.DialogCode.Accepted:
2707 self.closeProject() 2746 self.closeProject()
2708 2747
2709 # reset the auto save flag 2748 # reset the auto save flag
2710 autoSaveProject = Preferences.getProject("AutoSaveProject") 2749 autoSaveProject = Preferences.getProject("AutoSaveProject")
2723 self.__remoteServer.isServerConnected() 2762 self.__remoteServer.isServerConnected()
2724 and FileSystemUtilities.isRemoteFileName(self.pfile) 2763 and FileSystemUtilities.isRemoteFileName(self.pfile)
2725 ) 2764 )
2726 self.actGrp2.setEnabled(True) 2765 self.actGrp2.setEnabled(True)
2727 self.propsAct.setEnabled(True) 2766 self.propsAct.setEnabled(True)
2728 self.userPropsAct.setEnabled(True) 2767 self.userPropsAct.setEnabled(not isRemote)
2729 self.filetypesAct.setEnabled(True) 2768 self.filetypesAct.setEnabled(True)
2730 self.lexersAct.setEnabled(True) 2769 self.lexersAct.setEnabled(True)
2731 self.sessActGrp.setEnabled(False) 2770 self.sessActGrp.setEnabled(False)
2732 self.dbgActGrp.setEnabled(True) 2771 self.dbgActGrp.setEnabled(True)
2733 self.menuDebuggerAct.setEnabled(True) 2772 self.menuDebuggerAct.setEnabled(True)
2734 self.menuSessionAct.setEnabled(False) 2773 self.menuSessionAct.setEnabled(False)
2735 self.menuCheckAct.setEnabled(True) 2774 self.menuCheckAct.setEnabled(True)
2736 self.menuShowAct.setEnabled(True) 2775 self.menuShowAct.setEnabled(True)
2737 self.menuDiagramAct.setEnabled(True) 2776 self.menuDiagramAct.setEnabled(True)
2738 self.menuApidocAct.setEnabled(True) 2777 self.menuApidocAct.setEnabled(
2778 not FileSystemUtilities.isRemoteFileName(self.ppath)
2779 )
2739 self.menuPackagersAct.setEnabled(True) 2780 self.menuPackagersAct.setEnabled(True)
2740 self.pluginGrp.setEnabled(self.__pdata["PROJECTTYPE"] in ["E7Plugin"]) 2781 self.pluginGrp.setEnabled(
2782 self.__pdata["PROJECTTYPE"] in ["E7Plugin"]
2783 and not FileSystemUtilities.isRemoteFileName(self.ppath)
2784 )
2741 self.addLanguageAct.setEnabled(bool(self.__pdata["TRANSLATIONPATTERN"])) 2785 self.addLanguageAct.setEnabled(bool(self.__pdata["TRANSLATIONPATTERN"]))
2742 self.makeGrp.setEnabled(self.__pdata["MAKEPARAMS"]["MakeEnabled"]) 2786 self.makeGrp.setEnabled(
2743 self.menuMakeAct.setEnabled(self.__pdata["MAKEPARAMS"]["MakeEnabled"]) 2787 self.__pdata["MAKEPARAMS"]["MakeEnabled"]
2788 and not FileSystemUtilities.isRemoteFileName(self.ppath)
2789 )
2790 self.menuMakeAct.setEnabled(
2791 self.__pdata["MAKEPARAMS"]["MakeEnabled"]
2792 and not FileSystemUtilities.isRemoteFileName(self.ppath)
2793 )
2744 self.menuOtherToolsAct.setEnabled(True) 2794 self.menuOtherToolsAct.setEnabled(True)
2745 self.menuFormattingAct.setEnabled(True) 2795 self.menuFormattingAct.setEnabled(
2796 not FileSystemUtilities.isRemoteFileName(self.ppath)
2797 )
2798 self.menuVcsAct.setEnabled(
2799 not FileSystemUtilities.isRemoteFileName(self.ppath)
2800 )
2746 2801
2747 self.projectAboutToBeCreated.emit() 2802 self.projectAboutToBeCreated.emit()
2748 2803
2749 hashStr = str( 2804 hashStr = str(
2750 QCryptographicHash.hash( 2805 QCryptographicHash.hash(
2760 self.__pdata["LEXERASSOCS"] = { 2815 self.__pdata["LEXERASSOCS"] = {
2761 "*.py": "MicroPython", 2816 "*.py": "MicroPython",
2762 } 2817 }
2763 2818
2764 # create the project directory if it doesn't exist already 2819 # create the project directory if it doesn't exist already
2765 if not os.path.isdir(self.ppath): 2820 ppathExists = (
2821 self.__remotefsInterface.isdir(self.ppath)
2822 if isRemote
2823 else os.path.isdir(self.ppath)
2824 )
2825 if not ppathExists:
2766 try: 2826 try:
2767 os.makedirs(self.ppath) 2827 if isRemote:
2828 self.__remotefsInterface.makedirs(self.ppath)
2829 else:
2830 os.makedirs(self.ppath)
2768 except OSError: 2831 except OSError:
2769 EricMessageBox.critical( 2832 EricMessageBox.critical(
2770 self.ui, 2833 self.ui,
2771 self.tr("Create project directory"), 2834 self.tr("Create project directory"),
2772 self.tr( 2835 self.tr(
2780 return 2843 return
2781 2844
2782 # create an empty __init__.py file to make it a Python package 2845 # create an empty __init__.py file to make it a Python package
2783 # (only for Python and Python3) 2846 # (only for Python and Python3)
2784 if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]: 2847 if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]:
2785 fn = os.path.join(self.ppath, "__init__.py") 2848 if isRemote:
2786 with open(fn, "w", encoding="utf-8"): 2849 fn = self.__remotefsInterface.join(self.ppath, "__init__.py")
2787 pass 2850 self.__remotefsInterface.writeFile(fn, b"")
2851 else:
2852 fn = os.path.join(self.ppath, "__init__.py")
2853 with open(fn, "w", encoding="utf-8"):
2854 pass
2788 self.appendFile(fn, True) 2855 self.appendFile(fn, True)
2789 2856
2790 # create an empty main script file, if a name was given 2857 # create an empty main script file, if a name was given
2791 if self.__pdata["MAINSCRIPT"]: 2858 if self.__pdata["MAINSCRIPT"]:
2792 if not os.path.isabs(self.__pdata["MAINSCRIPT"]): 2859 if isRemote:
2793 ms = os.path.join(self.ppath, self.__pdata["MAINSCRIPT"]) 2860 if not self.__remotefsInterface.isabs(
2861 self.__pdata["MAINSCRIPT"]
2862 ):
2863 ms = self.__remotefsInterface.join(
2864 self.ppath, self.__pdata["MAINSCRIPT"]
2865 )
2866 else:
2867 ms = self.__pdata["MAINSCRIPT"]
2868 self.__remotefsInterface.makedirs(
2869 self.__remotefsInterface.dirname(ms), exist_ok=True
2870 )
2871 self.__remotefsInterface.writeFile(ms, b"")
2794 else: 2872 else:
2795 ms = self.__pdata["MAINSCRIPT"] 2873 if not os.path.isabs(self.__pdata["MAINSCRIPT"]):
2796 os.makedirs(os.path.dirname(ms), exist_ok=True) 2874 ms = os.path.join(self.ppath, self.__pdata["MAINSCRIPT"])
2797 with open(ms, "w"): 2875 else:
2798 pass 2876 ms = self.__pdata["MAINSCRIPT"]
2877 os.makedirs(os.path.dirname(ms), exist_ok=True)
2878 with open(ms, "w"):
2879 pass
2799 self.appendFile(ms, True) 2880 self.appendFile(ms, True)
2800 2881
2801 if self.__pdata["MAKEPARAMS"]["MakeEnabled"]: 2882 if self.__pdata["MAKEPARAMS"]["MakeEnabled"] and not isRemote:
2802 mf = self.__pdata["MAKEPARAMS"]["MakeFile"] 2883 mf = self.__pdata["MAKEPARAMS"]["MakeFile"]
2803 if mf: 2884 if mf:
2804 if not os.path.isabs(mf): 2885 if not os.path.isabs(mf):
2805 mf = os.path.join(self.ppath, mf) 2886 mf = os.path.join(self.ppath, mf)
2806 else: 2887 else:
2808 os.makedirs(os.path.dirname(mf), exist_ok=True) 2889 os.makedirs(os.path.dirname(mf), exist_ok=True)
2809 with open(mf, "w"): 2890 with open(mf, "w"):
2810 pass 2891 pass
2811 self.appendFile(mf) 2892 self.appendFile(mf)
2812 2893
2813 tpd = os.path.join(self.ppath, self.translationsRoot) 2894 if isRemote:
2814 if not self.translationsRoot.endswith(os.sep): 2895 tpd = self.__remotefsInterface.join(
2815 tpd = os.path.dirname(tpd) 2896 self.ppath, self.translationsRoot
2816 if not os.path.isdir(tpd): 2897 )
2817 os.makedirs(tpd, exist_ok=True) 2898 if not self.translationsRoot.endswith(
2818 if self.__pdata["TRANSLATIONSBINPATH"]: 2899 self.__remotefsInterface.separator()
2819 tpd = os.path.join(self.ppath, self.__pdata["TRANSLATIONSBINPATH"]) 2900 ):
2901 tpd = self.__remotefsInterface.dirname(tpd)
2902 if not self.__remotefsInterface.isdir(tpd):
2903 self.__remotefsInterface.makedirs(tpd, exist_ok=True)
2904 if self.__pdata["TRANSLATIONSBINPATH"]:
2905 tpd = self.__remotefsInterface.join(
2906 self.ppath, self.__pdata["TRANSLATIONSBINPATH"]
2907 )
2908 if not self.__remotefsInterface.isdir(tpd):
2909 self.__remotefsInterface.makedirs(tpd, exist_ok=True)
2910 else:
2911 tpd = os.path.join(self.ppath, self.translationsRoot)
2912 if not self.translationsRoot.endswith(os.sep):
2913 tpd = os.path.dirname(tpd)
2820 if not os.path.isdir(tpd): 2914 if not os.path.isdir(tpd):
2821 os.makedirs(tpd, exist_ok=True) 2915 os.makedirs(tpd, exist_ok=True)
2916 if self.__pdata["TRANSLATIONSBINPATH"]:
2917 tpd = os.path.join(
2918 self.ppath, self.__pdata["TRANSLATIONSBINPATH"]
2919 )
2920 if not os.path.isdir(tpd):
2921 os.makedirs(tpd, exist_ok=True)
2822 2922
2823 # create management directory if not present 2923 # create management directory if not present
2824 self.createProjectManagementDir() 2924 self.createProjectManagementDir()
2825 2925
2826 self.saveProject() 2926 self.saveProject()
2841 # set the auto save flag to its supposed value 2941 # set the auto save flag to its supposed value
2842 Preferences.setProject("AutoSaveProject", autoSaveProject) 2942 Preferences.setProject("AutoSaveProject", autoSaveProject)
2843 return 2943 return
2844 2944
2845 if self.__pdata["MAINSCRIPT"]: 2945 if self.__pdata["MAINSCRIPT"]:
2846 if not os.path.isabs(self.__pdata["MAINSCRIPT"]): 2946 if isRemote:
2847 ms = os.path.join(self.ppath, self.__pdata["MAINSCRIPT"]) 2947 if not self.__remotefsInterface.isabs(
2948 self.__pdata["MAINSCRIPT"]
2949 ):
2950 ms = self.__remotefsInterface.join(
2951 self.ppath, self.__pdata["MAINSCRIPT"]
2952 )
2953 else:
2954 ms = self.__pdata["MAINSCRIPT"]
2955 msExists = self.__remotefsInterface.exists(ms)
2848 else: 2956 else:
2849 ms = self.__pdata["MAINSCRIPT"] 2957 if not os.path.isabs(self.__pdata["MAINSCRIPT"]):
2850 if not os.path.exists(ms): 2958 ms = os.path.join(self.ppath, self.__pdata["MAINSCRIPT"])
2959 else:
2960 ms = self.__pdata["MAINSCRIPT"]
2961 msExists = os.path.exists(ms)
2962 if not msExists:
2851 try: 2963 try:
2852 os.makedirs(os.path.dirname(ms)) 2964 if isRemote:
2853 with open(ms, "w"): 2965 self.__remotefsInterface.makedirs(
2854 pass 2966 self.__remotefsInterface.dirname(ms), exist_ok=True
2967 )
2968 self.__remotefsInterface.writeFile(ms, b"")
2969 else:
2970 os.makedirs(os.path.dirname(ms), exist_ok=True)
2971 with open(ms, "w"):
2972 pass
2855 except OSError as err: 2973 except OSError as err:
2856 EricMessageBox.critical( 2974 EricMessageBox.critical(
2857 self.ui, 2975 self.ui,
2858 self.tr("Create main script"), 2976 self.tr("Create main script"),
2859 self.tr( 2977 self.tr(
2860 "<p>The mainscript <b>{0}</b> could not" 2978 "<p>The main script <b>{0}</b> could not"
2861 " be created.<br/>Reason: {1}</p>" 2979 " be created.<br/>Reason: {1}</p>"
2862 ).format(ms, str(err)), 2980 ).format(ms, str(err)),
2863 ) 2981 )
2864 self.appendFile(ms, True) 2982 self.appendFile(ms, True)
2865 else: 2983 else:
2866 ms = "" 2984 ms = ""
2867 2985
2868 if self.__pdata["MAKEPARAMS"]["MakeEnabled"]: 2986 if self.__pdata["MAKEPARAMS"]["MakeEnabled"] and not isRemote:
2869 mf = self.__pdata["MAKEPARAMS"]["MakeFile"] 2987 mf = self.__pdata["MAKEPARAMS"]["MakeFile"]
2870 if mf: 2988 if mf:
2871 if not os.path.isabs(mf): 2989 if not os.path.isabs(mf):
2872 mf = os.path.join(self.ppath, mf) 2990 mf = os.path.join(self.ppath, mf)
2873 else: 2991 else:
2874 mf = os.path.join(self.ppath, Project.DefaultMakefile) 2992 mf = os.path.join(self.ppath, Project.DefaultMakefile)
2875 if not os.path.exists(mf): 2993 if not os.path.exists(mf):
2876 try: 2994 try:
2877 os.makedirs(os.path.dirname(mf)) 2995 os.makedirs(os.path.dirname(mf), exist_ok=True)
2878 with open(mf, "w"): 2996 with open(mf, "w"):
2879 pass 2997 pass
2880 except OSError as err: 2998 except OSError as err:
2881 EricMessageBox.critical( 2999 EricMessageBox.critical(
2882 self.ui, 3000 self.ui,
2894 self.tr("New Project"), 3012 self.tr("New Project"),
2895 self.tr("""Add existing files to the project?"""), 3013 self.tr("""Add existing files to the project?"""),
2896 yesDefault=True, 3014 yesDefault=True,
2897 ) 3015 )
2898 if res: 3016 if res:
2899 self.newProjectAddFiles(ms) 3017 self.newProjectAddFiles(ms, isRemote=isRemote)
2900 addAllToVcs = res 3018 addAllToVcs = res and not isRemote
3019
2901 # create an empty __init__.py file to make it a Python package 3020 # create an empty __init__.py file to make it a Python package
2902 # if none exists (only for Python and Python3) 3021 # if none exists (only for Python and Python3)
2903 if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]: 3022 if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]:
2904 fn = os.path.join(self.ppath, "__init__.py") 3023 if isRemote:
2905 if not os.path.exists(fn): 3024 fn = self.__remotefsInterface.join(self.ppath, "__init__.py")
2906 with open(fn, "w", encoding="utf-8"): 3025 if not self.__remotefsInterface.exists(fn):
2907 pass 3026 self.__remotefsInterface.writeFile(fn, b"")
2908 self.appendFile(fn, True) 3027 self.appendFile(fn, True)
3028 else:
3029 fn = os.path.join(self.ppath, "__init__.py")
3030 if not os.path.exists(fn):
3031 with open(fn, "w", encoding="utf-8"):
3032 pass
3033 self.appendFile(fn, True)
2909 self.saveProject() 3034 self.saveProject()
2910 3035
2911 # check, if the existing project directory is already under 3036 # check, if the existing project directory is already under
2912 # VCS control 3037 # VCS control
2913 pluginManager = ericApp().getObject("PluginManager") 3038 if not isRemote:
2914 for indicator, vcsData in list( 3039 pluginManager = ericApp().getObject("PluginManager")
2915 pluginManager.getVcsSystemIndicators().items() 3040 for indicator, vcsData in list(
2916 ): 3041 pluginManager.getVcsSystemIndicators().items()
2917 if os.path.exists(os.path.join(self.ppath, indicator)): 3042 ):
2918 if len(vcsData) > 1: 3043 if os.path.exists(os.path.join(self.ppath, indicator)):
2919 vcsList = [] 3044 if len(vcsData) > 1:
2920 for _vcsSystemStr, vcsSystemDisplay in vcsData: 3045 vcsList = []
2921 vcsList.append(vcsSystemDisplay) 3046 for _vcsSystemStr, vcsSystemDisplay in vcsData:
2922 res, vcs_ok = QInputDialog.getItem( 3047 vcsList.append(vcsSystemDisplay)
2923 None, 3048 res, vcs_ok = QInputDialog.getItem(
2924 self.tr("New Project"), 3049 None,
2925 self.tr("Select Version Control System"), 3050 self.tr("New Project"),
2926 vcsList, 3051 self.tr("Select Version Control System"),
2927 0, 3052 vcsList,
2928 False, 3053 0,
2929 ) 3054 False,
2930 if vcs_ok: 3055 )
2931 for vcsSystemStr, vcsSystemDisplay in vcsData: 3056 if vcs_ok:
2932 if res == vcsSystemDisplay: 3057 for vcsSystemStr, vcsSystemDisplay in vcsData:
2933 vcsSystem = vcsSystemStr 3058 if res == vcsSystemDisplay:
2934 break 3059 vcsSystem = vcsSystemStr
3060 break
3061 else:
3062 vcsSystem = "None"
2935 else: 3063 else:
2936 vcsSystem = "None" 3064 vcsSystem = "None"
2937 else: 3065 else:
2938 vcsSystem = "None" 3066 vcsSystem = vcsData[0][1]
2939 else: 3067 self.__pdata["VCS"] = vcsSystem
2940 vcsSystem = vcsData[0][1] 3068 self.vcs = self.initVCS()
2941 self.__pdata["VCS"] = vcsSystem 3069 self.setDirty(True)
2942 self.vcs = self.initVCS() 3070 if self.vcs is not None:
2943 self.setDirty(True) 3071 # edit VCS command options
2944 if self.vcs is not None: 3072 if self.vcs.vcsSupportCommandOptions():
2945 # edit VCS command options 3073 vcores = EricMessageBox.yesNo(
2946 if self.vcs.vcsSupportCommandOptions(): 3074 self.ui,
2947 vcores = EricMessageBox.yesNo( 3075 self.tr("New Project"),
2948 self.ui, 3076 self.tr(
2949 self.tr("New Project"), 3077 """Would you like to edit the VCS"""
2950 self.tr( 3078 """ command options?"""
2951 """Would you like to edit the VCS""" 3079 ),
2952 """ command options?""" 3080 )
2953 ), 3081 else:
2954 ) 3082 vcores = False
3083 if vcores:
3084 codlg = VcsCommandOptionsDialog(self.vcs)
3085 if codlg.exec() == QDialog.DialogCode.Accepted:
3086 self.vcs.vcsSetOptions(codlg.getOptions())
3087 # add project file to repository
3088 if res == 0:
3089 apres = EricMessageBox.yesNo(
3090 self.ui,
3091 self.tr("New Project"),
3092 self.tr(
3093 "Shall the project file be added"
3094 " to the repository?"
3095 ),
3096 yesDefault=True,
3097 )
3098 if apres:
3099 self.saveProject()
3100 self.vcs.vcsAdd(self.pfile)
2955 else: 3101 else:
2956 vcores = False 3102 self.__pdata["VCS"] = "None"
2957 if vcores: 3103 self.saveProject()
2958 codlg = VcsCommandOptionsDialog(self.vcs) 3104 break
2959 if codlg.exec() == QDialog.DialogCode.Accepted:
2960 self.vcs.vcsSetOptions(codlg.getOptions())
2961 # add project file to repository
2962 if res == 0:
2963 apres = EricMessageBox.yesNo(
2964 self.ui,
2965 self.tr("New project"),
2966 self.tr(
2967 "Shall the project file be added"
2968 " to the repository?"
2969 ),
2970 yesDefault=True,
2971 )
2972 if apres:
2973 self.saveProject()
2974 self.vcs.vcsAdd(self.pfile)
2975 else:
2976 self.__pdata["VCS"] = "None"
2977 self.saveProject()
2978 break
2979 3105
2980 # put the project under VCS control 3106 # put the project under VCS control
2981 if self.vcs is None and self.vcsSoftwareAvailable() and self.vcsRequested: 3107 if (
3108 not isRemote
3109 and self.vcs is None
3110 and self.vcsSoftwareAvailable()
3111 and self.vcsRequested
3112 ):
2982 vcsSystemsDict = ( 3113 vcsSystemsDict = (
2983 ericApp() 3114 ericApp()
2984 .getObject("PluginManager") 3115 .getObject("PluginManager")
2985 .getPluginDisplayStrings("version_control") 3116 .getPluginDisplayStrings("version_control")
2986 ) 3117 )
3046 # set the auto save flag to its supposed value 3177 # set the auto save flag to its supposed value
3047 Preferences.setProject("AutoSaveProject", autoSaveProject) 3178 Preferences.setProject("AutoSaveProject", autoSaveProject)
3048 3179
3049 if self.__pdata["EMBEDDED_VENV"]: 3180 if self.__pdata["EMBEDDED_VENV"]:
3050 self.__createEmbeddedEnvironment() 3181 self.__createEmbeddedEnvironment()
3051 self.menuEnvironmentAct.setEnabled(self.__pdata["EMBEDDED_VENV"]) 3182 self.menuEnvironmentAct.setEnabled(
3183 self.__pdata["EMBEDDED_VENV"]
3184 and not FileSystemUtilities.isRemoteFileName(self.ppath)
3185 )
3052 3186
3053 self.projectOpenedHooks.emit() 3187 self.projectOpenedHooks.emit()
3054 self.projectOpened.emit() 3188 self.projectOpened.emit()
3055 3189
3056 # open the main script 3190 # open the main script
3057 if self.__pdata["MAINSCRIPT"]: 3191 if self.__pdata["MAINSCRIPT"]:
3058 if not os.path.isabs(self.__pdata["MAINSCRIPT"]): 3192 if isRemote:
3059 ms = os.path.join(self.ppath, self.__pdata["MAINSCRIPT"]) 3193 if not self.__remotefsInterface.isabs(self.__pdata["MAINSCRIPT"]):
3194 ms = self.__remotefsInterface.join(
3195 self.ppath, self.__pdata["MAINSCRIPT"]
3196 )
3197 else:
3198 ms = self.__pdata["MAINSCRIPT"]
3060 else: 3199 else:
3061 ms = self.__pdata["MAINSCRIPT"] 3200 if not os.path.isabs(self.__pdata["MAINSCRIPT"]):
3201 ms = os.path.join(self.ppath, self.__pdata["MAINSCRIPT"])
3202 else:
3203 ms = self.__pdata["MAINSCRIPT"]
3062 self.sourceFile.emit(ms) 3204 self.sourceFile.emit(ms)
3063 3205
3064 def newProjectAddFiles(self, mainscript): 3206 def newProjectAddFiles(self, mainscript, isRemote=False):
3065 """ 3207 """
3066 Public method to add files to a new project. 3208 Public method to add files to a new project.
3067 3209
3068 @param mainscript name of the mainscript 3210 @param mainscript name of the mainscript
3069 @type str 3211 @type str
3212 @param isRemote flag indicating a remote project (defaults to False)
3213 @type bool (optional)
3070 """ 3214 """
3071 # Show the file type associations for the user to change 3215 # Show the file type associations for the user to change
3072 self.__showFiletypeAssociations() 3216 self.__showFiletypeAssociations()
3073 3217
3074 ignoreList = [] 3218 ignoreList = []
3075 if self.__pdata["EMBEDDED_VENV"]: 3219 if self.__pdata["EMBEDDED_VENV"]:
3076 environmentPath = self.__findEmbeddedEnvironment() 3220 environmentPath = self.__findEmbeddedEnvironment()
3077 if environmentPath: 3221 if environmentPath:
3078 # there is already an embeded venv; ignore thie whenn adding files 3222 # there is already an embedded venv; ignore this when adding files
3079 ignoreList = [os.path.split(environmentPath)[-1]] 3223 ignoreList = (
3224 [self.__remotefsInterface.split(environmentPath)[-1]]
3225 if isRemote
3226 else [os.path.split(environmentPath)[-1]]
3227 )
3080 with EricOverrideCursor(): 3228 with EricOverrideCursor():
3081 # search the project directory for files with known extensions 3229 # search the project directory for files with known extensions
3082 for filespec in self.__pdata["FILETYPES"]: 3230 for filespec in self.__pdata["FILETYPES"]:
3083 files = FileSystemUtilities.direntries( 3231 files = (
3084 self.ppath, 3232 self.__remotefsInterface.direntries(
3085 filesonly=True, 3233 self.ppath,
3086 pattern=filespec, 3234 filesonly=True,
3087 ignore=ignoreList, 3235 pattern=filespec,
3236 ignore=ignoreList,
3237 )
3238 if isRemote
3239 else FileSystemUtilities.direntries(
3240 self.ppath,
3241 filesonly=True,
3242 pattern=filespec,
3243 ignore=ignoreList,
3244 )
3088 ) 3245 )
3089 for file in files: 3246 for file in files:
3090 self.appendFile(file) 3247 self.appendFile(file)
3091 3248
3092 # special handling for translation files 3249 # special handling for translation files
3093 if self.translationsRoot: 3250 if self.translationsRoot:
3094 tpd = os.path.join(self.ppath, self.translationsRoot) 3251 if isRemote:
3095 if not self.translationsRoot.endswith(os.sep): 3252 tpd = self.__remotefsInterface.join(
3096 tpd = os.path.dirname(tpd) 3253 self.ppath, self.translationsRoot
3254 )
3255 if not self.translationsRoot.endswith(os.sep):
3256 tpd = self.__remotefsInterface.dirname(tpd)
3257 else:
3258 tpd = os.path.join(self.ppath, self.translationsRoot)
3259 if not self.translationsRoot.endswith(os.sep):
3260 tpd = os.path.dirname(tpd)
3097 else: 3261 else:
3098 tpd = self.ppath 3262 tpd = self.ppath
3099 tslist = [] 3263 tslist = []
3100 if self.__pdata["TRANSLATIONPATTERN"]: 3264 if self.__pdata["TRANSLATIONPATTERN"]:
3101 pattern = os.path.basename(self.__pdata["TRANSLATIONPATTERN"]) 3265 pattern = (
3266 self.__remotefsInterface.basename(
3267 self.__pdata["TRANSLATIONPATTERN"]
3268 )
3269 if isRemote
3270 else os.path.basename(self.__pdata["TRANSLATIONPATTERN"])
3271 )
3102 if "%language%" in pattern: 3272 if "%language%" in pattern:
3103 pattern = pattern.replace("%language%", "*") 3273 pattern = pattern.replace("%language%", "*")
3104 else: 3274 else:
3105 tpd = self.__pdata["TRANSLATIONPATTERN"].split("%language%")[0] 3275 tpd = self.__pdata["TRANSLATIONPATTERN"].split("%language%")[0]
3106 else: 3276 else:
3107 pattern = "*.ts" 3277 pattern = "*.ts"
3108 tslist.extend(FileSystemUtilities.direntries(tpd, True, pattern)) 3278 tslist.extend(
3279 self.__remotefsInterface.direntries(tpd, True, pattern)
3280 if isRemote
3281 else FileSystemUtilities.direntries(tpd, True, pattern)
3282 )
3283
3109 pattern = self.__binaryTranslationFile(pattern) 3284 pattern = self.__binaryTranslationFile(pattern)
3110 if pattern: 3285 if pattern:
3111 tslist.extend(FileSystemUtilities.direntries(tpd, True, pattern)) 3286 tslist.extend(
3287 self.__remotefsInterface.direntries(tpd, True, pattern)
3288 if isRemote
3289 else FileSystemUtilities.direntries(tpd, True, pattern)
3290 )
3112 if tslist: 3291 if tslist:
3113 if "_" in os.path.basename(tslist[0]): 3292 hasUnderscore = (
3114 # the first entry determines the mainscript name 3293 "_" in self.__remotefsInterface.basename(tslist[0])
3115 mainscriptname = ( 3294 if isRemote
3116 os.path.splitext(mainscript)[0] 3295 else "_" in os.path.basename(tslist[0])
3117 or os.path.basename(tslist[0]).split("_")[0] 3296 )
3118 ) 3297 if hasUnderscore:
3119 self.__pdata["TRANSLATIONPATTERN"] = os.path.join( 3298 # the first entry determines the main script name
3120 os.path.dirname(tslist[0]), 3299 if isRemote:
3121 "{0}_%language%{1}".format( 3300 mainscriptname = (
3122 os.path.basename(tslist[0]).split("_")[0], 3301 self.__remotefsInterface.splitext(mainscript)[0]
3123 os.path.splitext(tslist[0])[1], 3302 or self.__remotefsInterface.basename(tslist[0]).split("_")[
3124 ), 3303 0
3125 ) 3304 ]
3305 )
3306 self.__pdata[
3307 "TRANSLATIONPATTERN"
3308 ] = self.__remotefsInterface.join(
3309 self.__remotefsInterface.dirname(tslist[0]),
3310 "{0}_%language%{1}".format(
3311 self.__remotefsInterface.basename(tslist[0]).split("_")[
3312 0
3313 ],
3314 self.__remotefsInterface.splitext(tslist[0])[1],
3315 ),
3316 )
3317 else:
3318 mainscriptname = (
3319 os.path.splitext(mainscript)[0]
3320 or os.path.basename(tslist[0]).split("_")[0]
3321 )
3322 self.__pdata["TRANSLATIONPATTERN"] = os.path.join(
3323 os.path.dirname(tslist[0]),
3324 "{0}_%language%{1}".format(
3325 os.path.basename(tslist[0]).split("_")[0],
3326 os.path.splitext(tslist[0])[1],
3327 ),
3328 )
3126 else: 3329 else:
3127 mainscriptname = "" 3330 mainscriptname = ""
3128 pattern, ok = QInputDialog.getText( 3331 pattern, ok = QInputDialog.getText(
3129 None, 3332 None,
3130 self.tr("Translation Pattern"), 3333 self.tr("Translation Pattern"),
3148 for ts in tslist: 3351 for ts in tslist:
3149 if fnmatch.fnmatch(ts, pattern): 3352 if fnmatch.fnmatch(ts, pattern):
3150 self.__pdata["TRANSLATIONS"].append(ts) 3353 self.__pdata["TRANSLATIONS"].append(ts)
3151 self.projectFileAdded.emit(ts, "TRANSLATIONS") 3354 self.projectFileAdded.emit(ts, "TRANSLATIONS")
3152 if self.__pdata["TRANSLATIONSBINPATH"]: 3355 if self.__pdata["TRANSLATIONSBINPATH"]:
3153 tpd = os.path.join( 3356 if isRemote:
3154 self.ppath, self.__pdata["TRANSLATIONSBINPATH"] 3357 tpd = self.__remotefsInterface.join(
3155 ) 3358 self.ppath, self.__pdata["TRANSLATIONSBINPATH"]
3156 pattern = os.path.basename( 3359 )
3157 self.__pdata["TRANSLATIONPATTERN"] 3360 pattern = self.__remotefsInterface.basename(
3158 ).replace("%language%", "*") 3361 self.__pdata["TRANSLATIONPATTERN"]
3362 ).replace("%language%", "*")
3363 else:
3364 tpd = os.path.join(
3365 self.ppath, self.__pdata["TRANSLATIONSBINPATH"]
3366 )
3367 pattern = os.path.basename(
3368 self.__pdata["TRANSLATIONPATTERN"]
3369 ).replace("%language%", "*")
3159 pattern = self.__binaryTranslationFile(pattern) 3370 pattern = self.__binaryTranslationFile(pattern)
3160 qmlist = FileSystemUtilities.direntries(tpd, True, pattern) 3371 qmlist = FileSystemUtilities.direntries(tpd, True, pattern)
3161 for qm in qmlist: 3372 for qm in qmlist:
3162 self.__pdata["TRANSLATIONS"].append(qm) 3373 self.__pdata["TRANSLATIONS"].append(qm)
3163 self.projectFileAdded.emit(qm, "TRANSLATIONS") 3374 self.projectFileAdded.emit(qm, "TRANSLATIONS")
3172 """ 3383 """
3173 Private slot to display the properties dialog. 3384 Private slot to display the properties dialog.
3174 """ 3385 """
3175 from .PropertiesDialog import PropertiesDialog 3386 from .PropertiesDialog import PropertiesDialog
3176 3387
3177 dlg = PropertiesDialog(self, new=False) 3388 isRemote = FileSystemUtilities.isRemoteFileName(self.ppath)
3389 dlg = PropertiesDialog(self, new=False, isRemote=isRemote)
3178 if dlg.exec() == QDialog.DialogCode.Accepted: 3390 if dlg.exec() == QDialog.DialogCode.Accepted:
3179 fileTypesDict = copy.copy(self.__pdata["FILETYPES"]) 3391 fileTypesDict = copy.copy(self.__pdata["FILETYPES"])
3180 dlg.storeData() 3392 dlg.storeData()
3181 self.setDirty(True) 3393 self.setDirty(True)
3182 if self.__pdata["MAINSCRIPT"]: 3394 if self.__pdata["MAINSCRIPT"]:
3183 if not os.path.isabs(self.__pdata["MAINSCRIPT"]): 3395 if isRemote:
3184 ms = os.path.join(self.ppath, self.__pdata["MAINSCRIPT"]) 3396 if not self.__remotefsInterface.isabs(self.__pdata["MAINSCRIPT"]):
3397 ms = self.__remotefsInterface.join(
3398 self.ppath, self.__pdata["MAINSCRIPT"]
3399 )
3400 else:
3401 ms = self.__pdata["MAINSCRIPT"]
3402 if self.__remotefsInterface.exists(ms):
3403 self.appendFile(ms)
3185 else: 3404 else:
3186 ms = self.__pdata["MAINSCRIPT"] 3405 if not os.path.isabs(self.__pdata["MAINSCRIPT"]):
3187 if os.path.exists(ms): 3406 ms = os.path.join(self.ppath, self.__pdata["MAINSCRIPT"])
3188 self.appendFile(ms) 3407 else:
3408 ms = self.__pdata["MAINSCRIPT"]
3409 if os.path.exists(ms):
3410 self.appendFile(ms)
3189 3411
3190 if self.__pdata["MAKEPARAMS"]["MakeEnabled"]: 3412 if self.__pdata["MAKEPARAMS"]["MakeEnabled"]:
3191 mf = self.__pdata["MAKEPARAMS"]["MakeFile"] 3413 mf = self.__pdata["MAKEPARAMS"]["MakeFile"]
3192 if mf: 3414 if isRemote:
3193 if not os.path.isabs(mf): 3415 if mf:
3194 mf = os.path.join(self.ppath, mf) 3416 if not self.__remotefsInterface.isabs(mf):
3417 mf = self.__remotefsInterface.join(self.ppath, mf)
3418 else:
3419 mf = self.__remotefsInterface.join(
3420 self.ppath, Project.DefaultMakefile
3421 )
3422 exists = self.__remotefsInterface.exists(mf)
3195 else: 3423 else:
3196 mf = os.path.join(self.ppath, Project.DefaultMakefile) 3424 if mf:
3197 if not os.path.exists(mf): 3425 if not os.path.isabs(mf):
3426 mf = os.path.join(self.ppath, mf)
3427 else:
3428 mf = os.path.join(self.ppath, Project.DefaultMakefile)
3429 exists = os.path.exists(mf)
3430 if not exists:
3198 try: 3431 try:
3199 with open(mf, "w"): 3432 if isRemote:
3200 pass 3433 self.__remotefsInterface.writeFile(mf, b"")
3434 else:
3435 with open(mf, "w"):
3436 pass
3201 except OSError as err: 3437 except OSError as err:
3202 EricMessageBox.critical( 3438 EricMessageBox.critical(
3203 self.ui, 3439 self.ui,
3204 self.tr("Create Makefile"), 3440 self.tr("Create Makefile"),
3205 self.tr( 3441 self.tr(
3208 ).format(mf, str(err)), 3444 ).format(mf, str(err)),
3209 ) 3445 )
3210 self.appendFile(mf) 3446 self.appendFile(mf)
3211 3447
3212 if self.translationsRoot: 3448 if self.translationsRoot:
3213 tp = os.path.join(self.ppath, self.translationsRoot) 3449 if isRemote:
3214 if not self.translationsRoot.endswith(os.sep): 3450 tp = self.__remotefsInterface.join(
3215 tp = os.path.dirname(tp) 3451 self.ppath, self.translationsRoot
3452 )
3453 if not self.translationsRoot.endswith(
3454 self.__remotefsInterface.separator()
3455 ):
3456 tp = self.__remotefsInterface.dirname(tp)
3457 if not self.__remotefsInterface.isdir(tp):
3458 self.__remotefsInterface.makedirs(tp)
3459 else:
3460 tp = os.path.join(self.ppath, self.translationsRoot)
3461 if not self.translationsRoot.endswith(os.sep):
3462 tp = os.path.dirname(tp)
3463 if not os.path.isdir(tp):
3464 os.makedirs(tp)
3216 else: 3465 else:
3217 tp = self.ppath 3466 tp = self.ppath
3218 if not os.path.isdir(tp):
3219 os.makedirs(tp)
3220 if tp != self.ppath and tp not in self.subdirs: 3467 if tp != self.ppath and tp not in self.subdirs:
3221 self.subdirs.append(tp) 3468 self.subdirs.append(tp)
3222 3469
3223 if self.__pdata["TRANSLATIONSBINPATH"]: 3470 if self.__pdata["TRANSLATIONSBINPATH"]:
3224 tp = os.path.join(self.ppath, self.__pdata["TRANSLATIONSBINPATH"]) 3471 if isRemote:
3225 if not os.path.isdir(tp): 3472 tp = self.__remotefsInterface.join(
3226 os.makedirs(tp) 3473 self.ppath, self.__pdata["TRANSLATIONSBINPATH"]
3474 )
3475 if not self.__remotefsInterface.isdir(tp):
3476 self.__remotefsInterface.makedirs(tp)
3477 else:
3478 tp = os.path.join(self.ppath, self.__pdata["TRANSLATIONSBINPATH"])
3479 if not os.path.isdir(tp):
3480 os.makedirs(tp)
3227 if tp != self.ppath and tp not in self.subdirs: 3481 if tp != self.ppath and tp not in self.subdirs:
3228 self.subdirs.append(tp) 3482 self.subdirs.append(tp)
3229 3483
3230 self.pluginGrp.setEnabled(self.__pdata["PROJECTTYPE"] in ["E7Plugin"]) 3484 self.pluginGrp.setEnabled(self.__pdata["PROJECTTYPE"] in ["E7Plugin"])
3231 3485
3373 return 3627 return
3374 3628
3375 if fn is None: 3629 if fn is None:
3376 fn = EricFileDialog.getOpenFileName( 3630 fn = EricFileDialog.getOpenFileName(
3377 self.parent(), 3631 self.parent(),
3378 self.tr("Open project"), 3632 self.tr("Open Project"),
3379 Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir(), 3633 Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir(),
3380 self.tr("Project Files (*.epj)"), 3634 self.tr("Project Files (*.epj)"),
3381 ) 3635 )
3382 3636
3383 if fn and self.closeProject(): 3637 if fn and self.closeProject():
3408 self.__readUserProperties() 3662 self.__readUserProperties()
3409 3663
3410 with EricOverrideCursor(): 3664 with EricOverrideCursor():
3411 oldState = self.isDirty() 3665 oldState = self.isDirty()
3412 self.vcs = self.initVCS() 3666 self.vcs = self.initVCS()
3413 if self.vcs is None and self.isDirty() == oldState: 3667 if not FileSystemUtilities.isRemoteFileName(self.ppath):
3414 # check, if project is version controlled 3668 if self.vcs is None and self.isDirty() == oldState:
3415 pluginManager = ericApp().getObject("PluginManager") 3669 # check, if project is version controlled
3416 for ( 3670 pluginManager = ericApp().getObject("PluginManager")
3417 indicator, 3671 for (
3418 vcsData, 3672 indicator,
3419 ) in pluginManager.getVcsSystemIndicators().items(): 3673 vcsData,
3420 if os.path.exists(os.path.join(self.ppath, indicator)): 3674 ) in pluginManager.getVcsSystemIndicators().items():
3421 if len(vcsData) > 1: 3675 if os.path.exists(os.path.join(self.ppath, indicator)):
3422 vcsList = [] 3676 if len(vcsData) > 1:
3423 for _vcsSystemStr, vcsSystemDisplay in vcsData: 3677 vcsList = []
3424 vcsList.append(vcsSystemDisplay) 3678 for _vcsSystemStr, vcsSystemDisplay in vcsData:
3425 with EricOverridenCursor(): 3679 vcsList.append(vcsSystemDisplay)
3426 res, vcs_ok = QInputDialog.getItem( 3680 with EricOverridenCursor():
3427 None, 3681 res, vcs_ok = QInputDialog.getItem(
3428 self.tr("New Project"), 3682 None,
3429 self.tr("Select Version Control System"), 3683 self.tr("New Project"),
3430 vcsList, 3684 self.tr(
3431 0, 3685 "Select Version Control System"
3432 False, 3686 ),
3433 ) 3687 vcsList,
3434 if vcs_ok: 3688 0,
3435 for vcsSystemStr, vcsSystemDisplay in vcsData: 3689 False,
3436 if res == vcsSystemDisplay: 3690 )
3437 vcsSystem = vcsSystemStr 3691 if vcs_ok:
3438 break 3692 for (
3693 vcsSystemStr,
3694 vcsSystemDisplay,
3695 ) in vcsData:
3696 if res == vcsSystemDisplay:
3697 vcsSystem = vcsSystemStr
3698 break
3699 else:
3700 vcsSystem = "None"
3439 else: 3701 else:
3440 vcsSystem = "None" 3702 vcsSystem = "None"
3441 else: 3703 else:
3442 vcsSystem = "None" 3704 vcsSystem = vcsData[0][0]
3443 else: 3705 self.__pdata["VCS"] = vcsSystem
3444 vcsSystem = vcsData[0][0] 3706 self.vcs = self.initVCS()
3445 self.__pdata["VCS"] = vcsSystem 3707 self.setDirty(True)
3446 self.vcs = self.initVCS() 3708 if self.vcs is not None and (
3447 self.setDirty(True) 3709 self.vcs.vcsRegisteredState(self.ppath)
3448 if self.vcs is not None and ( 3710 != VersionControlState.Controlled
3449 self.vcs.vcsRegisteredState(self.ppath) 3711 ):
3450 != VersionControlState.Controlled 3712 self.__pdata["VCS"] = "None"
3451 ): 3713 self.vcs = self.initVCS()
3452 self.__pdata["VCS"] = "None"
3453 self.vcs = self.initVCS()
3454 self.reloadAct.setEnabled(True) 3714 self.reloadAct.setEnabled(True)
3455 self.closeAct.setEnabled(True) 3715 self.closeAct.setEnabled(True)
3456 self.saveasAct.setEnabled(True) 3716 self.saveasAct.setEnabled(True)
3457 self.saveasRemoteAct.setEnabled( 3717 self.saveasRemoteAct.setEnabled(
3458 self.__remoteServer.isServerConnected() 3718 self.__remoteServer.isServerConnected()
3459 and FileSystemUtilities.isRemoteFileName(self.pfile) 3719 and FileSystemUtilities.isRemoteFileName(self.pfile)
3460 ) 3720 )
3461 self.actGrp2.setEnabled(True) 3721 self.actGrp2.setEnabled(True)
3462 self.propsAct.setEnabled(True) 3722 self.propsAct.setEnabled(True)
3463 self.userPropsAct.setEnabled(True) 3723 self.userPropsAct.setEnabled(
3724 not FileSystemUtilities.isRemoteFileName(self.pfile)
3725 )
3464 self.filetypesAct.setEnabled(True) 3726 self.filetypesAct.setEnabled(True)
3465 self.lexersAct.setEnabled(True) 3727 self.lexersAct.setEnabled(True)
3466 self.sessActGrp.setEnabled(True) 3728 self.sessActGrp.setEnabled(True)
3467 self.dbgActGrp.setEnabled(True) 3729 self.dbgActGrp.setEnabled(True)
3468 self.menuDebuggerAct.setEnabled(True) 3730 self.menuDebuggerAct.setEnabled(True)
3469 self.menuSessionAct.setEnabled(True) 3731 self.menuSessionAct.setEnabled(True)
3470 self.menuCheckAct.setEnabled(True) 3732 self.menuCheckAct.setEnabled(True)
3471 self.menuShowAct.setEnabled(True) 3733 self.menuShowAct.setEnabled(True)
3472 self.menuDiagramAct.setEnabled(True) 3734 self.menuDiagramAct.setEnabled(True)
3473 self.menuApidocAct.setEnabled(True) 3735 self.menuApidocAct.setEnabled(
3474 self.menuPackagersAct.setEnabled(True) 3736 not FileSystemUtilities.isRemoteFileName(self.ppath)
3737 )
3738 self.menuPackagersAct.setEnabled(
3739 not FileSystemUtilities.isRemoteFileName(self.ppath)
3740 )
3475 self.pluginGrp.setEnabled( 3741 self.pluginGrp.setEnabled(
3476 self.__pdata["PROJECTTYPE"] in ["E7Plugin"] 3742 self.__pdata["PROJECTTYPE"] in ["E7Plugin"]
3743 and not FileSystemUtilities.isRemoteFileName(self.ppath)
3477 ) 3744 )
3478 self.addLanguageAct.setEnabled( 3745 self.addLanguageAct.setEnabled(
3479 bool(self.__pdata["TRANSLATIONPATTERN"]) 3746 bool(self.__pdata["TRANSLATIONPATTERN"])
3480 ) 3747 )
3481 self.makeGrp.setEnabled(self.__pdata["MAKEPARAMS"]["MakeEnabled"]) 3748 self.makeGrp.setEnabled(
3749 self.__pdata["MAKEPARAMS"]["MakeEnabled"]
3750 and not FileSystemUtilities.isRemoteFileName(self.ppath)
3751 )
3482 self.menuMakeAct.setEnabled( 3752 self.menuMakeAct.setEnabled(
3483 self.__pdata["MAKEPARAMS"]["MakeEnabled"] 3753 self.__pdata["MAKEPARAMS"]["MakeEnabled"]
3754 and not FileSystemUtilities.isRemoteFileName(self.ppath)
3484 ) 3755 )
3485 self.menuOtherToolsAct.setEnabled(True) 3756 self.menuOtherToolsAct.setEnabled(True)
3486 self.menuFormattingAct.setEnabled(True) 3757 self.menuFormattingAct.setEnabled(
3758 not FileSystemUtilities.isRemoteFileName(self.ppath)
3759 )
3760 self.menuVcsAct.setEnabled(
3761 not FileSystemUtilities.isRemoteFileName(self.ppath)
3762 )
3487 3763
3488 # open a project debugger properties file being quiet 3764 # open a project debugger properties file being quiet
3489 # about errors 3765 # about errors
3490 if Preferences.getProject("AutoLoadDbgProperties"): 3766 if Preferences.getProject("AutoLoadDbgProperties"):
3491 self.__readDebugProperties(True) 3767 self.__readDebugProperties(True)
3502 self.__venvConfiguration["interpreter"], os.X_OK 3778 self.__venvConfiguration["interpreter"], os.X_OK
3503 ): 3779 ):
3504 self.__configureEnvironment(envPath) 3780 self.__configureEnvironment(envPath)
3505 else: 3781 else:
3506 self.__createEmbeddedEnvironment() 3782 self.__createEmbeddedEnvironment()
3507 self.menuEnvironmentAct.setEnabled(self.__pdata["EMBEDDED_VENV"]) 3783 self.menuEnvironmentAct.setEnabled(
3784 self.__pdata["EMBEDDED_VENV"]
3785 and not FileSystemUtilities.isRemoteFileName(self.ppath)
3786 )
3508 3787
3509 self.projectOpenedHooks.emit() 3788 self.projectOpenedHooks.emit()
3510 self.projectOpened.emit() 3789 self.projectOpened.emit()
3511 3790
3512 if Preferences.getProject("SearchNewFiles"): 3791 if Preferences.getProject("SearchNewFiles"):
3533 self.__readSession(quiet=True, indicator="_tmp") 3812 self.__readSession(quiet=True, indicator="_tmp")
3534 elif Preferences.getProject("AutoLoadSession"): 3813 elif Preferences.getProject("AutoLoadSession"):
3535 self.__readSession(quiet=True) 3814 self.__readSession(quiet=True)
3536 3815
3537 # start the VCS monitor thread 3816 # start the VCS monitor thread
3538 self.__vcsConnectStatusMonitor() 3817 if not FileSystemUtilities.isRemoteFileName(self.ppath):
3818 self.__vcsConnectStatusMonitor()
3539 else: 3819 else:
3540 self.__initData() # delete all invalid data read 3820 self.__initData() # delete all invalid data read
3541 3821
3542 def reopenProject(self): 3822 def reopenProject(self):
3543 """ 3823 """
3717 success &= vm.closeWindow(fn, ignoreDirty=True) 3997 success &= vm.closeWindow(fn, ignoreDirty=True)
3718 if not success: 3998 if not success:
3719 return False 3999 return False
3720 4000
3721 # stop the VCS monitor thread 4001 # stop the VCS monitor thread
3722 if self.vcs is not None: 4002 if (
4003 not FileSystemUtilities.isRemoteFileName(self.ppath)
4004 and self.vcs is not None
4005 ):
3723 self.vcs.stopStatusMonitor() 4006 self.vcs.stopStatusMonitor()
3724 4007
3725 # now save the tasks 4008 # now save the tasks
3726 if not noSave: 4009 if not noSave:
3727 self.writeTasks() 4010 self.writeTasks()
3728 self.ui.taskViewer.clearProjectTasks() 4011 self.ui.taskViewer.clearProjectTasks()
3729 self.ui.taskViewer.setProjectOpen(False) 4012 self.ui.taskViewer.setProjectOpen(False)
3730 4013
3731 # now shutdown the vcs interface 4014 # now shutdown the vcs interface
3732 if self.vcs: 4015 if not FileSystemUtilities.isRemoteFileName(self.ppath) and self.vcs:
3733 self.vcs.vcsShutdown() 4016 self.vcs.vcsShutdown()
3734 self.vcs.deleteLater() 4017 self.vcs.deleteLater()
3735 self.vcs = None 4018 self.vcs = None
3736 ericApp().getObject("PluginManager").deactivateVcsPlugins() 4019 ericApp().getObject("PluginManager").deactivateVcsPlugins()
3737 4020
3793 filesWithSyntaxErrors += 1 4076 filesWithSyntaxErrors += 1
3794 4077
3795 if reportSyntaxErrors and filesWithSyntaxErrors > 0: 4078 if reportSyntaxErrors and filesWithSyntaxErrors > 0:
3796 EricMessageBox.critical( 4079 EricMessageBox.critical(
3797 self.ui, 4080 self.ui,
3798 self.tr("Syntax errors detected"), 4081 self.tr("Syntax Errors Detected"),
3799 self.tr( 4082 self.tr(
3800 """The project contains %n file(s) with syntax errors.""", 4083 """The project contains %n file(s) with syntax errors.""",
3801 "", 4084 "",
3802 filesWithSyntaxErrors, 4085 filesWithSyntaxErrors,
3803 ), 4086 ),
3829 filesWithSyntaxErrors += 1 4112 filesWithSyntaxErrors += 1
3830 4113
3831 if reportSyntaxErrors and filesWithSyntaxErrors > 0: 4114 if reportSyntaxErrors and filesWithSyntaxErrors > 0:
3832 EricMessageBox.critical( 4115 EricMessageBox.critical(
3833 self.ui, 4116 self.ui,
3834 self.tr("Syntax errors detected"), 4117 self.tr("Syntax Errors Detected"),
3835 self.tr( 4118 self.tr(
3836 """The project contains %n file(s) with syntax errors.""", 4119 """The project contains %n file(s) with syntax errors.""",
3837 "", 4120 "",
3838 filesWithSyntaxErrors, 4121 filesWithSyntaxErrors,
3839 ), 4122 ),
3854 @return filename of the projects main script 4137 @return filename of the projects main script
3855 @rtype str 4138 @rtype str
3856 """ 4139 """
3857 if self.__pdata["MAINSCRIPT"]: 4140 if self.__pdata["MAINSCRIPT"]:
3858 if normalized: 4141 if normalized:
3859 return os.path.join(self.ppath, self.__pdata["MAINSCRIPT"]) 4142 if FileSystemUtilities.isRemoteFileName(self.ppath):
4143 return self.__remotefsInterface.join(
4144 self.ppath, self.__pdata["MAINSCRIPT"]
4145 )
4146 else:
4147 return os.path.join(self.ppath, self.__pdata["MAINSCRIPT"])
3860 else: 4148 else:
3861 return self.__pdata["MAINSCRIPT"] 4149 return self.__pdata["MAINSCRIPT"]
3862 else: 4150 else:
3863 return "" 4151 return ""
3864 4152
3887 """ 4175 """
3888 if fileType not in self.getFileCategories(): 4176 if fileType not in self.getFileCategories():
3889 raise ValueError("Given file type has incorrect value.") 4177 raise ValueError("Given file type has incorrect value.")
3890 4178
3891 if normalized: 4179 if normalized:
3892 return [os.path.join(self.ppath, fn) for fn in self.__pdata[fileType]] 4180 if FileSystemUtilities.isRemoteFileName(self.ppath):
4181 return [
4182 self.__remotefsInterface.join(self.ppath, fn)
4183 for fn in self.__pdata[fileType]
4184 ]
4185 else:
4186 return [os.path.join(self.ppath, fn) for fn in self.__pdata[fileType]]
3893 else: 4187 else:
3894 return self.__pdata[fileType] 4188 return self.__pdata[fileType]
3895 4189
3896 def getProjectType(self): 4190 def getProjectType(self):
3897 """ 4191 """
3982 @return tuple containing the absolute path names of the project specific 4276 @return tuple containing the absolute path names of the project specific
3983 word and exclude list 4277 word and exclude list
3984 @rtype tuple of (str, str) 4278 @rtype tuple of (str, str)
3985 """ 4279 """
3986 pwl = "" 4280 pwl = ""
3987 if self.__pdata["SPELLWORDS"]:
3988 pwl = os.path.join(self.ppath, self.__pdata["SPELLWORDS"])
3989 if not os.path.isfile(pwl):
3990 pwl = ""
3991
3992 pel = "" 4281 pel = ""
3993 if self.__pdata["SPELLEXCLUDES"]: 4282
3994 pel = os.path.join(self.ppath, self.__pdata["SPELLEXCLUDES"]) 4283 if not FileSystemUtilities.isRemoteFileName(self.ppath):
3995 if not os.path.isfile(pel): 4284 if self.__pdata["SPELLWORDS"]:
3996 pel = "" 4285 pwl = os.path.join(self.ppath, self.__pdata["SPELLWORDS"])
4286 if not os.path.isfile(pwl):
4287 pwl = ""
4288
4289 if self.__pdata["SPELLEXCLUDES"]:
4290 pel = os.path.join(self.ppath, self.__pdata["SPELLEXCLUDES"])
4291 if not os.path.isfile(pel):
4292 pel = ""
3997 4293
3998 return (pwl, pel) 4294 return (pwl, pel)
3999 4295
4000 def getDefaultSourceExtension(self): 4296 def getDefaultSourceExtension(self):
4001 """ 4297 """
4017 @return project path 4313 @return project path
4018 @rtype str 4314 @rtype str
4019 """ 4315 """
4020 return self.ppath 4316 return self.ppath
4021 4317
4022 def startswithProjectPath(self, path): 4318 def startswithProjectPath(self, checkpath):
4023 """ 4319 """
4024 Public method to check, if a path starts with the project path. 4320 Public method to check, if a path starts with the project path.
4025 4321
4026 @param path path to be checked 4322 @param checkpath path to be checked
4027 @type str 4323 @type str
4028 @return flag indicating that the path starts with the project path 4324 @return flag indicating that the path starts with the project path
4029 @rtype bool 4325 @rtype bool
4030 """ 4326 """
4031 return bool(self.ppath) and ( 4327 if FileSystemUtilities.isRemoteFileName(self.ppath):
4032 path == self.ppath 4328 return checkpath == self.ppath or checkpath.startswith(
4033 or FileSystemUtilities.normcasepath( 4329 self.ppath + self.__remotefsInterface.separator()
4034 FileSystemUtilities.toNativeSeparators(path) 4330 )
4035 ).startswith( 4331 else:
4036 FileSystemUtilities.normcasepath( 4332 return bool(self.ppath) and (
4037 FileSystemUtilities.toNativeSeparators(self.ppath + "/") 4333 checkpath == self.ppath
4334 or FileSystemUtilities.normcasepath(
4335 FileSystemUtilities.toNativeSeparators(checkpath)
4336 ).startswith(
4337 FileSystemUtilities.normcasepath(
4338 FileSystemUtilities.toNativeSeparators(self.ppath + "/")
4339 )
4038 ) 4340 )
4039 ) 4341 )
4040 )
4041 4342
4042 def getProjectFile(self): 4343 def getProjectFile(self):
4043 """ 4344 """
4044 Public method to get the path of the project file. 4345 Public method to get the path of the project file.
4045 4346
4094 @return project hash as a hex string 4395 @return project hash as a hex string
4095 @rtype str 4396 @rtype str
4096 """ 4397 """
4097 return self.__pdata["HASH"] 4398 return self.__pdata["HASH"]
4098 4399
4099 def getRelativePath(self, path): 4400 def getRelativePath(self, fullpath):
4100 """ 4401 """
4101 Public method to convert a file path to a project relative 4402 Public method to convert a file path to a project relative
4102 file path. 4403 file path.
4103 4404
4104 @param path file or directory name to convert 4405 @param fullpath file or directory name to convert
4105 @type str 4406 @type str
4106 @return project relative path or unchanged path, if path doesn't 4407 @return project relative path or unchanged path, if path doesn't
4107 belong to the project 4408 belong to the project
4108 @rtype str 4409 @rtype str
4109 """ 4410 """
4110 if path is None: 4411 if fullpath is None:
4111 return "" 4412 return ""
4112 4413
4113 try: 4414 try:
4114 if FileSystemUtilities.isRemoteFileName(self.ppath): 4415 if FileSystemUtilities.isRemoteFileName(self.ppath):
4115 if self.__remotefsInterface.separator() == "\\": 4416 if self.__remotefsInterface.separator() == "\\":
4116 return str(pathlib.PureWindowsPath(path).relative_to(self.ppath)) 4417 return str(
4418 pathlib.PureWindowsPath(fullpath).relative_to(self.ppath)
4419 )
4117 else: 4420 else:
4118 return str(pathlib.PurePosixPath(path).relative_to(self.ppath)) 4421 return str(pathlib.PurePosixPath(fullpath).relative_to(self.ppath))
4119 else: 4422 else:
4120 return str(pathlib.PurePath(path).relative_to(self.ppath)) 4423 return str(pathlib.PurePath(fullpath).relative_to(self.ppath))
4121 except ValueError: 4424 except ValueError:
4122 return path 4425 return fullpath
4123 4426
4124 def getRelativeUniversalPath(self, path): 4427 def getRelativeUniversalPath(self, fullpath):
4125 """ 4428 """
4126 Public method to convert a file path to a project relative 4429 Public method to convert a file path to a project relative
4127 file path with universal separators. 4430 file path with universal separators.
4128 4431
4129 @param path file or directory name to convert 4432 @param fullpath file or directory name to convert
4130 @type str 4433 @type str
4131 @return project relative path or unchanged path, if path doesn't 4434 @return project relative path or unchanged path, if path doesn't
4132 belong to the project 4435 belong to the project
4133 @rtype str 4436 @rtype str
4134 """ 4437 """
4135 if FileSystemUtilities.isRemoteFileName(self.ppath): 4438 if FileSystemUtilities.isRemoteFileName(self.ppath):
4136 return self.__remotefsInterface.fromNativeSeparators( 4439 return self.__remotefsInterface.fromNativeSeparators(
4137 self.getRelativePath(path) 4440 self.getRelativePath(fullpath)
4138 ) 4441 )
4139 else: 4442 else:
4140 return FileSystemUtilities.fromNativeSeparators(self.getRelativePath(path)) 4443 return FileSystemUtilities.fromNativeSeparators(
4444 self.getRelativePath(fullpath)
4445 )
4141 4446
4142 def getAbsolutePath(self, fn): 4447 def getAbsolutePath(self, fn):
4143 """ 4448 """
4144 Public method to convert a project relative file path to an absolute 4449 Public method to convert a project relative file path to an absolute
4145 file path. 4450 file path.
4252 environment name via the debugger settings if none was configured 4557 environment name via the debugger settings if none was configured
4253 @type bool 4558 @type bool
4254 @return name of the project's virtual environment 4559 @return name of the project's virtual environment
4255 @rtype str 4560 @rtype str
4256 """ 4561 """
4562 # TODO: remote server not supported yet
4257 venvName = ( 4563 venvName = (
4258 self.__venvConfiguration["name"] 4564 self.__venvConfiguration["name"]
4259 if self.__pdata["EMBEDDED_VENV"] and bool(self.__venvConfiguration["name"]) 4565 if self.__pdata["EMBEDDED_VENV"] and bool(self.__venvConfiguration["name"])
4260 else self.getDebugProperty("VIRTUALENV") 4566 else self.getDebugProperty("VIRTUALENV")
4261 ) 4567 )
4273 Public method to get the path name of the embedded virtual environment. 4579 Public method to get the path name of the embedded virtual environment.
4274 4580
4275 @return path name of the embedded virtual environment 4581 @return path name of the embedded virtual environment
4276 @rtype str 4582 @rtype str
4277 """ 4583 """
4584 # TODO: remote server not supported yet
4278 if self.__pdata["EMBEDDED_VENV"]: 4585 if self.__pdata["EMBEDDED_VENV"]:
4279 return self.__findEmbeddedEnvironment() 4586 return self.__findEmbeddedEnvironment()
4280 else: 4587 else:
4281 return "" 4588 return ""
4282 4589
4289 environment was configured 4596 environment was configured
4290 @type bool 4597 @type bool
4291 @return path of the project's interpreter 4598 @return path of the project's interpreter
4292 @rtype str 4599 @rtype str
4293 """ 4600 """
4601 # TODO: remote server not supported yet
4294 interpreter = ( 4602 interpreter = (
4295 self.__venvConfiguration["interpreter"] 4603 self.__venvConfiguration["interpreter"]
4296 if self.__pdata["EMBEDDED_VENV"] 4604 if self.__pdata["EMBEDDED_VENV"]
4297 else "" 4605 else ""
4298 ) 4606 )
4314 Public method to get the executable search path prefix of the project. 4622 Public method to get the executable search path prefix of the project.
4315 4623
4316 @return executable search path prefix 4624 @return executable search path prefix
4317 @rtype str 4625 @rtype str
4318 """ 4626 """
4627 # TODO: remote server not supported yet
4319 if self.__pdata["EMBEDDED_VENV"]: 4628 if self.__pdata["EMBEDDED_VENV"]:
4320 execPath = self.__venvConfiguration["exec_path"] 4629 execPath = self.__venvConfiguration["exec_path"]
4321 else: 4630 else:
4322 execPath = "" 4631 execPath = ""
4323 venvName = self.getProjectVenv() 4632 venvName = self.getProjectVenv()
4335 Public method to get the testing framework name of the project. 4644 Public method to get the testing framework name of the project.
4336 4645
4337 @return testing framework name of the project 4646 @return testing framework name of the project
4338 @rtype str 4647 @rtype str
4339 """ 4648 """
4649 # TODO: remote server not supported yet
4340 try: 4650 try:
4341 return self.__pdata["TESTING_FRAMEWORK"] 4651 return self.__pdata["TESTING_FRAMEWORK"]
4342 except KeyError: 4652 except KeyError:
4343 return "" 4653 return ""
4344 4654
4362 @param fn filename to be checked 4672 @param fn filename to be checked
4363 @type str 4673 @type str
4364 @return flag indicating membership 4674 @return flag indicating membership
4365 @rtype bool 4675 @rtype bool
4366 """ 4676 """
4367 newfn = os.path.abspath(fn) 4677 newfn = (
4678 self.__remotefsInterface.abspath(fn)
4679 if FileSystemUtilities.isRemoteFileName(self.ppath)
4680 else os.path.abspath(fn)
4681 )
4368 newfn = self.getRelativePath(newfn) 4682 newfn = self.getRelativePath(newfn)
4369 return any( 4683 return any(
4370 newfn in self.__pdata[category] for category in self.getFileCategories() 4684 newfn in self.__pdata[category] for category in self.getFileCategories()
4371 ) 4685 )
4372 4686
4395 @param group group to check 4709 @param group group to check
4396 @type str 4710 @type str
4397 @return flag indicating membership 4711 @return flag indicating membership
4398 @rtype bool 4712 @rtype bool
4399 """ 4713 """
4400 newfn = fn if FileSystemUtilities.isRemoteFileName(fn) else os.path.abspath(fn) 4714 newfn = (
4715 self.__remotefsInterface.abspath(fn)
4716 if FileSystemUtilities.isRemoteFileName(fn)
4717 else os.path.abspath(fn)
4718 )
4401 newfn = self.getRelativePath(newfn) 4719 newfn = self.getRelativePath(newfn)
4402 if newfn in self.__pdata[group] or ( 4720 if newfn in self.__pdata[group] or (
4403 group == "OTHERS" 4721 group == "OTHERS"
4404 and any(newfn.startswith(entry) for entry in self.__pdata[group]) 4722 and any(newfn.startswith(entry) for entry in self.__pdata[group])
4405 ): 4723 ):
4406 return True 4724 return True
4407 4725
4408 if OSUtilities.isWindowsPlatform(): 4726 if (
4727 OSUtilities.isWindowsPlatform()
4728 or self.__remotefsInterface.separator() == "\\"
4729 ):
4409 # try the above case-insensitive 4730 # try the above case-insensitive
4410 newfn = newfn.lower() 4731 newfn = newfn.lower()
4411 if any(entry.lower() == newfn for entry in self.__pdata[group]): 4732 if any(entry.lower() == newfn for entry in self.__pdata[group]):
4412 return True 4733 return True
4413 4734
5692 self.menuSessionAct = menu.addMenu(self.sessionMenu) 6013 self.menuSessionAct = menu.addMenu(self.sessionMenu)
5693 6014
5694 # build the project tools menu 6015 # build the project tools menu
5695 toolsMenu.setTearOffEnabled(True) 6016 toolsMenu.setTearOffEnabled(True)
5696 toolsMenu.addSeparator() 6017 toolsMenu.addSeparator()
5697 toolsMenu.addMenu(self.vcsMenu) 6018 self.menuVcsAct = toolsMenu.addMenu(self.vcsMenu)
5698 toolsMenu.addSeparator() 6019 toolsMenu.addSeparator()
5699 self.menuCheckAct = toolsMenu.addMenu(self.checksMenu) 6020 self.menuCheckAct = toolsMenu.addMenu(self.checksMenu)
5700 toolsMenu.addSeparator() 6021 toolsMenu.addSeparator()
5701 self.menuFormattingAct = toolsMenu.addMenu(self.formattingMenu) 6022 self.menuFormattingAct = toolsMenu.addMenu(self.formattingMenu)
5702 toolsMenu.addSeparator() 6023 toolsMenu.addSeparator()
5766 def __showMenu(self): 6087 def __showMenu(self):
5767 """ 6088 """
5768 Private method to set up the project menu. 6089 Private method to set up the project menu.
5769 """ 6090 """
5770 self.menuRecentAct.setEnabled(len(self.recent) > 0) 6091 self.menuRecentAct.setEnabled(len(self.recent) > 0)
5771 self.menuEnvironmentAct.setEnabled(self.__pdata["EMBEDDED_VENV"]) 6092 self.menuEnvironmentAct.setEnabled(
6093 self.__pdata["EMBEDDED_VENV"]
6094 and not FileSystemUtilities.isRemoteFileName(self.ppath)
6095 )
5772 6096
5773 self.showMenu.emit("Main", self.__menus["Main"]) 6097 self.showMenu.emit("Main", self.__menus["Main"])
5774 6098
5775 def __syncRecent(self): 6099 def __syncRecent(self):
5776 """ 6100 """
5777 Private method to synchronize the list of recently opened projects 6101 Private method to synchronize the list of recently opened projects
5778 with the central store. 6102 with the central store.
5779 """ 6103 """
5780 for recent in self.recent[:]: 6104 for recent in self.recent[:]:
5781 if FileSystemUtilities.samepath(self.pfile, recent): 6105 if (
6106 FileSystemUtilities.isRemoteFileName(recent) and recent == self.pfile
6107 ) or FileSystemUtilities.samepath(self.pfile, recent):
5782 self.recent.remove(recent) 6108 self.recent.remove(recent)
5783 self.recent.insert(0, self.pfile) 6109 self.recent.insert(0, self.pfile)
5784 maxRecent = Preferences.getProject("RecentNumber") 6110 maxRecent = Preferences.getProject("RecentNumber")
5785 if len(self.recent) > maxRecent: 6111 if len(self.recent) > maxRecent:
5786 self.recent = self.recent[:maxRecent] 6112 self.recent = self.recent[:maxRecent]
5796 6122
5797 for idx, rp in enumerate(self.recent, start=1): 6123 for idx, rp in enumerate(self.recent, start=1):
5798 formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}" 6124 formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
5799 act = self.recentMenu.addAction( 6125 act = self.recentMenu.addAction(
5800 formatStr.format( 6126 formatStr.format(
5801 idx, FileSystemUtilities.compactPath(rp, self.ui.maxMenuFilePathLen) 6127 idx,
6128 self.__remotefsInterface.compactPath(rp, self.ui.maxMenuFilePathLen)
6129 if FileSystemUtilities.isRemoteFileName(rp)
6130 else FileSystemUtilities.compactPath(
6131 rp, self.ui.maxMenuFilePathLen
6132 ),
5802 ) 6133 )
5803 ) 6134 )
5804 act.setData(rp) 6135 act.setData(rp)
5805 act.setEnabled(pathlib.Path(rp).exists()) 6136 if FileSystemUtilities.isRemoteFileName(rp):
6137 act.setEnabled(
6138 self.__remoteServer.isServerConnected
6139 and self.__remotefsInterface.exists(rp)
6140 )
6141 else:
6142 act.setEnabled(pathlib.Path(rp).exists())
5806 6143
5807 self.recentMenu.addSeparator() 6144 self.recentMenu.addSeparator()
5808 self.recentMenu.addAction(self.tr("&Clear"), self.clearRecent) 6145 self.recentMenu.addAction(self.tr("&Clear"), self.clearRecent)
5809 6146
5810 def __openRecent(self, act): 6147 def __openRecent(self, act):
5851 if self.__findProjectFileDialog is None: 6188 if self.__findProjectFileDialog is None:
5852 self.__findProjectFileDialog = QuickFindFileDialog(self) 6189 self.__findProjectFileDialog = QuickFindFileDialog(self)
5853 self.__findProjectFileDialog.sourceFile.connect(self.sourceFile) 6190 self.__findProjectFileDialog.sourceFile.connect(self.sourceFile)
5854 self.__findProjectFileDialog.designerFile.connect(self.designerFile) 6191 self.__findProjectFileDialog.designerFile.connect(self.designerFile)
5855 self.__findProjectFileDialog.linguistFile.connect(self.linguistFile) 6192 self.__findProjectFileDialog.linguistFile.connect(self.linguistFile)
5856 self.__findProjectFileDialog.show() 6193 self.__findProjectFileDialog.show(
6194 FileSystemUtilities.isRemoteFileName(self.ppath)
6195 )
5857 self.__findProjectFileDialog.raise_() 6196 self.__findProjectFileDialog.raise_()
5858 self.__findProjectFileDialog.activateWindow() 6197 self.__findProjectFileDialog.activateWindow()
5859 6198
5860 def __doSearchNewFiles(self, AI=True, onUserDemand=False): 6199 def __doSearchNewFiles(self, AI=True, onUserDemand=False):
5861 """ 6200 """
5877 6216
5878 autoInclude = Preferences.getProject("AutoIncludeNewFiles") 6217 autoInclude = Preferences.getProject("AutoIncludeNewFiles")
5879 recursiveSearch = Preferences.getProject("SearchNewFilesRecursively") 6218 recursiveSearch = Preferences.getProject("SearchNewFilesRecursively")
5880 newFiles = [] 6219 newFiles = []
5881 6220
6221 isRemote = FileSystemUtilities.isRemoteFileName(self.ppath)
6222
5882 ignore_patterns = [ 6223 ignore_patterns = [
5883 pattern 6224 pattern
5884 for pattern, filetype in self.__pdata["FILETYPES"].items() 6225 for pattern, filetype in self.__pdata["FILETYPES"].items()
5885 if filetype == "__IGNORE__" 6226 if filetype == "__IGNORE__"
5886 ] 6227 ]
5887 6228
5888 dirs = self.subdirs[:] 6229 dirs = [""] if recursiveSearch else self.subdirs[:] + [""]
5889 for directory in dirs: 6230 for directory in dirs:
5890 skip = False 6231 skip = False
5891 for ignore_pattern in ignore_patterns: 6232 for ignore_pattern in ignore_patterns:
5892 if fnmatch.fnmatch(directory, ignore_pattern): 6233 if fnmatch.fnmatch(directory, ignore_pattern):
5893 skip = True 6234 skip = True
5894 break 6235 break
5895 if skip: 6236 if skip:
5896 continue 6237 continue
5897 6238
5898 curpath = os.path.join(self.ppath, directory) 6239 curpath = (
6240 self.__remotefsInterface.join(self.ppath, directory)
6241 if isRemote
6242 else os.path.join(self.ppath, directory)
6243 )
5899 try: 6244 try:
5900 newSources = os.listdir(curpath) 6245 newSources = (
6246 [e["name"] for e in self.__remotefsInterface.listdir(curpath)[2]]
6247 if isRemote
6248 else os.listdir(curpath)
6249 )
5901 except OSError: 6250 except OSError:
5902 newSources = [] 6251 newSources = []
5903 pattern = ( 6252 pattern = (
5904 self.__pdata["TRANSLATIONPATTERN"].replace("%language%", "*") 6253 self.__pdata["TRANSLATIONPATTERN"].replace("%language%", "*")
5905 if self.__pdata["TRANSLATIONPATTERN"] 6254 if self.__pdata["TRANSLATIONPATTERN"]
5906 else "*.ts" 6255 else "*.ts"
5907 ) 6256 )
5908 binpattern = self.__binaryTranslationFile(pattern) 6257 binpattern = self.__binaryTranslationFile(pattern)
5909 for ns in newSources: 6258 for ns in newSources:
5910 # ignore hidden files and directories 6259 # ignore hidden files and directories
5911 if ns.startswith("."): 6260 if ns.startswith(".") or ns == "__pycache__":
5912 continue
5913 if (
5914 OSUtilities.isWindowsPlatform()
5915 and os.path.isdir(os.path.join(curpath, ns))
5916 and ns.startswith("_")
5917 ):
5918 # dot net hack
5919 continue 6261 continue
5920 6262
5921 # set fn to project relative name 6263 # set fn to project relative name
5922 # then reset ns to fully qualified name for insertion, 6264 # then reset ns to fully qualified name for insertion,
5923 # possibly. 6265 # possibly.
5924 fn = os.path.join(directory, ns) if directory else ns 6266 if isRemote:
5925 ns = os.path.abspath(os.path.join(curpath, ns)) 6267 fn = (
6268 self.__remotefsInterface.join(directory, ns)
6269 if directory
6270 else ns
6271 )
6272 ns = self.__remotefsInterface.abspath(
6273 self.__remotefsInterface.join(curpath, ns)
6274 )
6275
6276 isdir_ns = self.__remotefsInterface.isdir(ns)
6277 else:
6278 fn = os.path.join(directory, ns) if directory else ns
6279 ns = os.path.abspath(os.path.join(curpath, ns))
6280 isdir_ns = os.path.isdir(ns)
5926 6281
5927 # do not bother with dirs here... 6282 # do not bother with dirs here...
5928 if os.path.isdir(ns): 6283 if isdir_ns:
5929 if recursiveSearch: 6284 if recursiveSearch:
5930 d = self.getRelativePath(ns) 6285 d = self.getRelativePath(ns)
5931 if d not in dirs: 6286 if d not in dirs:
5932 dirs.append(d) # noqa: M538 6287 dirs.append(d) # noqa: M538
5933 continue 6288 continue
5934 6289
5935 filetype = "" 6290 filetype = ""
5936 bfn = os.path.basename(fn) 6291 bfn = (
6292 self.__remotefsInterface.basename(fn)
6293 if isRemote
6294 else os.path.basename(fn)
6295 )
5937 for pattern in sorted(self.__pdata["FILETYPES"], reverse=True): 6296 for pattern in sorted(self.__pdata["FILETYPES"], reverse=True):
5938 if fnmatch.fnmatch(bfn, pattern): 6297 if fnmatch.fnmatch(bfn, pattern):
5939 filetype = self.__pdata["FILETYPES"][pattern] 6298 filetype = self.__pdata["FILETYPES"][pattern]
5940 break 6299 break
5941 6300
6254 """ 6613 """
6255 Private slot used to calculate some code metrics for the project files. 6614 Private slot used to calculate some code metrics for the project files.
6256 """ 6615 """
6257 from eric7.DataViews.CodeMetricsDialog import CodeMetricsDialog 6616 from eric7.DataViews.CodeMetricsDialog import CodeMetricsDialog
6258 6617
6259 files = [ 6618 files = (
6260 os.path.join(self.ppath, file) 6619 [
6261 for file in self.__pdata["SOURCES"] 6620 self.__remotefsInterface.join(self.ppath, file)
6262 if file.endswith(".py") 6621 for file in self.__pdata["SOURCES"]
6263 ] 6622 if file.endswith(".py")
6623 ]
6624 if FileSystemUtilities.isRemoteFileName(self.ppath)
6625 else [
6626 os.path.join(self.ppath, file)
6627 for file in self.__pdata["SOURCES"]
6628 if file.endswith(".py")
6629 ]
6630 )
6264 self.codemetrics = CodeMetricsDialog() 6631 self.codemetrics = CodeMetricsDialog()
6265 self.codemetrics.show() 6632 self.codemetrics.show()
6266 self.codemetrics.prepare(files) 6633 self.codemetrics.prepare(files)
6267 6634
6268 def __showCodeCoverage(self): 6635 def __showCodeCoverage(self):
6300 else: 6667 else:
6301 fn = files[0] 6668 fn = files[0]
6302 else: 6669 else:
6303 return 6670 return
6304 6671
6305 files = [ 6672 files = (
6306 os.path.join(self.ppath, file) 6673 [
6307 for file in self.__pdata["SOURCES"] 6674 self.__remotefsInterface.join(self.ppath, file)
6308 if os.path.splitext(file)[1].startswith(".py") 6675 for file in self.__pdata["SOURCES"]
6309 ] 6676 if self.__remotefsInterface.splitext(file)[1].startswith(".py")
6677 ]
6678 if FileSystemUtilities.isRemoteFileName(self.ppath)
6679 else [
6680 os.path.join(self.ppath, file)
6681 for file in self.__pdata["SOURCES"]
6682 if os.path.splitext(file)[1].startswith(".py")
6683 ]
6684 )
6310 self.codecoverage = PyCoverageDialog() 6685 self.codecoverage = PyCoverageDialog()
6311 self.codecoverage.show() 6686 self.codecoverage.show()
6312 self.codecoverage.start(fn, files) 6687 self.codecoverage.start(fn, files)
6313 6688
6314 def __showProfileData(self): 6689 def __showProfileData(self):
6915 Public method to test, if make is enabled for the project. 7290 Public method to test, if make is enabled for the project.
6916 7291
6917 @return flag indicating enabled make support 7292 @return flag indicating enabled make support
6918 @rtype bool 7293 @rtype bool
6919 """ 7294 """
6920 return self.__pdata["MAKEPARAMS"]["MakeEnabled"] 7295 return self.__pdata["MAKEPARAMS"][
7296 "MakeEnabled"
7297 ] and not FileSystemUtilities.isRemoteFileName(self.ppath)
6921 7298
6922 @pyqtSlot() 7299 @pyqtSlot()
6923 def __autoExecuteMake(self): 7300 def __autoExecuteMake(self):
6924 """ 7301 """
6925 Private slot to execute a project specific make run (auto-run) 7302 Private slot to execute a project specific make run (auto-run)
6926 (execute or question). 7303 (execute or question).
6927 """ 7304 """
6928 if Preferences.getProject("AutoExecuteMake"): 7305 if Preferences.getProject(
7306 "AutoExecuteMake"
7307 ) and not FileSystemUtilities.isRemoteFileName(self.ppath):
6929 self.__executeMake( 7308 self.__executeMake(
6930 questionOnly=self.__pdata["MAKEPARAMS"]["MakeTestOnly"], 7309 questionOnly=self.__pdata["MAKEPARAMS"]["MakeTestOnly"],
6931 interactive=False, 7310 interactive=False,
6932 ) 7311 )
6933 7312
6940 @type bool 7319 @type bool
6941 @param interactive flag indicating an interactive invocation (i.e. 7320 @param interactive flag indicating an interactive invocation (i.e.
6942 through a menu action) 7321 through a menu action)
6943 @type bool 7322 @type bool
6944 """ 7323 """
7324 if FileSystemUtilities.isRemoteFileName(self.ppath):
7325 EricMessageBox.critical(
7326 self.ui,
7327 self.tr("Execute Make"),
7328 self.tr("'Make' is not supported for remote projects. Aborting..."),
7329 )
7330 return
7331
6945 if ( 7332 if (
6946 not self.__pdata["MAKEPARAMS"]["MakeEnabled"] 7333 not self.__pdata["MAKEPARAMS"]["MakeEnabled"]
6947 or self.__makeProcess is not None 7334 or self.__makeProcess is not None
6948 ): 7335 ):
6949 return 7336 return
7165 7552
7166 def __showContextMenuOthers(self): 7553 def __showContextMenuOthers(self):
7167 """ 7554 """
7168 Private slot called before the 'Other Tools' menu is shown. 7555 Private slot called before the 'Other Tools' menu is shown.
7169 """ 7556 """
7557 self.createSBOMAct.setEnabled(
7558 not FileSystemUtilities.isRemoteFileName(self.ppath)
7559 )
7560
7170 self.showMenu.emit("OtherTools", self.othersMenu) 7561 self.showMenu.emit("OtherTools", self.othersMenu)
7171 7562
7172 @pyqtSlot() 7563 @pyqtSlot()
7173 def __createSBOMFile(self): 7564 def __createSBOMFile(self):
7174 """ 7565 """

eric ide

mercurial