From 881610dfd2ee0f8450b3f1aec78c9a5a6ff76b43 Mon Sep 17 00:00:00 2001
From: goro <qtc-committer@nokia.com>
Date: Fri, 5 Dec 2008 18:51:07 +0100
Subject: [PATCH] Migrate subversion plugin to extended PathChooser

---
 src/libs/utils/pathchooser.cpp          | 131 +++++++++++++++++++-----
 src/libs/utils/pathchooser.h            |  20 +++-
 src/plugins/subversion/settingspage.cpp |  17 ++-
 src/plugins/subversion/settingspage.h   |   3 -
 src/plugins/subversion/settingspage.ui  |  20 ++--
 5 files changed, 143 insertions(+), 48 deletions(-)

diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp
index 340dbcad36a..68ebe9cbbfd 100644
--- a/src/libs/utils/pathchooser.cpp
+++ b/src/libs/utils/pathchooser.cpp
@@ -48,40 +48,54 @@
 namespace Core {
 namespace Utils {
 
+#ifdef Q_OS_OSX
+/*static*/ const char * const PathChooser::browseButtonLabel = "Choose...";
+#else
+/*static*/ const char * const PathChooser::browseButtonLabel = "Browse...";
+#endif
+
 // ------------------ PathValidatingLineEdit
 class PathValidatingLineEdit : public BaseValidatingLineEdit {
 public:
-    explicit PathValidatingLineEdit(QWidget *parent = 0);
+    explicit PathValidatingLineEdit(PathChooser *chooser, QWidget *parent = 0);
 
 protected:
     virtual bool validate(const QString &value, QString *errorMessage) const;
+
+private:
+    PathChooser *m_chooser;
 };
 
-PathValidatingLineEdit::PathValidatingLineEdit(QWidget *parent) :
-    BaseValidatingLineEdit(parent)
+PathValidatingLineEdit::PathValidatingLineEdit(PathChooser *chooser, QWidget *parent) :
+    BaseValidatingLineEdit(parent),
+    m_chooser(chooser)
 {
+    Q_ASSERT(chooser != NULL);
 }
 
 bool PathValidatingLineEdit::validate(const QString &value, QString *errorMessage) const
 {
-    return PathChooser::validatePath(value, errorMessage);
+    return m_chooser->validatePath(value, errorMessage);
 }
 
 // ------------------ PathChooserPrivate
 struct PathChooserPrivate {
-    PathChooserPrivate();
+    PathChooserPrivate(PathChooser *chooser);
 
     PathValidatingLineEdit *m_lineEdit;
+    PathChooser::Kind m_acceptingKind;
+    QString m_dialogTitleOverride;
 };
 
-PathChooserPrivate::PathChooserPrivate() :
-    m_lineEdit(new PathValidatingLineEdit)
+PathChooserPrivate::PathChooserPrivate(PathChooser *chooser) :
+    m_lineEdit(new PathValidatingLineEdit(chooser)),
+    m_acceptingKind(PathChooser::Directory)
 {
 }
 
 PathChooser::PathChooser(QWidget *parent) :
     QWidget(parent),
-    m_d(new PathChooserPrivate)
+    m_d(new PathChooserPrivate(this))
 {
     QHBoxLayout *hLayout = new QHBoxLayout;
     hLayout->setContentsMargins(0, 0, 0, 0);
@@ -90,11 +104,12 @@ PathChooser::PathChooser(QWidget *parent) :
     connect(m_d->m_lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()));
     connect(m_d->m_lineEdit, SIGNAL(validChanged()), this, SIGNAL(validChanged()));
 
-    m_d->m_lineEdit->setMinimumWidth(300);
+    m_d->m_lineEdit->setMinimumWidth(260);
     hLayout->addWidget(m_d->m_lineEdit);
+    hLayout->setSizeConstraint(QLayout::SetMinimumSize);
 
     QToolButton *browseButton = new QToolButton;
-    browseButton->setText(tr("..."));
+    browseButton->setText(tr(browseButtonLabel));
     connect(browseButton, SIGNAL(clicked()), this, SLOT(slotBrowse()));
 
     hLayout->addWidget(browseButton);
@@ -123,8 +138,28 @@ void PathChooser::slotBrowse()
     QString predefined = path();
     if (!predefined.isEmpty() && !QFileInfo(predefined).isDir())
         predefined.clear();
-    // Prompt for a directory, delete trailing slashes unless it is "/", only
-    QString newPath = QFileDialog::getExistingDirectory(this, tr("Choose a path"), predefined);
+
+    // Prompt for a file/dir
+    QString dialogTitle;
+    QString newPath;
+    switch (m_d->m_acceptingKind) {
+    case PathChooser::Directory:
+        newPath = QFileDialog::getExistingDirectory(this,
+                makeDialogTitle(tr("Choose a directory")), predefined);
+        break;
+
+    case PathChooser::File: // fall through
+    case PathChooser::Command:
+        newPath = QFileDialog::getOpenFileName(this,
+                makeDialogTitle(tr("Choose a file")), predefined);
+        break;
+
+    default:
+        ;
+    }
+
+    // TODO make cross-platform
+    // Delete trailing slashes unless it is "/", only
     if (!newPath .isEmpty()) {
         if (newPath .size() > 1 && newPath .endsWith(QDir::separator()))
             newPath .truncate(newPath .size() - 1);
@@ -149,20 +184,52 @@ bool PathChooser::validatePath(const QString &path, QString *errorMessage)
             *errorMessage = tr("The path must not be empty.");
         return false;
     }
-    // Must be a directory?
+
     const QFileInfo fi(path);
-    if (fi.isDir())
-        return true; // Happy!
+    const bool isDir = fi.isDir();
 
-    if (!fi.exists()) {
-        if (errorMessage)
-            *errorMessage = tr("The path '%1' does not exist.").arg(path);
-        return false;
+    // Check if existing
+    switch (m_d->m_acceptingKind) {
+    case PathChooser::Directory: // fall through
+    case PathChooser::File:
+        if (!fi.exists()) {
+            if (errorMessage)
+                *errorMessage = tr("The path '%1' does not exist.").arg(path);
+            return false;
+        }
+        break;
+
+    case PathChooser::Command: // fall through
+    default:
+        ;
+    }
+
+    // Check expected kind
+    switch (m_d->m_acceptingKind) {
+    case PathChooser::Directory:
+        if (!isDir)
+            if (errorMessage)
+                *errorMessage = tr("The path '%1' is not a directory.").arg(path);
+            return false;
+        break;
+
+    case PathChooser::File:
+        if (isDir)
+            if (errorMessage)
+                *errorMessage = tr("The path '%1' is not a file.").arg(path);
+            return false;
+        break;
+
+    case PathChooser::Command:
+        // TODO do proper command validation
+        // i.e. search $PATH for a matching file
+        break;
+
+    default:
+        ;
     }
-    // Must be something weird
-    if (errorMessage)
-        *errorMessage = tr("The path '%1' is not a directory.").arg(path);
-    return false;
+
+    return true;
 }
 
 QString PathChooser::label()
@@ -182,5 +249,23 @@ QString PathChooser::homePath()
 #endif
 }
 
+void PathChooser::setExpectedKind(Kind expected)
+{
+    m_d->m_acceptingKind = expected;
+}
+
+void PathChooser::setPromptDialogTitle(const QString &title)
+{
+    m_d->m_dialogTitleOverride = title;
+}
+
+QString PathChooser::makeDialogTitle(const QString &title)
+{
+    if (m_d->m_dialogTitleOverride.isNull())
+        return title;
+    else
+        return m_d->m_dialogTitleOverride;
+}
+
 } // namespace Utils
 } // namespace Core
diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h
index ab821d5df1e..d4bd098e908 100644
--- a/src/libs/utils/pathchooser.h
+++ b/src/libs/utils/pathchooser.h
@@ -54,9 +54,23 @@ class QWORKBENCH_UTILS_EXPORT PathChooser : public QWidget
     Q_PROPERTY(QString path READ path WRITE setPath DESIGNABLE true)
 
 public:
+    static const char * const browseButtonLabel;
+
     explicit PathChooser(QWidget *parent = 0);
     virtual ~PathChooser();
 
+    enum Kind {
+        Directory,
+        File,
+        Command,
+        // ,Any
+    };
+
+    // Default is <Directory>
+    void setExpectedKind(Kind expected);
+
+    void setPromptDialogTitle(const QString &title);
+
     bool isValid() const;
     QString errorMessage() const;
 
@@ -65,11 +79,15 @@ public:
     // Returns the suggested label title when used in a form layout
     static QString label();
 
-    static bool validatePath(const QString &path, QString *errorMessage = 0);
+    bool validatePath(const QString &path, QString *errorMessage = 0);
 
     // Return the home directory, which needs some fixing under Windows.
     static QString homePath();
 
+private:
+    // Returns overridden title or the one from <title>
+    QString makeDialogTitle(const QString &title);
+
 signals:
     void validChanged();
     void changed();
