Beispiel #1
0
 def newShelf(self, interactive):
     shelve = time.strftime('%Y-%m-%d_%H-%M-%S') + \
              '_parent_rev_%d' % self.repo['.'].rev()
     if interactive:
         name, ok = qtlib.getTextInput(self,
                                       _('TortoiseHg New Shelf Name'),
                                       _('Specify name of new shelf'),
                                       text=shelve)
         if not ok:
             return
         shelve = hglib.fromunicode(name)
         invalids = (':', '#', '/', '\\', '<', '>', '|')
         bads = [c for c in shelve if c in invalids]
         if bads:
             qtlib.ErrorMsgBox(_('Bad filename'),
                               _('A shelf name cannot contain :#/\\<>|'))
             return
     try:
         fn = os.path.join('shelves', shelve)
         shelfpath = self.repo.join(fn)
         if os.path.exists(shelfpath):
             qtlib.ErrorMsgBox(
                 _('File already exists'),
                 _('A shelf file of that name already exists'))
             return
         self.repo.makeshelf(shelve)
         self.showMessage(_('New shelf created'))
         self.refreshCombos()
         if shelfpath in self.shelves:
             self.combob.setCurrentIndex(self.shelves.index(shelfpath))
     except EnvironmentError, e:
         self.showMessage(hglib.tounicode(str(e)))
Beispiel #2
0
def checkPatchname(reporoot, activequeue, newpatchname, parent):
    if activequeue == 'patches':
        pn = 'patches'
    else:
        pn = 'patches-%s' % activequeue
    patchfile = os.sep.join([reporoot, ".hg", pn, newpatchname])
    if os.path.exists(patchfile):
        dlg = CheckPatchnameDialog(newpatchname, parent)
        choice = dlg.exec_()
        if choice == 1:
            # add .OLD to existing patchfile
            try:
                os.rename(patchfile, patchfile + '.OLD')
            except (OSError, IOError), inst:
                qtlib.ErrorMsgBox(_('Rename Error'),
                                  _('Could not rename existing patchfile'),
                                  hglib.tounicode(str(inst)))
                return False
            return True
        elif choice == 2:
            # overwite existing patchfile
            try:
                os.remove(patchfile)
            except (OSError, IOError), inst:
                qtlib.ErrorMsgBox(_('Rename Error'),
                                  _('Could not delete existing patchfile'),
                                  hglib.tounicode(str(inst)))
                return False
            return True
Beispiel #3
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
Beispiel #4
0
    def init(self):
        dest = self.getPath()

        if dest == '':
            qtlib.ErrorMsgBox(_('Error executing init'),
                              _('Destination path is empty'),
                              _('Please enter the directory path'))
            self.dest_edit.setFocus()
            return False

        dest = os.path.normpath(dest)
        self.dest_edit.setText(hglib.tounicode(dest))
        udest = self.dest_edit.text()

        if not os.path.exists(dest):
            p = dest
            l = 0
            while not os.path.exists(p):
                l += 1
                p, t = os.path.split(p)
                if not t:
                    break  # already root path
            if l > 1:
                res = qtlib.QuestionMsgBox(
                    _('Init'),
                    _('Are you sure about adding the new repository '
                      '%d extra levels deep?') % l,
                    _('Path exists up to:\n%s\nand you asked for:\n%s') %
                    (p, udest),
                    defaultbutton=QMessageBox.No)
                if not res:
                    self.dest_edit.setFocus()
                    return
            try:
                # create the folder, just like Hg would
                os.makedirs(dest)
            except:
                qtlib.ErrorMsgBox(_('Error executing init'),
                                  _('Cannot create folder %s') % udest)
                return False

        _ui = ui.ui()

        # dotencode is the new default repo format in Mercurial 1.7
        if self.make_pre_1_7_chk.isChecked():
            _ui.setconfig('format', 'dotencode', 'False')

        try:
            # create the new repo
            hg.repository(_ui, dest, create=1)
        except error.RepoError, inst:
            qtlib.ErrorMsgBox(_('Error executing init'),
                              _('Unable to create new repository'),
                              hglib.tounicode(str(inst)))
            return False
