# HG changeset patch # User Chris Cannam # Date 1294777159 0 # Node ID 0689dada141995d1c56e6d0d7d782a9d566a9c3e # Parent 0fe81e1b26ceb103f02198fa819ed7d7bdf6cdb4# Parent be483734bde51575674f68b7cd802cb1e648c565 Merge diff -r 0fe81e1b26ce -r 0689dada1419 changesetitem.cpp --- a/changesetitem.cpp Tue Jan 11 20:18:37 2011 +0000 +++ b/changesetitem.cpp Tue Jan 11 20:19:19 2011 +0000 @@ -55,7 +55,7 @@ { int w = 100; if (m_wide) w = 180; - return QRectF(-((w-50)/2 - 1), -30, w - 3, 79); + return QRectF(-((w-50)/2 - 1), -30, w - 3, 90); } void @@ -211,7 +211,10 @@ f.setPixelSize(ps); } - if (scale < 0.1) { + bool showText = (scale >= 0.2); + bool showProperLines = (scale >= 0.1); + + if (!showProperLines) { paint->setPen(QPen(branchColour, 0)); } else { paint->setPen(QPen(branchColour, 2)); @@ -225,22 +228,54 @@ if (m_wide) width = 180; int x0 = -((width - 50) / 2 - 1); - int height = 49; + int textwid = width - 7; + + QString comment; + QStringList lines; + int lineCount = 3; + + if (showText) { + + comment = m_changeset->comment().trimmed(); + comment = comment.replace("\\n", " "); + comment = comment.replace(QRegExp("^\"\\s*\\**\\s*"), ""); + comment = comment.replace(QRegExp("\"$"), ""); + comment = comment.replace("\\\"", "\""); + + comment = TextAbbrev::abbreviate(comment, fm, textwid, + TextAbbrev::ElideEnd, "...", 3); + // abbreviate() changes this (ouch!), restore it + textwid = width - 5; + + lines = comment.split('\n'); + lineCount = lines.size(); + + if (lineCount < 2) lineCount = 2; + } + + int height = (lineCount + 1) * fh + 2; QRectF r(x0, 0, width - 3, height); + + if (showProperLines) { + + paint->setBrush(Qt::white); + + if (m_current) { + paint->drawRect(QRectF(x0 - 4, -4, width + 5, height + 8)); + } + + if (m_new) { + paint->save(); + paint->setPen(Qt::yellow); + paint->setBrush(Qt::NoBrush); + paint->drawRect(QRectF(x0 - 2, -2, width + 1, height + 4)); + paint->restore(); + } + } + paint->drawRect(r); - if (m_new) { - paint->save(); - paint->setPen(Qt::yellow); - paint->drawRect(QRectF(x0 - 2, -2, width + 1, height + 4)); - paint->restore(); - } - - if (m_current) { - paint->drawRect(QRectF(x0 - 4, -4, width + 5, height + 8)); - } - - if (scale < 0.2) { + if (!showText) { paint->restore(); return; } @@ -250,8 +285,8 @@ paint->setPen(QPen(Qt::white)); - int wid = width - 5; - QString person = TextAbbrev::abbreviate(m_changeset->authorName(), fm, wid); + QString person = TextAbbrev::abbreviate(m_changeset->authorName(), + fm, textwid); paint->drawText(x0 + 3, fm.ascent(), person); paint->setPen(QPen(Qt::black)); @@ -293,23 +328,8 @@ paint->restore(); } - fm = QFontMetrics(f); - fh = fm.height(); paint->setFont(f); - QString comment = m_changeset->comment().trimmed(); - comment = comment.replace("\\n", " "); - comment = comment.replace(QRegExp("^\"\\s*\\**\\s*"), ""); - comment = comment.replace(QRegExp("\"$"), ""); - comment = comment.replace("\\\"", "\""); - - wid = width - 5; - int nlines = (height / fh) - 1; - if (nlines < 1) nlines = 1; - comment = TextAbbrev::abbreviate(comment, fm, wid, TextAbbrev::ElideEnd, - "...", nlines); - - QStringList lines = comment.split('\n'); for (int i = 0; i < lines.size(); ++i) { paint->drawText(x0 + 3, i * fh + fh + fm.ascent(), lines[i].trimmed()); } diff -r 0fe81e1b26ce -r 0689dada1419 connectionitem.cpp --- a/connectionitem.cpp Tue Jan 11 20:18:37 2011 +0000 +++ b/connectionitem.cpp Tue Jan 11 20:19:19 2011 +0000 @@ -89,7 +89,12 @@ float c_x = xscale * c_col + size/2; float p_x = xscale * p_col + size/2; - p.moveTo(c_x, yscale * c_row + size); + // ensure line reaches the box, even if it's in a small height -- + // doesn't matter if we overshoot as the box is opaque and has a + // greater Z value + p.moveTo(c_x, yscale * c_row + size - 20); + + p.lineTo(c_x, yscale * c_row + size); if (p_col == c_col) { diff -r 0fe81e1b26ce -r 0689dada1419 easyhg_en.qm Binary file easyhg_en.qm has changed diff -r 0fe81e1b26ce -r 0689dada1419 easyhg_en.ts --- a/easyhg_en.ts Tue Jan 11 20:18:37 2011 +0000 +++ b/easyhg_en.ts Tue Jan 11 20:19:19 2011 +0000 @@ -154,37 +154,37 @@ HgRunner - + User name: - + User name for "%1": - + Enter user name - + Password: - + Password for "%1" at "%2": - + Password for user "%1": - + Enter password @@ -226,61 +226,61 @@ MainWindow - - + + EasyMercurial - + About EasyMercurial - + <qt><h2>About EasyMercurial</h2><p>EasyMercurial is a simple user interface for the Mercurial version control system.</p><p>EasyMercurial is based on hgExplorer by Jari Korhonen, with thanks.<br>EasyMercurial development carried out by Chris Cannam for soundsoftware.ac.uk at the Centre for Digital Music, Queen Mary, University of London.<ul><li>Copyright &copy; 2010 Jari Korhonen</li><li>Copyright &copy; 2010 Chris Cannam</li><li>Copyright &copy; 2010 Queen Mary, University of London</li></ul><p> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING included with this distribution for more information. - + Commit files - + Tag - + Enter tag: - + Revert files - - - - + + + + <h3>%1</h3><p>%2 - + You are about to commit the following files: - + You are about to <b>revert</b> the following files to their previous committed state.<br><br>This will <b>throw away any changes</b> that you have made to these files but have not committed: - + You are about to <b>revert</b> %n file(s).<br><br>This will <b>throw away any changes</b> that you have made to these files but have not committed. You are about to <b>revert</b> %n files.<br><br>This will <b>throw away any changes</b> that you have made to these files but have not committed. @@ -289,218 +289,200 @@ - + Merge from the default branch - + Merge from branch "%1" - + Merge from %1 - + Confirm pull - + Confirm pull from remote repository - + You are about to pull from the following remote repository: - + Confirm push - + Confirm push to remote repository - + You are about to push to the following remote repository: - - - Serve - - - - - Failed to identify an active IPv4 address - - - - Starting server at %n address(es): - - Starting server at this address: - Starting server at %n addresses: - - - - + Open Repository - + <qt><big>What would you like to open?</big></qt> - + <qt><center><img src=":images/browser-64.png"><br>Remote repository</center></qt> - + Open a remote Mercurial repository, by cloning from its URL into a local folder. - + <qt><center><img src=":images/hglogo-64.png"><br>Local repository</center></qt> - + Open an existing local Mercurial repository. - + <qt><center><img src=":images/hdd_unmount-64.png"><br>File folder</center></qt> - + Open a local folder, by creating a Mercurial repository in it. - + File chosen - + <qt><b>Folder required</b><br><br>You asked to open "%1".<br>This is a file; to open a repository, you need to choose a folder.</qt> - - + + Folder does not exist - + <qt><b>Folder does not exist</b><br><br>You asked to open "%1".<br>This folder does not exist, and it cannot be created because its parent does not exist either.</qt> - - + + Path is in existing repository - + <qt><b>Path is in an existing repository</b><br><br>You asked to initialise a repository at "%1".<br>This path is already inside an existing repository.</qt> - - + + Path is a file - + <qt><b>Path is a file</b><br><br>You asked to initialise a repository at "%1".<br>This is an existing file; it is only possible to initialise in folders.</qt> - + <qt><b>Local path is in an existing repository</b><br><br>You asked to open a remote repository by cloning it to the local path "%1".<br>This path is already inside an existing repository.<br>Please provide a new folder name for the local repository.</qt> - + <qt><b>Local path is a file</b><br><br>You asked to open a remote repository by cloning it to the local path "%1".<br>This path is an existing file.<br>Please provide a new folder name for the local repository.</qt> - + Folder exists - + <qt><b>Local folder already exists</b><br><br>You asked to open a remote repository by cloning it to the local path "%1".<br>This is the path of an existing folder.<br>Please provide a new folder name for the local repository.</qt> - + Path is inside a repository - + <qt><b>Open the repository that contains this path?</b><br><br>You asked to open "%1".<br>This is not the root folder of a repository.<br>But it is inside a repository, whose root is at "%2". <br><br>Would you like to open that repository instead?</qt> - + Folder has no repository - + <qt><b>Initialise a repository here?</b><br><br>You asked to open "%1".<br>This folder does not contain a Mercurial repository.<br><br>Would you like to initialise a repository here?</qt> - + <qt><b>Initialise a new repository?</b><br><br>You asked to open "%1".<br>This folder does not yet exist.<br><br>Would you like to create the folder and initialise a new empty repository in it?</qt> - + Repository exists - + <qt><b>Open existing repository?</b><br><br>You asked to initialise a new repository at "%1".<br>This folder already contains a repository. Would you like to open it?</qt> - + Ok - + Mercurial command did not return any output. - + Pushed %n changeset(s) Pushed %n changeset @@ -508,22 +490,22 @@ - + No changes to push - + Push complete - + The push command output was: - + Pulled %n changeset(s) Pulled %n changeset @@ -531,374 +513,383 @@ - + No changes to pull - + Pull complete - + The pull command output was: - - - - - Push failed - - - - - Your local repository could not be pushed to the remote repository.<br><br>You may need to merge the changes locally first.<br><br>The output of the push command was: - - - - - Your local repository could not be pushed to the remote repository.<br><br>The remote repository may have been changed by someone else since you last pushed. Try pulling and merging their changes into your local repository first.<br><br>The output of the push command was: - - - - - - Failed to run Mercurial - - - - - The Mercurial program either could not be found or failed to run.<br>This may indicate a problem with the Mercurial installation, or with the EasyHg interaction extension.<br><br>The test command said: - - - - + <qt><h3>Command failed</h3><p>The following command failed:</p><code>%1</code>%2</qt> - + <p>Its output said:</p><code>%1</code> - + Command failed - + Change summary - + Summary of uncommitted changes - - - + + + Update - - Open a repository - - - - - Quit - - - - - Quit EasyMercurial - - - - - Refresh the window to show the current state of the working folder - - - - - See what changes are available in the remote repository waiting to be pulled - - - - - Pull changes from the remote repository to the local repository - - - - - Push changes from the local repository to the remote repository - - - - - See what has changed in the working folder compared with the last committed state - - - - - Throw away your changes and return to the last committed state - - - - - Mark the selected file(s) to be added on the next commit - - - - - Mark the selected file(s) to be removed from version control on the next commit - - - - - Update the working folder to the head of the current repository branch - - - - - Commit your changes to the local repository - - - - - Merge the two independent sets of changes in the local repository into the working folder - - - - - Edit .hgignore File - - - - - Edit the .hgignore file, containing the names of files that should be ignored by Mercurial - - - - - Serve via HTTP - - - - - - + + + Merge - + the default branch - + branch "%1" - + On %1. Not at the head of the branch: consider updating - + <b>Awaiting merge</b> on %1 - + You are about to commit %n file(s). You are about to commit %n file. You are about to commit %n files. - - - Running temporary server at %n address(es): - - Running temporary server at this address: - Running temporary server at %n addresses: - - - - <p>Press Close to stop the server and return.</p> - - - - + <qt><h3>Update successful</h3><p>%1</p> - + <qt><h3>Merge successful</h3><p>%1</p> - + Resolved - + <qt><h3>Merge resolved</h3><p>Merge resolved successfully.</p> - - (Examining repository) - - - - + Nothing committed to this repository yet - + Have unresolved files following merge on %1 - + Have merged but not yet committed on %1 - + On %1. Not at the head of the branch - + At one of %n heads of %1 + - + At the head of %1 - + + Init local repository + + + + + Create an empty local repository in selected folder + + + + + Clone from remote + + + + + Clone from remote repository into local repository in selected folder + + + + Open... - + + Open repository + + + + Settings... - + View and change application settings - + + Exit + + + + + Exit application + + + + Refresh - + + Refresh (info of) status of workfolder files + + + + Preview - + + View info of changesets incoming to us from remote repository (on pull operation) + + + + Pull - + + Pull changesets from remote repository to local repository + + + + Push - + + Push local changesets to remote repository + + + + Diff - + + Folderdiff: View all differences between working folder files and local repository files + + + + + View changesetdiff + + + + + Change set diff: View differences between all files of 2 repository changesets + + + + Revert - + + Undo selected working folder file changes (return to local repository version) + + + + Add - + + Add working folder file(s) (selected or all yet untracked) to local repository (on next commit) + + + + Remove - + + Remove selected working folder file from local repository (on next commit) + + + + + Update working folder from local repository + + + + Commit - + + Save selected file(s) or all changed files in working folder (and all subfolders) to local repository + + + + + Merge two local repository changesets to working folder + + + + Annotate - + Show line-by-line version information for selected file - + + Tag revision + + + + + Give decsriptive name (tag) to current workfolder parent revision. + + + + + Edit .hgignore + + + + + Edit .hgignore file (file contains names of files that should be ignored by mercurial) + + + + + Serve (via http) + + + + Serve local repository via http for workgroup access - + About - + + Show the application's About box + + + + + About Qt + + + + + Show the Qt library's About box + + + + Clear selections - - + + File - + Advanced - + Help - + Ready @@ -994,98 +985,6 @@ - SettingsDialog - - - Settings - - - - - User details - - - - - Name: - - - - - Email address: - - - - - System application locations - - - - - Mercurial (hg) program: - - - - - - - - - Browse... - - - - - External diff program: - - - - - External file-merge program: - - - - - External text editor: - - - - - EasyHg Mercurial extension: - - - - - Use EasyHg Mercurial extension - - - - - Mercurial program - - - - - External diff program - - - - - External file-merge program - - - - - External text editor - - - - - EasyHg Mercurial extension - - - - StartupDialog @@ -1127,8 +1026,7 @@ - Summarise changes - Show summary + Show summary diff -r 0fe81e1b26ce -r 0689dada1419 grapher.cpp --- a/grapher.cpp Tue Jan 11 20:18:37 2011 +0000 +++ b/grapher.cpp Tue Jan 11 20:19:19 2011 +0000 @@ -427,6 +427,7 @@ ChangesetItem *item = new ChangesetItem(cs); item->setX(0); item->setY(0); + item->setZValue(0); m_items[id] = item; m_scene->addChangesetItem(item); } @@ -445,6 +446,7 @@ if (merge) conn->setConnectionType(ConnectionItem::Merge); conn->setChild(item); conn->setParent(m_items[parentId]); + conn->setZValue(-1); m_scene->addItem(conn); } } @@ -454,12 +456,14 @@ if (!m_uncommittedParents.empty()) { m_uncommitted = new UncommittedItem(); m_uncommitted->setBranch(uncommittedBranch); + m_uncommitted->setZValue(10); m_scene->addUncommittedItem(m_uncommitted); foreach (QString p, m_uncommittedParents) { ConnectionItem *conn = new ConnectionItem(); conn->setConnectionType(ConnectionItem::Merge); conn->setParent(m_items[p]); conn->setChild(m_uncommitted); + conn->setZValue(0); m_scene->addItem(conn); } } @@ -583,7 +587,7 @@ item->setCols(datemincol, datemaxcol - datemincol + 1); item->setRows(changeRow, n); item->setEven(even); - item->setZValue(-1); + item->setZValue(-2); m_scene->addDateItem(item); even = !even; } @@ -599,7 +603,7 @@ item->setCols(datemincol, datemaxcol - datemincol + 1); item->setRows(changeRow, n+1); item->setEven(even); - item->setZValue(-1); + item->setZValue(-2); m_scene->addDateItem(item); even = !even; } diff -r 0fe81e1b26ce -r 0689dada1419 historywidget.cpp --- a/historywidget.cpp Tue Jan 11 20:18:37 2011 +0000 +++ b/historywidget.cpp Tue Jan 11 20:19:19 2011 +0000 @@ -36,6 +36,7 @@ m_panner = new Panner; m_panned->setDragMode(QGraphicsView::ScrollHandDrag); + m_panned->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); QGridLayout *layout = new QGridLayout; layout->addWidget(m_panned, 0, 0); diff -r 0fe81e1b26ce -r 0689dada1419 mainwindow.cpp --- a/mainwindow.cpp Tue Jan 11 20:18:37 2011 +0000 +++ b/mainwindow.cpp Tue Jan 11 20:19:19 2011 +0000 @@ -124,10 +124,6 @@ cs->addDefaultName("default"); cs->addDefaultName(getUserInfo()); - if (workFolderPath == "") { - open(); - } - hgTest(); } @@ -495,6 +491,16 @@ hgIgnorePath = workFolderPath; hgIgnorePath += "/.hgignore"; + + if (!QDir(workFolderPath).exists()) return; + QFile f(hgIgnorePath); + if (!f.exists()) { + f.open(QFile::WriteOnly); + QTextStream *ts = new QTextStream(&f); + *ts << "syntax: glob\n"; + delete ts; + f.close(); + } params << hgIgnorePath; @@ -973,11 +979,22 @@ tr("Open a local folder, by creating a Mercurial repository in it."), MultiChoiceDialog::DirectoryArg); - d->setCurrentChoice("local"); + QSettings settings; + settings.beginGroup("General"); + QString lastChoice = settings.value("lastopentype", "local").toString(); + if (lastChoice != "local" && + lastChoice != "remote" && + lastChoice != "init") { + lastChoice = "local"; + } + + d->setCurrentChoice(lastChoice); if (d->exec() == QDialog::Accepted) { QString choice = d->getCurrentChoice(); + settings.setValue("lastopentype", choice); + QString arg = d->getArgument().trimmed(); bool result = false; @@ -1070,6 +1087,28 @@ return false; } +bool MainWindow::askAboutUnknownFolder(QString arg) +{ + bool result = (QMessageBox::question + (this, tr("Path does not exist"), + tr("Path does not exist: create it?

