Пример #1
0
    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)))
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
 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()
Пример #5
0
    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
Пример #6
0
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)
Пример #7
0
 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)
Пример #8
0
 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)
Пример #9
0
 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
Пример #10
0
    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)
Пример #11
0
    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)
Пример #12
0
 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)
Пример #13
0
 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
Пример #14
0
 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
Пример #15
0
 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)
Пример #16
0
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
Пример #17
0
    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 = []
Пример #18
0
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)
Пример #19
0
    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_()
Пример #20
0
    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)
Пример #21
0
    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)
Пример #22
0
 def okClicked(self):
     errormsg = self.validateForm()
     if errormsg:
         qtlib.WarningMsgBox(_('Missing information'), errormsg)
         return
     return self.accept()
Пример #23
0
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
Пример #24
0
                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
Пример #25
0
    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
Пример #26
0
                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()

Пример #27
0
    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