Beispiel #5
0
def mqNewRefreshCommand(repo, isnew, stwidget, pnwidget, message, opts, olist):
    if isnew:
        name = hglib.fromunicode(pnwidget.text())
        if not name:
            qtlib.ErrorMsgBox(_('Patch Name Required'),
                              _('You must enter a patch name'))
            pnwidget.setFocus()
            return
        cmdline = ['qnew', '--repository', repo.root, name]
    else:
        cmdline = ['qrefresh', '--repository', repo.root]
    if message:
        cmdline += ['--message=' + hglib.fromunicode(message)]
    cmdline += getUserOptions(opts, *olist)
    files = ['--'] + [repo.wjoin(x) for x in stwidget.getChecked()]
    addrem = [repo.wjoin(x) for x in stwidget.getChecked('!?')]
    if len(files) > 1:
        cmdline += files
    else:
        cmdline += ['--exclude', repo.root]
    if addrem:
        cmdlines = [['addremove', '-R', repo.root] + addrem, cmdline]
    else:
        cmdlines = [cmdline]
    return cmdlines
Beispiel #6
0
 def init_data(self, ui, pats):
     """calculate initial values for widgets"""
     fname = ''
     target = ''
     cwd = os.getcwd()
     try:
         self.root = paths.find_root()
         self.repo = thgrepo.repository(ui, path=self.root)
     except (error.RepoError):
         qtlib.ErrorMsgBox(_('Error'),
                 _('Could not find or initialize the repository '
                   'from folder<p>%s</p>' % cwd))
         return ('', '')
     try:
         fname = scmutil.canonpath(self.root, cwd, pats[0])
         target = scmutil.canonpath(self.root, cwd, pats[1])
     except:
         pass
     os.chdir(self.root)
     fname = hglib.tounicode(util.normpath(fname))
     if target:
         target = hglib.tounicode(util.normpath(target))
     else:
         target = fname
     return (fname, target)
Beispiel #7
0
    def onCompletion(self):
        self.qui.progress_bar.hide()
        self.qui.progress_label.hide()

        output = self.cmd.core.rawoutput()

        saved = 'saved:' in output
        published = 'published:' in output
        if (saved or published):
            if saved:
                url = output.split('saved: ').pop().strip()
                msg = _('Review draft posted to %s\n') % url
            else:
                url = output.split('published: ').pop().strip()
                msg = _('Review published to %s\n') % url

            QDesktopServices.openUrl(QUrl(url))

            qtlib.InfoMsgBox(_('Review Board'), _('Success'), msg, parent=self)
        else:
            error = output.split('abort: ').pop().strip()
            if error[:29] == "HTTP Error: basic auth failed":
                if self.passwordPrompt():
                    self.accept()
                else:
                    self.qui.post_review_button.setEnabled(True)
                    self.qui.close_button.setEnabled(True)
                    return
            else:
                qtlib.ErrorMsgBox(_('Review Board'), _('Error'), error)

        self.writeSettings()
        super(PostReviewDialog, self).accept()
Beispiel #8
0
def run(ui, *pats, **opts):
    repo = thgrepo.repository(None, paths.find_root())
    if hasattr(repo, 'mq'):
        return QReorderDialog(repo)
    else:
        qtlib.ErrorMsgBox(_('TortoiseHg Error'),
                          _('Please enable the MQ extension first.'))
Beispiel #9
0
    def get_commit_message(self, parameters, logmessage):
        commonurl = ""
        commonroot = ""
        bugid = ""
        bstrarray = _midlSAFEARRAY(comtypes.BSTR)
        pathlist = bstrarray.from_param(())

        bugtr = self._get_bugtraq_object()
        if bugtr is None:
            return ""
        try:
            if self.supports_bugtraq2_interface():
                (bugid, revPropNames, revPropValues,
                 newmessage) = bugtr.GetCommitMessage2(0, parameters,
                                                       commonurl, commonroot,
                                                       pathlist, logmessage,
                                                       bugid)
            else:
                newmessage = bugtr.GetCommitMessage(0, parameters, commonroot,
                                                    pathlist, logmessage)
        except COMError:
            qtlib.ErrorMsgBox(
                _('Issue Tracker Plugin Error'),
                _('Error getting commit message information from Issue Tracker plugin'
                  ))
            return ""

        return newmessage