You asked to open a remote repository by cloning it to \"%1\". This folder does not exist, and neither does its parent.

Would you like to create the parent folder as well?
").arg(xmlEncode(arg)), + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Cancel) + == QMessageBox::Ok); + if (result) { + QDir dir(arg); + dir.cdUp(); + if (!dir.mkpath(dir.absolutePath())) { + QMessageBox::critical + (this, tr("Failed to create folder"), + tr("Failed to create folder

Sorry, the path for the parent folder \"%1\" could not be created.
").arg(dir.absolutePath())); + return false; + } + return true; + } + return false; +} + bool MainWindow::complainAboutUnknownFolder(QString arg) { QMessageBox::critical @@ -1265,7 +1304,9 @@ } if (status == FolderUnknown) { - return complainAboutUnknownFolder(local); + if (!askAboutUnknownFolder(local)) { + return false; + } } if (status == FolderExists) { @@ -1902,11 +1943,25 @@ switch (action) { case ACT_TEST_HG: - hgTestExtension(); + { + QSettings settings; + settings.beginGroup("General"); + if (settings.value("useextension", true).toBool()) { + hgTestExtension(); + } else if (workFolderPath == "") { + open(); + } else { + hgQueryPaths(); + } break; + } case ACT_TEST_HG_EXT: - hgQueryPaths(); + if (workFolderPath == "") { + open(); + } else{ + hgQueryPaths(); + } break; case ACT_QUERY_PATHS: @@ -2055,7 +2110,7 @@ workFolderExist = false; } - if (!workFolderDir.exists(workFolderPath)) { + if (workFolderPath == "" || !workFolderDir.exists(workFolderPath)) { localRepoActionsEnabled = false; workFolderExist = false; } else { @@ -2177,7 +2232,11 @@ } if (stateUnknown) { - hgTabs->setState(tr("(Examining repository)")); + if (workFolderPath == "") { + hgTabs->setState(tr("No repository open")); + } else { + hgTabs->setState(tr("(Examining repository)")); + } } else if (emptyRepo) { hgTabs->setState(tr("Nothing committed to this repository yet")); } else if (noWorkingCopy) { diff -r 0fe81e1b26ce -r 0689dada1419 mainwindow.h --- a/mainwindow.h Tue Jan 11 20:18:37 2011 +0000 +++ b/mainwindow.h Tue Jan 11 20:19:19 2011 +0000 @@ -144,6 +144,7 @@ bool complainAboutCloneToFile(QString); QString complainAboutCloneToExistingFolder(QString local, QString remote); // returns new location, or empty string for cancel + bool askAboutUnknownFolder(QString); bool askToInitExisting(QString); bool askToInitNew(QString); bool askToOpenParentRepo(QString, QString); diff -r 0fe81e1b26ce -r 0689dada1419 panner.cpp --- a/panner.cpp Tue Jan 11 20:18:37 2011 +0000 +++ b/panner.cpp Tue Jan 11 20:19:19 2011 +0000 @@ -110,6 +110,7 @@ void Panner::resizeEvent(QResizeEvent *) { + DEBUG << "Panner::resizeEvent" << endl; if (scene()) fit(sceneRect()); m_cache = QPixmap(); } @@ -117,6 +118,7 @@ void Panner::slotSceneRectChanged(const QRectF &newRect) { + DEBUG << "Panner::slotSceneRectChanged" << endl; if (!scene()) return; // spurious fit(newRect); m_cache = QPixmap(); @@ -126,6 +128,7 @@ void Panner::slotSceneChanged(const QList &) { + DEBUG << "Panner::slotSceneChanged" << endl; if (!scene()) return; // spurious m_cache = QPixmap(); viewport()->update(); @@ -163,7 +166,8 @@ void Panner::updateScene(const QList &rects) { - if (!m_cache.isNull()) m_cache = QPixmap(); + DEBUG << "Panner::updateScene" << endl; +// if (!m_cache.isNull()) m_cache = QPixmap(); QGraphicsView::updateScene(rects); } @@ -187,6 +191,8 @@ cachePainter.setTransform(viewportTransform()); ps->drawItems(&cachePainter, numItems, items, options); cachePainter.end(); + + DEBUG << "done" << endl; } painter->save(); diff -r 0fe81e1b26ce -r 0689dada1419 uncommitteditem.cpp --- a/uncommitteditem.cpp Tue Jan 11 20:18:37 2011 +0000 +++ b/uncommitteditem.cpp Tue Jan 11 20:19:19 2011 +0000 @@ -127,6 +127,7 @@ int height = 49; QRectF r(x0, 0, width - 3, height); + paint->setBrush(Qt::white); paint->drawRect(r); if (m_wide) {