diff --git a/src/plugins/subversion/settingspage.cpp b/src/plugins/subversion/settingspage.cpp
index ab785db796e..4621928b963 100644
--- a/src/plugins/subversion/settingspage.cpp
+++ b/src/plugins/subversion/settingspage.cpp
@@ -39,20 +39,24 @@
 #include <extensionsystem/pluginmanager.h>
 
 #include <QtGui/QFileDialog>
+#include <utils/pathchooser.h>
 
 using namespace Subversion::Internal;
+using namespace Core::Utils;
+
 
 SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
     QWidget(parent)
 {
     m_ui.setupUi(this);
-    connect(m_ui.browseButton, SIGNAL(clicked()), this, SLOT(browseForCommand()));
+    m_ui.pathChooser->setExpectedKind(PathChooser::Command);
+    m_ui.pathChooser->setPromptDialogTitle(tr("Subversion Command"));
 }
 
 SubversionSettings SettingsPageWidget::settings() const
 {
     SubversionSettings rc;
-    rc.svnCommand = m_ui.svnCmdLineEdit->text();
+    rc.svnCommand = m_ui.pathChooser->path();
     rc.useAuthentication = m_ui.userGroupBox->isChecked();
     rc.user =  m_ui.usernameLineEdit->text();
     rc.password = m_ui.passwordLineEdit->text();
@@ -63,19 +67,12 @@ SubversionSettings SettingsPageWidget::settings() const
 
 void SettingsPageWidget::setSettings(const SubversionSettings &s)
 {
-    m_ui.svnCmdLineEdit->setText(s.svnCommand);
+    m_ui.pathChooser->setPath(s.svnCommand);
     m_ui.usernameLineEdit->setText(s.user);
     m_ui.passwordLineEdit->setText(s.password);
     m_ui.userGroupBox->setChecked(s.useAuthentication);
 }
 
-void SettingsPageWidget::browseForCommand()
-{
-    QString cmd = QFileDialog::getOpenFileName(window(), tr("Subversion Command"));
-    if (!cmd.isEmpty())
-        m_ui.svnCmdLineEdit->setText(cmd);
-}
-
 SettingsPage::SettingsPage()
 {
 }
diff --git a/src/plugins/subversion/settingspage.h b/src/plugins/subversion/settingspage.h
index f32401b6d93..8ac704f0727 100644
--- a/src/plugins/subversion/settingspage.h
+++ b/src/plugins/subversion/settingspage.h
@@ -59,9 +59,6 @@ public:
     SubversionSettings settings() const;
     void setSettings(const SubversionSettings &);
 
-private slots:;
-    void browseForCommand();
-
 private:
     Ui::SettingsPage m_ui;
 };
diff --git a/src/plugins/subversion/settingspage.ui b/src/plugins/subversion/settingspage.ui
index 14e5ebce87e..21b20187bbd 100644
--- a/src/plugins/subversion/settingspage.ui
+++ b/src/plugins/subversion/settingspage.ui
@@ -32,14 +32,7 @@
         </widget>
        </item>
        <item>
-        <widget class="QLineEdit" name="svnCmdLineEdit"/>
-       </item>
-       <item>
-        <widget class="QToolButton" name="browseButton">
-         <property name="text">
-          <string>...</string>
-         </property>
-        </widget>
+        <widget class="Core::Utils::PathChooser" name="pathChooser" native="true"/>
        </item>
       </layout>
      </item>
@@ -109,9 +102,14 @@
    </item>
   </layout>
  </widget>
- <tabstops>
-  <tabstop>svnCmdLineEdit</tabstop>
- </tabstops>
+ <customwidgets>
+  <customwidget>
+   <class>Core::Utils::PathChooser</class>
+   <extends>QWidget</extends>
+   <header location="global">utils/pathchooser.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections/>
 </ui>
-- 
GitLab