Beispiel #10
0
 def edit_pgraph_clicked(self):
     opts = {} # TODO: How to find user ID
     mgr = self.pbranch.patchmanager(self.repo.ui, self.repo, opts)
     if not mgr.hasgraphdesc():
         self.pbranch.writefile(mgr.graphdescpath(), '')
     oldtext = mgr.graphdesc()
     # run editor in the repository root
     olddir = os.getcwd()
     os.chdir(self.repo.root)
     try:
         newtext = None
         newtext = self.repo.ui.edit(oldtext, opts.get('user'))
     except error.Abort:
         no_editor_configured =(os.environ.get("HPLUMAOR") or
             self.repo.ui.config("ui", "editor") or
             os.environ.get("VISUAL") or
             os.environ.get("EDITOR","editor-not-configured")
             == "editor-not-configured")
         if no_editor_configured:
             qtlib.ErrorMsgBox(_('No editor found'),
                 _('Mercurial was unable to find an editor. Please configure Mercurial to use an editor installed on your system.'))
         else:
             raise
     os.chdir(olddir)
     if newtext is not None:
         mgr.updategraphdesc(newtext)
         self.refresh()
Beispiel #11
0
    def accept(self):
        # If the editor has been modified, we implicitly accept the changes
        acceptresolution = self.editor.isModified()
        if not acceptresolution:
            action = QMessageBox.warning(self,
                _("Warning"),
                _("You have marked all rejected patch chunks as resolved yet you " \
                "have not modified the file on the edit panel.\n\n" \
                "This probably means that no code from any of the rejected patch " \
                "chunks made it into the file.\n\n"\
                "Are you sure that you want to leave the file as is and " \
                "consider all the rejected patch chunks as resolved?\n\n" \
                "Doing so may delete them from a shelve, for example, which " \
                "would mean that you would lose them forever!\n\n"
                "Click Yes to accept the file as is or No to continue resolving " \
                "the rejected patch chunks."),
                QMessageBox.Yes, QMessageBox.No)
            if action == QMessageBox.Yes:
                acceptresolution = True

        if acceptresolution:
            f = QFile(hglib.tounicode(self.path))
            saved = f.open(QIODevice.WriteOnly) and self.editor.write(f)
            if not saved:
                qtlib.ErrorMsgBox(_('Unable to save file'),
                                  f.errorString(), parent=self)
                return
            self.saveSettings()
            super(RejectsDialog, self).accept()
Beispiel #12
0
def run(ui, *pats, **opts):
    repo = opts.get('repo') or thgrepo.repository(ui, paths.find_root())
    try:
        # ManifestWidget expects integer revision
        rev = repo[opts.get('rev')].rev()
    except error.RepoLookupError, e:
        qtlib.ErrorMsgBox(_('Failed to open Manifest dialog'),
                          hglib.tounicode(e.message))
        return
Beispiel #13
0
def run(ui, *pats, **opts):
    if len(pats) != 1:
        qtlib.ErrorMsgBox(_('Filename required'),
                          _('You must provide the path to a file'))
        import sys; sys.exit()
    path = pats[0]
    if path.endswith('.rej'):
        path = path[:-4]
    dlg = RejectsDialog(path, None)
    return dlg
Beispiel #14
0
    def errorPrompt(self):
        self.qui.progress_bar.hide()
        self.qui.progress_label.hide()

        if self.error_message:
            qtlib.ErrorMsgBox(_('Review Board'), _('Error'),
                              self.error_message)
            self.close()
        elif self.isValid():
            self.qui.post_review_button.setEnabled(True)
Beispiel #15
0
def run(ui, *pats, **opts):
    revs = opts.get('rev') or None
    if not revs and len(pats):
        revs = pats[0]
    repo = opts.get('repo') or thgrepo.repository(ui, path=paths.find_root())

    try:
        return PostReviewDialog(repo.ui, repo, revs)
    except error.RepoLookupError, e:
        qtlib.ErrorMsgBox(_('Failed to open Review Board dialog'),
                          hglib.tounicode(e.message))
Beispiel #16
0
def run(ui, *pats, **opts):
    from tortoisehg.util import paths
    repo = thgrepo.repository(ui, path=paths.find_root())
    if os.path.exists(repo.join('rebasestate')):
        qtlib.InfoMsgBox(_('Rebase already in progress'),
                          _('Resuming rebase already in progress'))
    elif not opts['source'] or not opts['dest']:
        qtlib.ErrorMsgBox(_('Abort'),
                          _('You must provide source and dest arguments'))
        import sys; sys.exit()
    return RebaseDialog(repo, None, **opts)
