def addRepo(self, group, root, row=-1): grp = group if grp == None: grp = self.allreposIndex() rgi = grp.internalPointer() if row < 0: row = rgi.childCount() # make sure all paths are properly normalized root = os.path.normpath(root) # Check whether the repo that we are adding is a subrepo # This check could be expensive, particularly for network repositories # Thus, only perform this check on network repos if the showNetworkSubrepos # flag is set itemIsSubrepo = False if self.showNetworkSubrepos \ or not paths.netdrive_status(root): outerrepopath = paths.find_root(os.path.dirname(root)) if outerrepopath: # Check whether repo we are adding is a subrepo of # its containing (outer) repo # This check is currently quite imperfect, since it # only checks the current repo revision outerrepo = hg.repository(ui.ui(), path=outerrepopath) relroot = util.normpath(root[len(outerrepopath) + 1:]) if relroot in outerrepo['.'].substate: itemIsSubrepo = True self.beginInsertRows(grp, row, row) if itemIsSubrepo: ri = SubrepoItem(root) else: ri = RepoItem(root) rgi.insertChild(row, ri) if not self.showSubrepos \ or (not self.showNetworkSubrepos and paths.netdrive_status(root)): self.endInsertRows() return invalidRepoList = ri.appendSubrepos() self.endInsertRows() if invalidRepoList: if invalidRepoList[0] == root: qtlib.WarningMsgBox( _('Could not get subrepository list'), _('It was not possible to get the subrepository list for ' 'the repository in:<br><br><i>%s</i>') % root) else: qtlib.WarningMsgBox( _('Could not open some subrepositories'), _('It was not possible to fully load the subrepository ' 'list for the repository in:<br><br><i>%s</i><br><br>' 'The following subrepositories may be missing, broken or ' 'on an inconsistent state and cannot be accessed:' '<br><br><i>%s</i>') % (root, "<br>".join(invalidRepoList)))
def updateModel(self, wctx, patchecked): self.tv.setSortingEnabled(False) if self.tv.model(): checked = self.tv.model().getChecked() else: checked = patchecked if self.pats and not checked: qtlib.WarningMsgBox(_('No appropriate files'), _('No files found for this operation'), parent=self) ms = merge.mergestate(self.repo) tm = WctxModel(wctx, ms, self.pctx, self.savechecks, self.opts, checked, self, checkable=self.checkable, defcheck=self.defcheck) if self.checkable: tm.checkToggled.connect(self.checkToggled) tm.checkCountChanged.connect(self.updateCheckCount) self.savechecks = True oldtm = self.tv.model() self.tv.setModel(tm) if oldtm: oldtm.deleteLater() self.tv.setSortingEnabled(True) self.tv.setColumnHidden(COL_PATH, bool(wctx.p2()) or not self.checkable) self.tv.setColumnHidden(COL_MERGE_STATE, not tm.anyMerge()) if self.checkable: self.updateCheckCount() for col in (COL_PATH, COL_STATUS, COL_MERGE_STATE): w = self.tv.sizeHintForColumn(col) self.tv.setColumnWidth(col, w) for col in (COL_PATH_DISPLAY, COL_EXTENSION, COL_SIZE): self.tv.resizeColumnToContents(col) # reset selection, or select first row curidx = tm.index(0, 0) selmodel = self.tv.selectionModel() flags = QItemSelectionModel.Select | QItemSelectionModel.Rows if self.reselection: selected, current = self.reselection for i, row in enumerate(tm.getAllRows()): if row[COL_PATH] in selected: selmodel.select(tm.index(i, 0), flags) if row[COL_PATH] == current: curidx = tm.index(i, 0) else: selmodel.select(curidx, flags) selmodel.currentChanged.connect(self.onCurrentChange) selmodel.selectionChanged.connect(self.onSelectionChange) if curidx and curidx.isValid(): selmodel.setCurrentIndex(curidx, QItemSelectionModel.Current) self.onSelectionChange(None, None)
def writeIgnoreFile(self): eol = self.doseoln and '\r\n' or '\n' out = eol.join(self.ignorelines) + eol hasignore = os.path.exists(self.repo.join(self.ignorefile)) try: f = util.atomictempfile(self.ignorefile, 'wb', createmode=None) f.write(out) f.close() if not hasignore: ret = qtlib.QuestionMsgBox( _('New file created'), _('TortoiseHg has created a new ' '.hgignore file. Would you like to ' 'add this file to the source code ' 'control repository?'), parent=self) if ret: commands.add(ui.ui(), self.repo, self.ignorefile) shlib.shell_notify([self.ignorefile]) self.ignoreFilterUpdated.emit() except EnvironmentError, e: qtlib.WarningMsgBox(_('Unable to write .hgignore file'), hglib.tounicode(str(e)), parent=self)
def accept(self): cmdopts = {} if hasattr(self, 'chk'): if self.command == 'revert': cmdopts['no_backup'] = self.chk.isChecked() elif self.command == 'remove': cmdopts['force'] = self.chk.isChecked() files = self.stwidget.getChecked() if not files: qtlib.WarningMsgBox(_('No files selected'), _('No operation to perform'), parent=self) return self.repo.bfstatus = True self.repo.lfstatus = True repostate = self.repo.status() self.repo.bfstatus = False self.repo.lfstatus = False if self.command == 'remove': if not self.chk.isChecked(): modified = repostate[0] selmodified = [] for wfile in files: if wfile in modified: selmodified.append(wfile) if selmodified: prompt = qtlib.CustomPrompt( _('Confirm Remove'), _('You have selected one or more files that have been ' 'modified. By default, these files will not be ' 'removed. What would you like to do?'), self, (_('Remove &Unmodified Files'), _('Remove &All Selected Files'), _('Cancel')), 0, 2, selmodified) ret = prompt.run() if ret == 1: cmdopts['force'] = True elif ret == 2: return unknown, ignored = repostate[4:6] for wfile in files: if wfile in unknown or wfile in ignored: try: util.unlink(wfile) except EnvironmentError: pass files.remove(wfile) elif self.command == 'add': if 'largefiles' in self.repo.extensions(): self.addWithPrompt(files) return if files: cmdline = hglib.buildcmdargs(self.command, *files, **cmdopts) self.files = files self.cmd.run(cmdline) else: self.reject()
def rename(self): """execute the rename""" # check inputs src = self.get_src() dest = self.get_dest() if not os.path.exists(src): qtlib.WarningMsgBox(self.msgTitle, _('Source does not exists.')) return fullsrc = os.path.abspath(src) if not fullsrc.startswith(self.repo.root): qtlib.ErrorMsgBox(self.errTitle, _('The source must be within the repository tree.')) return fulldest = os.path.abspath(dest) if not fulldest.startswith(self.repo.root): qtlib.ErrorMsgBox(self.errTitle, _('The destination must be within the repository tree.')) return if src == dest: qtlib.ErrorMsgBox(self.errTitle, _('Please give a destination that differs from the source')) return if (os.path.isfile(dest) and not self.isCaseFoldingOnWin()): res = qtlib.QuestionMsgBox(self.msgTitle, '<p>%s</p><p>%s</p>' % (_('Destination file already exists.'), _('Are you sure you want to overwrite it ?')), defaultbutton=QMessageBox.No) if not res: return cmdline = self.compose_command(src, dest) self.show_command(cmdline) if self.isCaseFoldingOnWin(): # We do the rename ourselves if it's a pure casefolding # action on Windows. Because there is no way to make Hg # do 'hg mv foo Foo' correctly there. if self.copy_chk.isChecked(): qtlib.ErrorMsgBox(self.errTitle, _('Cannot do a pure casefolding copy on Windows')) return else: try: targetdir = os.path.dirname(fulldest) if not os.path.isdir(targetdir): os.makedirs(targetdir) os.rename(fullsrc, fulldest) except (OSError, IOError), inst: if self.copy_chk.isChecked(): txt = _('The following error was caught while copying:') else: txt = _('The following error was caught while renaming:') qtlib.ErrorMsgBox(self.errTitle, txt, hglib.tounicode(str(inst))) return
def fileEditor(filename, **opts): 'Open a simple modal file editing dialog' dialog = QDialog() dialog.setWindowFlags(dialog.windowFlags() & ~Qt.WindowContextHelpButtonHint | Qt.WindowMaximizeButtonHint) dialog.setWindowTitle(filename) dialog.setLayout(QVBoxLayout()) editor = Scintilla() editor.setBraceMatching(QsciScintilla.SloppyBraceMatch) editor.installEventFilter(KeyPressInterceptor(dialog)) editor.setMarginLineNumbers(1, True) editor.setMarginWidth(1, '000') editor.setLexer(QsciLexerProperties()) if opts.get('foldable'): editor.setFolding(QsciScintilla.BoxedTreeFoldStyle) dialog.layout().addWidget(editor) searchbar = SearchToolBar(dialog, hidable=True) searchbar.searchRequested.connect(editor.find) searchbar.conditionChanged.connect(editor.highlightText) searchbar.hide() def showsearchbar(): searchbar.show() searchbar.setFocus(Qt.OtherFocusReason) qtlib.newshortcutsforstdkey(QKeySequence.Find, dialog, showsearchbar) dialog.layout().addWidget(searchbar) BB = QDialogButtonBox bb = QDialogButtonBox(BB.Save|BB.Cancel) bb.accepted.connect(dialog.accept) bb.rejected.connect(dialog.reject) dialog.layout().addWidget(bb) s = QSettings() geomname = 'editor-geom' desktopgeom = qApp.desktop().availableGeometry() dialog.resize(desktopgeom.size() * 0.5) dialog.restoreGeometry(s.value(geomname).toByteArray()) ret = QDialog.Rejected try: f = QFile(filename) f.open(QIODevice.ReadOnly) editor.read(f) editor.setModified(False) ret = dialog.exec_() if ret == QDialog.Accepted: f = QFile(filename) f.open(QIODevice.WriteOnly) editor.write(f) s.setValue(geomname, dialog.saveGeometry()) except EnvironmentError, e: qtlib.WarningMsgBox(_('Unable to read/write config file'), hglib.tounicode(str(e)), parent=dialog)
def addLfiles(self): if 'largefiles' in self.repo.extensions(): cmdline = ['add', '--large'] files = self.stwidget.getChecked() if not files: qtlib.WarningMsgBox(_('No files selected'), _('No operation to perform'), parent=self) return cmdline.extend(files) self.files = files self.cmd.run(cmdline)
def _runCustomCommandByMenu(self, action): files = [ file for file in self._selectedfiles if os.path.exists(self.repo.wjoin(file)) ] if not files: qtlib.WarningMsgBox( _('File(s) not found'), _('The selected files do not exist in the working directory')) return self.runCustomCommandRequested.emit(str(action.data().toString()), files)
def setData(self, column, value): if column == 0: shortname = hglib.fromunicode(value.toString()) abshgrcpath = os.path.join(self.rootpath(), '.hg', 'hgrc') if not hgrcutil.setConfigValue(abshgrcpath, 'web.name', shortname): qtlib.WarningMsgBox(_('Unable to update repository name'), _('An error occurred while updating the repository hgrc ' 'file (%s)') % hglib.tounicode(abshgrcpath)) return False self.setShortName(shortname) return True return False
def _scanAddedRepo(self, index): m = self.tview.model() invalidpaths = m.loadSubrepos(index) if not invalidpaths: return root = m.repoRoot(index) if root in invalidpaths: qtlib.WarningMsgBox( _('Could not get subrepository list'), _('It was not possible to get the subrepository list for ' 'the repository in:<br><br><i>%s</i>') % root, parent=self) else: qtlib.WarningMsgBox( _('Could not open some subrepositories'), _('It was not possible to fully load the subrepository ' 'list for the repository in:<br><br><i>%s</i><br><br>' 'The following subrepositories may be missing, broken or ' 'on an inconsistent state and cannot be accessed:' '<br><br><i>%s</i>') % (root, "<br>".join(invalidpaths)), parent=self)
def archive(self): # verify input type = self.get_selected_archive_type()['type'] dest = unicode(self.dest_edit.text()) if os.path.exists(dest): if type == 'files': if os.path.isfile(dest): qtlib.WarningMsgBox(_('Duplicate Name'), _('The destination "%s" already exists as ' 'a file!') % dest) return False elif os.listdir(dest): if not qtlib.QuestionMsgBox(_('Confirm Overwrite'), _('The directory "%s" is not empty!\n\n' 'Do you want to overwrite it?') % dest, parent=self): return False else: if os.path.isfile(dest): if not qtlib.QuestionMsgBox(_('Confirm Overwrite'), _('The file "%s" already exists!\n\n' 'Do you want to overwrite it?') % dest, parent=self): return False else: qtlib.WarningMsgBox(_('Duplicate Name'), _('The destination "%s" already exists as ' 'a folder!') % dest) return False # prepare command line cmdline = self.compose_command(hglib.fromunicode(dest), type) if self.files_in_rev_chk.isChecked(): self.savedcwd = os.getcwd() os.chdir(self.repo.root) # start archiving self.cmd.run(cmdline)
def mouseDoubleClickEvent(self, event): if self.selitem and self.selitem.internalPointer().isRepo(): # We can only open mercurial repositories and subrepositories repotype = self.selitem.internalPointer().repotype() if repotype == 'hg': self.showFirstTabOrOpen() else: qtlib.WarningMsgBox( _('Unsupported repository type (%s)') % repotype, _('Cannot open non Mercurial repositories or subrepositories' ), parent=self) else: # a double-click on non-repo rows opens an editor super(RepoTreeView, self).mouseDoubleClickEvent(event)
def addEntry(self): newfilter = hglib.fromunicode(self.le.text()).strip() if newfilter == '': return self.le.clear() if self.recombo.currentIndex() == 0: test = 'glob:' + newfilter try: match.match(self.repo.root, '', [], [test]) self.insertFilters([newfilter], False) except util.Abort, inst: qtlib.WarningMsgBox(_('Invalid glob expression'), str(inst), parent=self) return
def addNewRepo(self): 'menu action handler for adding a new repository' caption = _('Select repository directory to add') FD = QFileDialog path = FD.getExistingDirectory(caption=caption, options=FD.ShowDirsOnly | FD.ReadOnly) if path: root = paths.find_root(hglib.fromunicode(path)) if root and not self.tview.model().getRepoItem(root): try: self.tview.model().addRepo(self.selitem, root) except error.RepoError: qtlib.WarningMsgBox(_('Failed to add repository'), _('%s is not a valid repository') % path, parent=self) return
def open(self, root=None): 'open context menu action, open repowidget unconditionally' if not root: root = self.selitem.internalPointer().rootpath() repotype = self.selitem.internalPointer().repotype() else: root = hglib.fromunicode(root) if os.path.exists(os.path.join(root, '.hg')): repotype = 'hg' else: repotype = 'unknown' if repotype == 'hg': self.openRepo.emit(hglib.tounicode(root), False) else: qtlib.WarningMsgBox( _('Unsupported repository type (%s)') % repotype, _('Cannot open non Mercurial repositories or subrepositories'), parent=self)
def promptForLfiles(parent, ui, repo, files): lfiles = [] section = 'largefiles' try: minsize = float(ui.config(section, 'minsize', default=10)) except ValueError: minsize = 10 patterns = ui.config(section, 'patterns', default=()) if patterns: patterns = patterns.split(' ') try: matcher = match.match(repo.root, '', list(patterns)) except error.Abort as e: qtlib.WarningMsgBox(_('Invalid Patterns'), _('Failed to process largefiles.patterns.'), hglib.tounicode(str(e)), parent=parent) return None else: matcher = None for wfile in files: if matcher and matcher(wfile): # patterns have always precedence over size lfiles.append(wfile) else: # check for minimal size try: filesize = os.path.getsize(repo.wjoin(wfile)) if filesize > minsize * 1024 * 1024: lfiles.append(wfile) except OSError: pass # file not exist or inaccessible if lfiles: ret = _createPrompt(parent, files).run() if ret == 0: # add as largefiles/bfiles for lfile in lfiles: files.remove(lfile) elif ret == 1: # add as normal files lfiles = [] elif ret == 2: return None return files, lfiles
def validatePage(self): if self.cmd.core.running(): return False if len(self.repo.parents()) == 1: # commit succeeded, repositoryChanged() called wizard().next() if self.skiplast.isChecked(): self.wizard().close() return True user = qtlib.getCurrentUsername(self, self.repo, self.opts) if not user: return False self.setTitle(_('Committing...')) self.setSubTitle(_('Please wait while committing merged files.')) message = hglib.fromunicode(self.msgEntry.text()) cmdline = [ 'commit', '--verbose', '--message', message, '--repository', self.repo.root, '--user', user ] if self.opts.get('recurseinsubrepos'): cmdline.append('--subrepos') try: date = self.opts.get('date') if date: util.parsedate(date) dcmd = ['--date', date] else: dcmd = [] except error.Abort, e: if e.hint: err = _('%s (hint: %s)') % (hglib.tounicode( str(e)), hglib.tounicode(e.hint)) else: err = hglib.tounicode(str(e)) qtlib.WarningMsgBox( _('TortoiseHg Merge Commit'), _('Error creating interpreting commit date (%s).\n' 'Using current date instead.'), err) dcmd = []
def loadIniFile(rcpath, parent=None): for fn in rcpath: if os.path.exists(fn): break else: for fn in rcpath: # Try to create a file from rcpath try: f = open(fn, 'w') f.write('# Generated by TortoiseHg\n') f.close() break except EnvironmentError: pass else: qtlib.WarningMsgBox(_('Unable to create a config file'), _('Insufficient access rights.'), parent=parent) return None, {} return fn, wconfig.readfile(fn)
def __call__(self, dlgfunc, ui, *args, **opts): portable_fork(ui, opts) if self._mainapp: self._opendialog(dlgfunc, ui, *args, **opts) return QSettings.setDefaultFormat(QSettings.IniFormat) self._mainapp = QApplication(sys.argv) self._gc = GarbageCollector(self, self.debug) try: # default org is used by QSettings self._mainapp.setApplicationName('TortoiseHgQt') self._mainapp.setOrganizationName('TortoiseHg') self._mainapp.setOrganizationDomain('tortoisehg.org') self._mainapp.setApplicationVersion(thgversion.version()) self._installtranslator() qtlib.setup_font_substitutions() qtlib.fix_application_font() qtlib.configstyles(ui) qtlib.initfontcache(ui) self._mainapp.setWindowIcon(qtlib.geticon('thg-logo')) if 'repository' in opts: try: # Ensure we can open the repository before opening any # dialog windows. Since thgrepo instances are cached, this # is not wasted. from tortoisehg.hgqt import thgrepo thgrepo.repository(ui, opts['repository']) except error.RepoError, e: qtlib.WarningMsgBox(hglib.tounicode(_('Repository Error')), hglib.tounicode(str(e))) return dlg = dlgfunc(ui, *args, **opts) if dlg: dlg.show() dlg.raise_()
def rename(self): """execute the rename""" # check inputs src = self.get_src() dest = self.get_dest() if not os.path.exists(src): qtlib.WarningMsgBox(self.msgTitle, _('Source does not exists.')) return fullsrc = os.path.abspath(src) if not fullsrc.startswith(self.repo.root): qtlib.ErrorMsgBox(self.errTitle, _('The source must be within the repository tree.')) return fulldest = os.path.abspath(dest) if not fulldest.startswith(self.repo.root): qtlib.ErrorMsgBox(self.errTitle, _('The destination must be within the repository tree.')) return if src == dest: qtlib.ErrorMsgBox(self.errTitle, _('Please give a destination that differs from the source')) return if (os.path.isfile(dest) and not self.isCaseFoldingOnWin()): res = qtlib.QuestionMsgBox(self.msgTitle, '<p>%s</p><p>%s</p>' % (_('Destination file already exists.'), _('Are you sure you want to overwrite it ?')), defaultbutton=QMessageBox.No) if not res: return if self.isCaseFoldingOnWin() and self.copy_chk.isChecked(): qtlib.ErrorMsgBox(self.errTitle, _('Cannot do a pure casefolding copy on Windows')) return cmdline = self.compose_command(src, dest) self.show_command(cmdline) self.cmd.run(cmdline)
def refresh(self): try: l = open(self.ignorefile, 'rb').readlines() self.doseoln = l[0].endswith('\r\n') except (IOError, ValueError, IndexError): self.doseoln = os.name == 'nt' l = [] self.ignorelines = [line.strip() for line in l] self.ignorelist.clear() uni = hglib.tounicode self.ignorelist.addItems([uni(l) for l in self.ignorelines]) try: self.repo.thginvalidate() self.repo.lfstatus = True wctx = self.repo[None] wctx.status(unknown=True) self.repo.lfstatus = False except (EnvironmentError, error.RepoError), e: qtlib.WarningMsgBox(_('Unable to read repository status'), uni(str(e)), parent=self)
def okClicked(self): errormsg = self.validateForm() if errormsg: qtlib.WarningMsgBox(_('Missing information'), errormsg) return return self.accept()
class RepoItem(RepoTreeItem): xmltagname = 'repo' def __init__(self, root, shortname=None, basenode=None, parent=None): RepoTreeItem.__init__(self, parent) self._root = root self._shortname = shortname or u'' self._basenode = basenode or node.nullid self._valid = True # expensive check is done at appendSubrepos() def isRepo(self): return True def rootpath(self): return self._root def shortname(self): if self._shortname: return self._shortname else: return hglib.tounicode(os.path.basename(self._root)) def repotype(self): return 'hg' def basenode(self): """Return node id of revision 0""" return self._basenode def setBaseNode(self, basenode): self._basenode = basenode def setShortName(self, uname): uname = unicode(uname) if uname != self._shortname: self._shortname = uname def data(self, column, role): if role == Qt.DecorationRole and column == 0: baseiconname = 'hg' if paths.is_unc_path(self.rootpath()): baseiconname = 'thg-remote-repo' ico = qtlib.geticon(baseiconname) if not self._valid: ico = qtlib.getoverlaidicon(ico, qtlib.geticon('dialog-warning')) return ico elif role in (Qt.DisplayRole, Qt.EditRole): return [self.shortname, self.shortpath][column]() def getCommonPath(self): return self.parent().getCommonPath() def shortpath(self): try: cpath = self.getCommonPath() except: cpath = '' spath2 = spath = os.path.normpath(self._root) if os.name == 'nt': spath2 = spath2.lower() if cpath and spath2.startswith(cpath): iShortPathStart = len(cpath) spath = spath[iShortPathStart:] if spath and spath[0] in '/\\': # do not show a slash at the beginning of the short path spath = spath[1:] return hglib.tounicode(spath) def menulist(self): acts = [ 'open', 'clone', 'addsubrepo', None, 'explore', 'terminal', 'copypath', None, 'rename', 'remove' ] if self.childCount() > 0: acts.extend([None, (_('&Sort'), ['sortbyname', 'sortbyhgsub'])]) acts.extend([None, 'settings']) return acts def flags(self): return (Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEditable) def dump(self, xw): xw.writeAttribute('root', hglib.tounicode(self._root)) xw.writeAttribute('shortname', self.shortname()) xw.writeAttribute('basenode', node.hex(self.basenode())) _dumpChild(xw, parent=self) @classmethod def undump(cls, xr): a = xr.attributes() obj = cls(hglib.fromunicode(a.value('', 'root').toString()), unicode(a.value('', 'shortname').toString()), node.bin(str(a.value('', 'basenode').toString()))) _undumpChild(xr, parent=obj, undump=_undumpSubrepoItem) return obj def details(self): return _('Local Repository %s') % hglib.tounicode(self._root) def appendSubrepos(self, repo=None): invalidRepoList = [] try: sri = None if repo is None: if not os.path.exists(self._root): self._valid = False return [self._root] elif not os.path.exists(os.path.join(self._root, '.hgsub')): return [] # skip repo creation, which is expensive repo = hg.repository(ui.ui(), self._root) wctx = repo['.'] sortkey = lambda x: os.path.basename(util.normpath(repo.wjoin(x))) for subpath in sorted(wctx.substate, key=sortkey): sri = None abssubpath = repo.wjoin(subpath) subtype = wctx.substate[subpath][2] sriIsValid = os.path.isdir(abssubpath) sri = _newSubrepoItem(abssubpath, repotype=subtype) sri._valid = sriIsValid self.appendChild(sri) if not sriIsValid: self._valid = False sri._valid = False invalidRepoList.append(repo.wjoin(subpath)) return invalidRepoList if subtype == 'hg': # Only recurse into mercurial subrepos sctx = wctx.sub(subpath) invalidSubrepoList = sri.appendSubrepos(sctx._repo) if invalidSubrepoList: self._valid = False invalidRepoList += invalidSubrepoList except (EnvironmentError, error.RepoError, util.Abort), e: # Add the repo to the list of repos/subrepos # that could not be open self._valid = False if sri: sri._valid = False invalidRepoList.append(abssubpath) invalidRepoList.append(self._root) except Exception, e: # If any other sort of exception happens, show the corresponding # error message, but do not crash! # Note that we _also_ will mark the offending repos as invalid # It is unfortunate that Python 2.4, which we target does not # support combined try/except/finally clauses, forcing us # to duplicate some code here self._valid = False if sri: sri._valid = False invalidRepoList.append(abssubpath) invalidRepoList.append(self._root) # Show a warning message indicating that there was an error if repo: rootpath = repo.root else: rootpath = self._root warningMessage = (_('An exception happened while loading the ' \ 'subrepos of:<br><br>"%s"<br><br>') + \ _('The exception error message was:<br><br>%s<br><br>') +\ _('Click OK to continue or Abort to exit.')) \ % (hglib.tounicode(rootpath), hglib.tounicode(e.message)) res = qtlib.WarningMsgBox(_('Error loading subrepos'), warningMessage, buttons=QMessageBox.Ok | QMessageBox.Abort) # Let the user abort so that he gets the full exception info if res == QMessageBox.Abort: raise
match.match(self.repo.root, '', [], [test]) self.insertFilters([newfilter], False) except util.Abort, inst: qtlib.WarningMsgBox(_('Invalid glob expression'), str(inst), parent=self) return else: test = 'relre:' + newfilter try: match.match(self.repo.root, '', [], [test]) re.compile(test) self.insertFilters([newfilter], True) except (util.Abort, re.error), inst: qtlib.WarningMsgBox(_('Invalid regexp expression'), str(inst), parent=self) return def refresh(self): try: l = open(self.ignorefile, 'rb').readlines() self.doseoln = l[0].endswith('\r\n') except (IOError, ValueError, IndexError): self.doseoln = os.name == 'nt' l = [] self.ignorelines = [line.strip() for line in l] self.ignorelist.clear() uni = hglib.tounicode
def addSubrepo(self): 'menu action handler for adding a new subrepository' root = hglib.tounicode(self.selitem.internalPointer().rootpath()) caption = _('Select an existing repository to add as a subrepo') FD = QFileDialog path = unicode( FD.getExistingDirectory(caption=caption, directory=root, options=FD.ShowDirsOnly | FD.ReadOnly)) if path: path = os.path.normpath(path) sroot = paths.find_root(path) root = os.path.normcase(os.path.normpath(root)) if not sroot: qtlib.WarningMsgBox(_('Cannot add subrepository'), _('%s is not a valid repository') % path, parent=self) return elif not os.path.isdir(sroot): qtlib.WarningMsgBox(_('Cannot add subrepository'), _('"%s" is not a folder') % sroot, parent=self) return elif os.path.normcase(sroot) == root: qtlib.WarningMsgBox( _('Cannot add subrepository'), _('A repository cannot be added as a subrepo of itself'), parent=self) return elif root != paths.find_root( os.path.dirname(os.path.normcase(path))): qtlib.WarningMsgBox( _('Cannot add subrepository'), _('The selected folder:<br><br>%s<br><br>' 'is not inside the target repository.<br><br>' 'This may be allowed but is greatly discouraged.<br>' 'If you want to add a non trivial subrepository mapping ' 'you must manually edit the <i>.hgsub</i> file') % root, parent=self) return else: # The selected path is the root of a repository that is inside # the selected repository # Use forward slashes for relative subrepo root paths srelroot = sroot[len(root) + 1:] srelroot = util.pconvert(srelroot) # Is is already on the selected repository substate list? try: repo = hg.repository(ui.ui(), hglib.fromunicode(root)) except: qtlib.WarningMsgBox( _('Cannot open repository'), _('The selected repository:<br><br>%s<br><br>' 'cannot be open!') % root, parent=self) return if hglib.fromunicode(srelroot) in repo['.'].substate: qtlib.WarningMsgBox( _('Subrepository already exists'), _('The selected repository:<br><br>%s<br><br>' 'is already a subrepository of:<br><br>%s<br><br>' 'as: "%s"') % (sroot, root, srelroot), parent=self) return else: # Already a subrepo! # Read the current .hgsub file contents lines = [] hasHgsub = os.path.exists(repo.wjoin('.hgsub')) if hasHgsub: try: fsub = repo.wopener('.hgsub', 'r') lines = fsub.readlines() fsub.close() except: qtlib.WarningMsgBox( _('Failed to add subrepository'), _('Cannot open the .hgsub file in:<br><br>%s') \ % root, parent=self) return # Make sure that the selected subrepo (or one of its # subrepos!) is not already on the .hgsub file linesep = '' for line in lines: line = hglib.tounicode(line) spath = line.split("=")[0].strip() if not spath: continue if not linesep: linesep = hglib.getLineSeparator(line) spath = util.pconvert(spath) if line.startswith(srelroot): qtlib.WarningMsgBox( _('Failed to add repository'), _('The .hgsub file already contains the ' 'line:<br><br>%s') % line, parent=self) return if not linesep: linesep = os.linesep # Append the new subrepo to the end of the .hgsub file lines.append( hglib.fromunicode('%s = %s' % (srelroot, srelroot))) lines = [line.strip(linesep) for line in lines] # and update the .hgsub file try: fsub = repo.wopener('.hgsub', 'w') fsub.write(linesep.join(lines) + linesep) fsub.close() if not hasHgsub: commands.add(ui.ui(), repo, repo.wjoin('.hgsub')) qtlib.InfoMsgBox( _('Subrepo added to .hgsub file'), _('The selected subrepo:<br><br><i>%s</i><br><br>' 'has been added to the .hgsub file of the repository:<br><br><i>%s</i><br><br>' 'Remember that in order to finish adding the ' 'subrepo <i>you must still <u>commit</u></i> the ' 'changes to the .hgsub file in order to confirm ' 'the addition of the subrepo.') \ % (srelroot, root), parent=self) except: qtlib.WarningMsgBox( _('Failed to add repository'), _('Cannot update the .hgsub file in:<br><br>%s') \ % root, parent=self) return
and os.path.exists(os.path.sep.join([dest, '.hg']))): hgignore = os.path.join(dest, '.hgignore') if not os.path.exists(hgignore): try: open(hgignore, 'wb') except: pass if self.run_wb_chk.isChecked(): from tortoisehg.hgqt import run try: run.log(ui.ui(), root=dest) except Exception, e: qtlib.WarningMsgBox( _('Init'), _('<p>Repository successfully created at</p><p>%s</p>') % dest, _('<p>But could not run Workbench for it.</p><p>%s</p>') % hglib.tounicode(str(e))) else: if not self.parent(): qtlib.InfoMsgBox( _('Init'), _('<p>Repository successfully created at</p><p>%s</p>') % udest) self.accept() def reject(self): super(InitDialog, self).reject()
def appendSubrepos(self, repo=None): invalidRepoList = [] # Mercurial repos are the only ones that can have subrepos if self.repotype() == 'hg': try: sri = None if repo is None: if not os.path.exists(self._root): self._valid = False return [self._root] elif not os.path.exists(os.path.join(self._root, '.hgsub')): return [] # skip repo creation, which is expensive repo = hg.repository(ui.ui(), self._root) wctx = repo['.'] sortkey = lambda x: os.path.basename(util.normpath(repo.wjoin(x))) for subpath in sorted(wctx.substate, key=sortkey): sri = None abssubpath = repo.wjoin(subpath) subtype = wctx.substate[subpath][2] sriIsValid = os.path.isdir(abssubpath) sri = SubrepoItem(abssubpath, subtype=subtype) sri._valid = sriIsValid self.appendChild(sri) if not sriIsValid: self._valid = False sri._valid = False invalidRepoList.append(repo.wjoin(subpath)) return invalidRepoList continue if subtype == 'hg': # Only recurse into mercurial subrepos sctx = wctx.sub(subpath) invalidSubrepoList = sri.appendSubrepos(sctx._repo) if invalidSubrepoList: self._valid = False invalidRepoList += invalidSubrepoList except (EnvironmentError, error.RepoError, util.Abort), e: # Add the repo to the list of repos/subrepos # that could not be open self._valid = False if sri: sri._valid = False invalidRepoList.append(abssubpath) invalidRepoList.append(self._root) except Exception, e: # If any other sort of exception happens, show the corresponding # error message, but do not crash! # Note that we _also_ will mark the offending repos as invalid # It is unfortunate that Python 2.4, which we target does not # support combined try/except/finally clauses, forcing us # to duplicate some code here self._valid = False if sri: sri._valid = False invalidRepoList.append(abssubpath) invalidRepoList.append(self._root) # Show a warning message indicating that there was an error if repo: rootpath = repo.root else: rootpath = self._root warningMessage = (_('An exception happened while loading the ' \ 'subrepos of:<br><br>"%s"<br><br>') + \ _('The exception error message was:<br><br>%s<br><br>') +\ _('Click OK to continue or Abort to exit.')) \ % (rootpath, e.message) res = qtlib.WarningMsgBox(_('Error loading subrepos'), warningMessage, buttons = QMessageBox.Ok | QMessageBox.Abort) # Let the user abort so that he gets the full exception info if res == QMessageBox.Abort: raise