Beispiel #17
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)
Beispiel #18
0
    def show_options_dialog(self, options):
        if not self.has_options():
            return ""

        bugtr = self._get_bugtraq_object()
        if bugtr is None:
            return ""
        try:
            options = bugtr.ShowOptionsDialog(0, options)
        except COMError:
            qtlib.ErrorMsgBox(_('Issue Tracker Plugin Error'),
                              _('Cannot open Plugin Options dialog'))
            return ""
        return options
Beispiel #19
0
def run(ui, *revs, **opts):
    from tortoisehg.util import paths
    repo = thgrepo.repository(ui, path=paths.find_root())

    revs = list(revs)
    revs.extend(opts['rev'])

    if os.path.exists(repo.join('graftstate')):
        qtlib.InfoMsgBox(_('Graft already in progress'),
                          _('Resuming graft already in progress'))
    elif not revs:
        qtlib.ErrorMsgBox(_('Abort'),
                          _('You must provide revisions to graft'))
        import sys; sys.exit()
    return GraftDialog(repo, None, source=revs)
Beispiel #20
0
 def _get_bugtraq_object(self):
     if self.bugtr == None:
         obj = CreateObject(self.guid)
         try:
             self.bugtr = obj.QueryInterface(IBugTraqProvider2)
         except COMError:
             if not self.errorshown:
                 self.errorshown = True
                 qtlib.ErrorMsgBox(
                     _('Issue Tracker Plugin Error'),
                     _('Could not instantiate Issue Tracker plugin COM object'
                       ),
                     _('This error will not be shown again until you restart the workbench'
                       ))
             return None
     return self.bugtr
Beispiel #21
0
def run(ui, *revs, **opts):
    # TODO: same options as patchbomb
    if opts.get('rev'):
        if revs:
            raise util.Abort(_('use only one form to specify the revision'))
        revs = opts.get('rev')

    # TODO: repo should be a required argument?
    repo = opts.get('repo') or thgrepo.repository(ui, paths.find_root())

    try:
        return EmailDialog(repo,
                           revs,
                           outgoing=opts.get('outgoing', False),
                           outgoingrevs=opts.get('outgoingrevs', None))
    except error.RepoLookupError, e:
        qtlib.ErrorMsgBox(_('Failed to open Email dialog'),
                          hglib.tounicode(e.message))
Beispiel #22
0
    def on_commit_finished(self, logmessage):
        if not self.supports_bugtraq2_interface():
            return ""

        commonroot = ""
        bstrarray = _midlSAFEARRAY(comtypes.BSTR)
        pathlist = bstrarray.from_param(())

        bugtr = self._get_bugtraq_object()
        if bugtr is None:
            return ""
        try:
            errormessage = bugtr.OnCommitFinished(0, commonroot, pathlist,
                                                  logmessage, 0)
        except COMError:
            qtlib.ErrorMsgBox(_('Issue Tracker Plugin Error'),
                              _('Error executing "commit finished" trigger'))
            return ""
        return errormessage
Beispiel #23
0
 def onBrowseQclone(self):
     FD = QFileDialog
     caption = _("Select patch folder")
     upath = FD.getExistingDirectory(self, caption, \
         self.qclone_txt.text(), QFileDialog.ShowDirsOnly)
     if upath:
         path = hglib.fromunicode(upath).replace('/', os.sep)
         src = hglib.fromunicode(self.src_combo.currentText())
         if not path.startswith(src):
             qtlib.ErrorMsgBox(
                 'TortoiseHg QClone',
                 _('The selected patch folder is not'
                   ' under the source repository.'),
                 '<p>src = %s</p><p>path = %s</p>' % (src, path))
             return
         path = path.replace(src + os.sep, '')
         self.qclone_txt.setText(
             QDir.toNativeSeparators(hglib.tounicode(path)))
         self.qclone_txt.setFocus()
     self.composeCommand()
Beispiel #24
0
    def __init__(self, path, parent):
        super(RejectsDialog, self).__init__(parent)
        self.setWindowTitle(_('Merge rejected patch chunks into %s') %
                            hglib.tounicode(path))
        self.setWindowFlags(Qt.Window)
        self.path = path

        self.setLayout(QVBoxLayout())
        editor = qscilib.Scintilla()
        editor.setBraceMatching(qsci.SloppyBraceMatch)
        editor.setFolding(qsci.BoxedTreeFoldStyle)
        editor.installEventFilter(qscilib.KeyPressInterceptor(self))
        editor.setContextMenuPolicy(Qt.CustomContextMenu)
        editor.customContextMenuRequested.connect(self.menuRequested)
        self.baseLineColor = editor.markerDefine(qsci.Background, -1)
        editor.setMarkerBackgroundColor(QColor('lightblue'), self.baseLineColor)
        self.layout().addWidget(editor, 3)

        searchbar = qscilib.SearchToolBar(self, 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, self, showsearchbar)
        self.layout().addWidget(searchbar)

        hbox = QHBoxLayout()
        hbox.setContentsMargins(2, 2, 2, 2)
        self.layout().addLayout(hbox, 1)
        self.chunklist = QListWidget(self)
        self.updating = True
        self.chunklist.currentRowChanged.connect(self.showChunk)
        hbox.addWidget(self.chunklist, 1)

        bvbox = QVBoxLayout()
        bvbox.setContentsMargins(2, 2, 2, 2)
        self.resolved = tb = QToolButton()
        tb.setIcon(qtlib.geticon('thg-success'))
        tb.setToolTip(_('Mark this chunk as resolved, goto next unresolved'))
        tb.pressed.connect(self.resolveCurrentChunk)
        self.unresolved = tb = QToolButton()
        tb.setIcon(qtlib.geticon('thg-warning'))
        tb.setToolTip(_('Mark this chunk as unresolved'))
        tb.pressed.connect(self.unresolveCurrentChunk)
        bvbox.addStretch(1)
        bvbox.addWidget(self.resolved, 0)
        bvbox.addWidget(self.unresolved, 0)
        bvbox.addStretch(1)
        hbox.addLayout(bvbox, 0)

        self.editor = editor
        self.rejectbrowser = RejectBrowser(self)
        hbox.addWidget(self.rejectbrowser, 5)

        BB = QDialogButtonBox
        bb = QDialogButtonBox(BB.Save|BB.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        self.layout().addWidget(bb)
        self.saveButton = bb.button(BB.Save)

        s = QSettings()
        self.restoreGeometry(s.value('rejects/geometry').toByteArray())
        self.editor.loadSettings(s, 'rejects/editor')
        self.rejectbrowser.loadSettings(s, 'rejects/rejbrowse')

        f = QFile(hglib.tounicode(path))
        if not f.open(QIODevice.ReadOnly):
            qtlib.ErrorMsgBox(_('Unable to merge rejects'),
                              _("Can't read this file (maybe deleted)"))
            self.hide()
            QTimer.singleShot(0, self.reject)
            return
        earlybytes = f.read(4096)
        if '\0' in earlybytes:
            qtlib.ErrorMsgBox(_('Unable to merge rejects'),
                              _('This appears to be a binary file'))
            self.hide()
            QTimer.singleShot(0, self.reject)
            return

        f.seek(0)
        editor.read(f)
        editor.setModified(False)
        lexer = lexers.getlexer(ui.ui(), path, earlybytes, self)
        editor.setLexer(lexer)
        editor.setMarginLineNumbers(1, True)
        editor.setMarginWidth(1, str(editor.lines())+'X')

        buf = cStringIO.StringIO()
        try:
            buf.write('diff -r aaaaaaaaaaaa -r bbbbbbbbbbb %s\n' % path)
            buf.write(open(path + '.rej', 'rb').read())
            buf.seek(0)
        except IOError, e:
            pass
Beispiel #25
0
                    _('Unable to create new repository'),
                    hglib.tounicode(str(inst)))
            return False
        except util.Abort, e:
            if e.hint:
                err = _('%s (hint: %s)') % (hglib.tounicode(str(e)),
                                            hglib.tounicode(e.hint))
            else:
                err = hglib.tounicode(str(e))
            qtlib.ErrorMsgBox(_('Error executing init'),
                    _('Error when creating repository'), err)
            return False
        except:
            import traceback
            qtlib.ErrorMsgBox(_('Error executing init'),
                    _('Error when creating repository'),
                    traceback.format_exc())
            return False

        # Create the .hg* file, mainly to workaround
        # Explorer's problem in creating files with a name
        # beginning with a dot.
        if (self.add_files_chk.isChecked() 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
Beispiel #26
0
class InitDialog(QDialog):
    """TortoiseHg init dialog"""

    def __init__(self, destdir=[], opts={}, parent=None):
        super(InitDialog, self).__init__(parent)

        # main layout
        self.vbox = QVBoxLayout()
        self.vbox.setSpacing(6)
        self.grid = QGridLayout()
        self.grid.setSpacing(6)
        self.vbox.addLayout(self.grid)

        # dest widgets
        self.dest_lbl = QLabel(_('Destination path:'))
        self.dest_edit = QLineEdit()
        self.dest_edit.setMinimumWidth(300)
        self.dest_btn = QPushButton(_('Browse...'))
        self.dest_btn.setAutoDefault(False)
        self.grid.addWidget(self.dest_lbl, 0, 0)
        self.grid.addWidget(self.dest_edit, 0, 1)
        self.grid.addWidget(self.dest_btn, 0, 2)

        # options checkboxes
        self.add_files_chk = QCheckBox(
                _('Add special files (.hgignore, ...)'))
        self.make_pre_1_7_chk = QCheckBox(
                _('Make repo compatible with Mercurial <1.7'))
        self.run_wb_chk = QCheckBox(
                _('Show in Workbench after init'))
        self.grid.addWidget(self.add_files_chk, 1, 1)
        self.grid.addWidget(self.make_pre_1_7_chk, 2, 1)
        if not self.parent():
            self.grid.addWidget(self.run_wb_chk, 3, 1)

        # buttons
        self.init_btn = QPushButton(_('Create'))
        self.init_btn.setDefault(True)
        self.close_btn = QPushButton(_('&Close'))
        self.close_btn.setAutoDefault(False)
        self.hbox = QHBoxLayout()
        self.hbox.addStretch(0)
        self.hbox.addWidget(self.init_btn)
        self.hbox.addWidget(self.close_btn)
        self.vbox.addLayout(self.hbox)

        # some extras
        self.hgcmd_lbl = QLabel(_('Hg command:'))
        self.hgcmd_lbl.setAlignment(Qt.AlignRight)
        self.hgcmd_txt = QLineEdit()
        self.hgcmd_txt.setReadOnly(True)
        self.grid.addWidget(self.hgcmd_lbl, 4, 0)
        self.grid.addWidget(self.hgcmd_txt, 4, 1)

        # init defaults
        self.cwd = os.getcwd()
        path = os.path.abspath(destdir and destdir[0] or self.cwd)
        if os.path.isfile(path):
            path = os.path.dirname(path)
        self.dest_edit.setText(hglib.tounicode(path))
        self.add_files_chk.setChecked(True)
        self.make_pre_1_7_chk.setChecked(False)
        self.compose_command()

        # dialog settings
        self.setWindowTitle(_('New Repository'))
        self.setWindowIcon(qtlib.geticon('hg-init'))
        self.setWindowFlags(
                self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
        self.setLayout(self.vbox)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.dest_edit.setFocus()

        # connecting slots
        self.dest_edit.textChanged.connect(self.compose_command)
        self.dest_btn.clicked.connect(self.browse_clicked)
        self.init_btn.clicked.connect(self.init)
        self.close_btn.clicked.connect(self.close)
        self.make_pre_1_7_chk.toggled.connect(self.compose_command)

    def browse_clicked(self):
        """Select the destination directory"""
        dest = hglib.fromunicode(self.dest_edit.text())
        if not os.path.exists(dest):
            dest = os.path.dirname(dest)
        FD = QFileDialog
        caption = _('Select Destination Folder')
        path = FD.getExistingDirectory(parent=self, caption=caption,
                options=FD.ShowDirsOnly | FD.ReadOnly)
        if path:
            self.dest_edit.setText(path)

    def compose_command(self):
        # just a stub for extension with extra options (--mq, --ssh, ...)
        cmd = ['hg', 'init']
        if self.make_pre_1_7_chk.isChecked():
            cmd.append('--config format.dotencode=False')
        cmd.append(self.getPath())
        self.hgcmd_txt.setText(hglib.tounicode(' '.join(cmd)))

    def getPath(self):
        return hglib.fromunicode(self.dest_edit.text()).strip()

    def init(self):
        dest = self.getPath()

        if dest == '':
            qtlib.ErrorMsgBox(_('Error executing init'),
                    _('Destination path is empty'),
                    _('Please enter the directory path'))
            self.dest_edit.setFocus()
            return False

        dest = os.path.normpath(dest)
        self.dest_edit.setText(hglib.tounicode(dest))
        udest = self.dest_edit.text()

        if not os.path.exists(dest):
            p = dest
            l = 0
            while not os.path.exists(p):
                l += 1
                p, t = os.path.split(p)
                if not t:
                    break  # already root path
            if l > 1:
                res = qtlib.QuestionMsgBox(_('Init'),
                        _('Are you sure about adding the new repository '
                          '%d extra levels deep?') % l,
                        _('Path exists up to:\n%s\nand you asked for:\n%s')
                            % (p, udest),
                        defaultbutton=QMessageBox.No)
                if not res:
                    self.dest_edit.setFocus()
                    return
            try:
                # create the folder, just like Hg would
                os.makedirs(dest)
            except:
                qtlib.ErrorMsgBox(_('Error executing init'),
                        _('Cannot create folder %s') % udest)
                return False

        _ui = ui.ui()

        # dotencode is the new default repo format in Mercurial 1.7
        if self.make_pre_1_7_chk.isChecked():
            _ui.setconfig('format', 'dotencode', 'False')

        try:
            # create the new repo
            hg.repository(_ui, dest, create=1)
        except error.RepoError, inst:
            qtlib.ErrorMsgBox(_('Error executing init'),
                    _('Unable to create new repository'),
                    hglib.tounicode(str(inst)))
            return False
        except util.Abort, e:
            if e.hint:
                err = _('%s (hint: %s)') % (hglib.tounicode(str(e)),
                                            hglib.tounicode(e.hint))
            else:
                err = hglib.tounicode(str(e))
            qtlib.ErrorMsgBox(_('Error executing init'),
                    _('Error when creating repository'), err)
            return False
Beispiel #27
0
 def reloadFailed(self, msg):
     qtlib.ErrorMsgBox(_('Failed to refresh'), msg, parent=self)
Beispiel #28
0
    def clone(self):
        if self.cmd.core.running():
            return
        # prepare user input
        srcQ = self.src_combo.currentText().trimmed()
        src = hglib.fromunicode(srcQ)
        destQ = self.dest_combo.currentText().trimmed()
        dest = hglib.fromunicode(destQ)
        if not dest:
            dest = os.path.basename(src)
            destQ = QString(hglib.tounicode(dest))

        if not dest.startswith('ssh://'):
            if not os.path.exists(dest):
                try:
                    os.mkdir(dest)
                except EnvironmentError:
                    qtlib.ErrorMsgBox(_('TortoiseHg Clone'),
                                      _('Error creating destination folder'),
                                      _('Please specify a different path.'))
                    return False
                self.prev_dest = None

        if srcQ:
            l = list(self.shist)
            if srcQ in l:
                l.remove(srcQ)
            l.insert(0, srcQ)
            self.shist = l[:10]
        if destQ:
            l = list(self.dhist)
            if destQ in l:
                l.remove(destQ)
            l.insert(0, destQ)
            self.dhist = l[:10]
        s = QSettings()
        s.setValue('clone/source', self.shist)
        s.setValue('clone/dest', self.dhist)

        # verify input
        if src == '':
            qtlib.ErrorMsgBox(_('TortoiseHg Clone'), _('Source path is empty'),
                              _('Please enter a valid source path.'))
            self.src_combo.setFocus()
            return False

        if src == dest:
            qtlib.ErrorMsgBox(_('TortoiseHg Clone'),
                              _('Source and destination are the same'),
                              _('Please specify different paths.'))
            return False

        if dest == os.getcwd():
            if os.listdir(dest):
                # cur dir has files, specify no dest, let hg take
                # basename
                dest = ''
            else:
                dest = '.'
        else:
            abs = os.path.abspath(dest)
            dirabs = os.path.dirname(abs)
            if dirabs == src:
                dest = os.path.join(os.path.dirname(dirabs), dest)

        # prepare command line
        self.src_combo.setEditText(hglib.tounicode(src))
        self.dest_combo.setEditText(hglib.tounicode(dest))
        cmdline = self.composeCommand()

        # do not make the same clone twice (see #514)
        if dest == self.prev_dest and os.path.exists(dest) and self.ret == 0:
            qtlib.ErrorMsgBox(_('TortoiseHg Clone'),
                              _('Please enter a new destination path.'))
            self.dest_combo.setFocus()
            return
        self.prev_dest = dest

        # start cloning
        self.cmd.run(cmdline, useproc=src.startswith('p4://'))