Przeglądaj źródła

ENH: add context menu for deleting, ignoring, and getting help for cache entries.
ENH: add delete cache button
ENH: add information string above configure/generate buttons
ENH: change search to search both columns, and from regex to plain string search
ENH: add buddy info in cache entry view, so double clicking in the left column
starts editing the associated value.
BUG: fix file path editor so it goes away when focus is lost

Clinton Stimpson 18 lat temu
rodzic
commit
9f676df3c6

+ 5 - 1
Source/QtDialog/CMakeSetupDialog.cxx

@@ -77,7 +77,7 @@ CMakeSetupDialog::CMakeSetupDialog()
 
 
   QWidget* cont = new QWidget(this);
   QWidget* cont = new QWidget(this);
   this->setupUi(cont);
   this->setupUi(cont);
-  this->Splitter->setStretchFactor(0, 2);
+  this->Splitter->setStretchFactor(0, 3);
   this->Splitter->setStretchFactor(1, 1);
   this->Splitter->setStretchFactor(1, 1);
   this->setCentralWidget(cont);
   this->setCentralWidget(cont);
   this->ProgressBar->reset();
   this->ProgressBar->reset();
@@ -196,6 +196,9 @@ void CMakeSetupDialog::initialize()
                    this, SLOT(cacheModelDirty()));
                    this, SLOT(cacheModelDirty()));
   QObject::connect(this->CacheValues->cacheModel(), SIGNAL(modelReset()),
   QObject::connect(this->CacheValues->cacheModel(), SIGNAL(modelReset()),
                    this, SLOT(cacheModelDirty()));
                    this, SLOT(cacheModelDirty()));
+  
+  QObject::connect(this->DeleteCacheButton, SIGNAL(clicked(bool)), 
+                   this, SLOT(doDeleteCache()));
 
 
   // get the saved binary directories
   // get the saved binary directories
   QStringList buildPaths = this->loadBuildPaths();
   QStringList buildPaths = this->loadBuildPaths();
@@ -464,6 +467,7 @@ void CMakeSetupDialog::setEnabledState(bool enabled)
   this->ConfigureButton->setEnabled(enabled);
   this->ConfigureButton->setEnabled(enabled);
   this->ReloadCacheAction->setEnabled(enabled);
   this->ReloadCacheAction->setEnabled(enabled);
   this->DeleteCacheAction->setEnabled(enabled);
   this->DeleteCacheAction->setEnabled(enabled);
+  this->DeleteCacheButton->setEnabled(enabled);
   this->ExitAction->setEnabled(enabled);
   this->ExitAction->setEnabled(enabled);
   this->ConfigureAction->setEnabled(enabled);
   this->ConfigureAction->setEnabled(enabled);
   // generate button/action are handled separately
   // generate button/action are handled separately

+ 26 - 3
Source/QtDialog/CMakeSetupDialog.ui

@@ -5,8 +5,8 @@
    <rect>
    <rect>
     <x>0</x>
     <x>0</x>
     <y>0</y>
     <y>0</y>
-    <width>693</width>
-    <height>582</height>
+    <width>705</width>
+    <height>495</height>
    </rect>
    </rect>
   </property>
   </property>
   <layout class="QGridLayout" >
   <layout class="QGridLayout" >
@@ -140,6 +140,9 @@
       <property name="alternatingRowColors" >
       <property name="alternatingRowColors" >
        <bool>true</bool>
        <bool>true</bool>
       </property>
       </property>
+      <property name="selectionMode" >
+       <enum>QAbstractItemView::ExtendedSelection</enum>
+      </property>
       <property name="selectionBehavior" >
       <property name="selectionBehavior" >
        <enum>QAbstractItemView::SelectRows</enum>
        <enum>QAbstractItemView::SelectRows</enum>
       </property>
       </property>
@@ -154,7 +157,7 @@
      </widget>
      </widget>
     </widget>
     </widget>
    </item>
    </item>
-   <item row="3" column="0" >
+   <item row="4" column="0" >
     <layout class="QHBoxLayout" >
     <layout class="QHBoxLayout" >
      <item>
      <item>
       <widget class="QPushButton" name="ConfigureButton" >
       <widget class="QPushButton" name="ConfigureButton" >
@@ -170,6 +173,13 @@
        </property>
        </property>
       </widget>
       </widget>
      </item>
      </item>
+     <item>
+      <widget class="QPushButton" name="DeleteCacheButton" >
+       <property name="text" >
+        <string>Delete Cache</string>
+       </property>
+      </widget>
+     </item>
      <item>
      <item>
       <spacer>
       <spacer>
        <property name="orientation" >
        <property name="orientation" >
@@ -205,6 +215,19 @@
      </item>
      </item>
     </layout>
     </layout>
    </item>
    </item>
+   <item row="3" column="0" >
+    <widget class="QLabel" name="label_3" >
+     <property name="text" >
+      <string>Right click on a cache value for additional options (delete, ignore, and help).&lt;br>Press Configure to update and display new values in red, then press Generate to generate selected build files.</string>
+     </property>
+     <property name="alignment" >
+      <set>Qt::AlignCenter</set>
+     </property>
+     <property name="wordWrap" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
   </layout>
   </layout>
  </widget>
  </widget>
  <customwidgets>
  <customwidgets>

+ 28 - 5
Source/QtDialog/QCMake.cxx

@@ -150,22 +150,45 @@ void QCMake::generate()
   
   
 void QCMake::setProperties(const QCMakeCachePropertyList& props)
 void QCMake::setProperties(const QCMakeCachePropertyList& props)
 {
 {
+  QStringList toremove;
   cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
   cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
-  cmCacheManager::CacheIterator it = cachem->NewIterator();
-  foreach(QCMakeCacheProperty prop, props)
+  for(cmCacheManager::CacheIterator i = cachem->NewIterator();
+      !i.IsAtEnd(); i.Next())
     {
     {
-    if ( it.Find(prop.Key.toAscii().data()) )
+
+    if(i.GetType() == cmCacheManager::INTERNAL ||
+       i.GetType() == cmCacheManager::STATIC)
+      {
+      continue;
+      }
+
+    QCMakeCacheProperty prop;
+    prop.Key = i.GetName();
+    int idx = props.indexOf(prop);
+    if(idx == -1)
       {
       {
+      toremove.append(i.GetName());
+      }
+    else
+      {
+      prop = props[idx];
       if(prop.Value.type() == QVariant::Bool)
       if(prop.Value.type() == QVariant::Bool)
         {
         {
-        it.SetValue(prop.Value.toBool() ? "ON" : "OFF");
+        i.SetValue(prop.Value.toBool() ? "ON" : "OFF");
         }
         }
       else
       else
         {
         {
-        it.SetValue(prop.Value.toString().toAscii().data());
+        i.SetValue(prop.Value.toString().toAscii().data());
         }
         }
       }
       }
+
     }
     }
+
+  foreach(QString s, toremove)
+    {
+    cachem->RemoveCacheEntry(s.toAscii().data());
+    }
+  
   cachem->SaveCache(this->BinaryDirectory.toAscii().data());
   cachem->SaveCache(this->BinaryDirectory.toAscii().data());
 }
 }
 
 

+ 129 - 22
Source/QtDialog/QCMakeCacheView.cxx

@@ -25,6 +25,10 @@
 #include <QFileInfo>
 #include <QFileInfo>
 #include <QStyle>
 #include <QStyle>
 #include <QKeyEvent>
 #include <QKeyEvent>
+#include <QMenu>
+#include <QDialog>
+#include <QLabel>
+#include <QDialogButtonBox>
 
 
 static QRegExp AdvancedRegExp[2] = { QRegExp("(false)"), QRegExp("(true|false)") };
 static QRegExp AdvancedRegExp[2] = { QRegExp("(false)"), QRegExp("(true|false)") };
 
 
@@ -40,6 +44,7 @@ QCMakeCacheView::QCMakeCacheView(QWidget* p)
   this->SearchFilter = new QSortFilterProxyModel(this);
   this->SearchFilter = new QSortFilterProxyModel(this);
   this->SearchFilter->setSourceModel(this->AdvancedFilter);
   this->SearchFilter->setSourceModel(this->AdvancedFilter);
   this->SearchFilter->setFilterCaseSensitivity(Qt::CaseInsensitive);
   this->SearchFilter->setFilterCaseSensitivity(Qt::CaseInsensitive);
+  this->SearchFilter->setFilterKeyColumn(-1); // all columns
   this->setModel(this->SearchFilter);
   this->setModel(this->SearchFilter);
 
 
   // our delegate for creating our editors
   // our delegate for creating our editors
@@ -72,6 +77,81 @@ QCMakeCacheModel* QCMakeCacheView::cacheModel() const
 {
 {
   return this->CacheModel;
   return this->CacheModel;
 }
 }
+  
+void QCMakeCacheView::contextMenuEvent(QContextMenuEvent* /*e*/)
+{
+  QList<QModelIndex> idxs = this->selectionModel()->selectedRows();
+
+  if(idxs.count())
+    {
+    QMenu* menu = new QMenu(this);
+    QAction* d = NULL;
+    QAction* i = NULL;
+    if(this->cacheModel()->editEnabled())
+      {
+      QString t = idxs.count() > 1 ? tr("Delete Cache Entries") : 
+                                     tr("Delete Cache Entry");
+      d = menu->addAction(t);
+      t = idxs.count() > 1 ? tr("Ignore Cache Entries") : 
+                             tr("Ignore Cache Entry");
+      i = menu->addAction(t);
+      }
+    QAction* h = menu->addAction(tr("Help For Cache Entry"));
+    QAction* which = menu->exec(QCursor::pos());
+    if(!which)
+      {
+      return;
+      }
+    
+    if(which == h)
+      {
+      QModelIndex idx = this->selectionModel()->currentIndex();
+      idx = this->SearchFilter->mapToSource(idx);
+      idx = this->AdvancedFilter->mapToSource(idx);
+      idx = this->cacheModel()->index(idx.row(), 0);
+      QString msg = this->cacheModel()->data(idx, Qt::DisplayRole).toString() +
+                    "\n\n" +
+             this->cacheModel()->data(idx, QCMakeCacheModel::HelpRole).toString();
+      QDialog dialog;
+      dialog.setWindowTitle(tr("CMakeSetup Help"));
+      QVBoxLayout* l = new QVBoxLayout(&dialog);
+      QLabel* lab = new QLabel(&dialog);
+      l->addWidget(lab);
+      lab->setText(msg);
+      lab->setWordWrap(true);
+      QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
+                                                    Qt::Horizontal, &dialog);
+      QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
+      l->addWidget(btns);
+      dialog.exec();
+      }
+    else
+      {
+      QList<QPersistentModelIndex> pidxs;
+      foreach(QModelIndex i, idxs)
+        {
+        i = this->SearchFilter->mapToSource(i);
+        i = this->AdvancedFilter->mapToSource(i);
+        pidxs.append(i);
+        }
+      if(which == d)
+        {
+        foreach(QPersistentModelIndex j, pidxs)
+          {
+          this->cacheModel()->removeRows(j.row(), 1);
+          }
+        }
+      else if(which == i)
+        {
+        foreach(QPersistentModelIndex j, pidxs)
+          {
+          j = this->cacheModel()->index(j.row(), 1);
+          this->cacheModel()->setData(j, "IGNORE", Qt::DisplayRole);
+          }
+        }
+      }
+    }
+}
 
 
 QModelIndex QCMakeCacheView::moveCursor(CursorAction act, 
 QModelIndex QCMakeCacheView::moveCursor(CursorAction act, 
   Qt::KeyboardModifiers mod)
   Qt::KeyboardModifiers mod)
@@ -120,7 +200,7 @@ bool QCMakeCacheView::showAdvanced() const
 
 
 void QCMakeCacheView::setSearchFilter(const QString& s)
 void QCMakeCacheView::setSearchFilter(const QString& s)
 {
 {
-  this->SearchFilter->setFilterRegExp(s);
+  this->SearchFilter->setFilterFixedString(s);
 }
 }
 
 
 QCMakeCacheModel::QCMakeCacheModel(QObject* p)
 QCMakeCacheModel::QCMakeCacheModel(QObject* p)
@@ -297,7 +377,30 @@ bool QCMakeCacheModel::setData (const QModelIndex& idx, const QVariant& value, i
   return false;
   return false;
 }
 }
 
 
-
+QModelIndex QCMakeCacheModel::buddy ( const QModelIndex& idx ) const
+{
+  if(idx.column() == 0)
+    {
+    return this->index(idx.row(), 1);
+    }
+  return idx;
+}
+  
+bool QCMakeCacheModel::removeRows(int row, int, const QModelIndex&)
+{
+  if(row < 0 || row >= this->Properties.count())
+    {
+    return false;
+    }
+  this->beginRemoveRows(QModelIndex(), row, row);
+  this->Properties.removeAt(row);
+  if(this->NewCount >= row+1)
+    {
+    this->NewCount--;
+    }
+  this->endRemoveRows();
+  return true;
+}
 
 
 QCMakeCacheModelDelegate::QCMakeCacheModelDelegate(QObject* p)
 QCMakeCacheModelDelegate::QCMakeCacheModelDelegate(QObject* p)
   : QItemDelegate(p)
   : QItemDelegate(p)
@@ -314,52 +417,56 @@ QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p,
     }
     }
   else if(type == QCMakeCacheProperty::PATH)
   else if(type == QCMakeCacheProperty::PATH)
     {
     {
-    return new QCMakeCachePathEditor(idx.data().toString(), false, p);
+    return new QCMakeCachePathEditor(false, p);
     }
     }
   else if(type == QCMakeCacheProperty::FILEPATH)
   else if(type == QCMakeCacheProperty::FILEPATH)
     {
     {
-    return new QCMakeCachePathEditor(idx.data().toString(), true, p);
+    return new QCMakeCachePathEditor(true, p);
     }
     }
 
 
   return new QLineEdit(p);
   return new QLineEdit(p);
 }
 }
   
   
-QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, bool fp,
-                                             QWidget* p)
-  : QWidget(p), LineEdit(this), IsFilePath(fp)
+QCMakeCachePathEditor::QCMakeCachePathEditor(bool fp, QWidget* p)
+  : QLineEdit(p), IsFilePath(fp)
 {
 {
-  QHBoxLayout* l = new QHBoxLayout(this);
-  l->setMargin(0);
-  l->setSpacing(0);
-  l->addWidget(&this->LineEdit);
-  QToolButton* tb = new QToolButton(this);
-  tb->setText("...");
-  l->addWidget(tb);
-  QObject::connect(tb, SIGNAL(clicked(bool)),
+  // this *is* instead of has a line edit so QAbstractItemView
+  // doesn't get confused with what the editor really is
+  this->setContentsMargins(0, 0, 0, 0);
+  this->ToolButton = new QToolButton(this);
+  this->ToolButton->setText("...");
+  this->ToolButton->setCursor(QCursor(Qt::ArrowCursor));
+  QObject::connect(this->ToolButton, SIGNAL(clicked(bool)),
                    this, SLOT(chooseFile()));
                    this, SLOT(chooseFile()));
-  this->LineEdit.setText(file);
-  this->LineEdit.selectAll();
-  tb->setFocusProxy(&this->LineEdit);
-  this->setFocusProxy(&this->LineEdit);
+}
+
+void QCMakeCachePathEditor::resizeEvent(QResizeEvent* e)
+{
+  // make the tool button fit on the right side
+  int h = e->size().height();
+  this->ToolButton->resize(h, h);
+  this->ToolButton->move(this->width() - h, 0);
+  this->setContentsMargins(0, 0, h, 0);
 }
 }
 
 
 void QCMakeCachePathEditor::chooseFile()
 void QCMakeCachePathEditor::chooseFile()
 {
 {
+  // choose a file and set it
   QString path;
   QString path;
   if(this->IsFilePath)
   if(this->IsFilePath)
     {
     {
-    QFileInfo info(this->value());
+    QFileInfo info(this->text());
     path = QFileDialog::getOpenFileName(this, tr("Select File"), 
     path = QFileDialog::getOpenFileName(this, tr("Select File"), 
         info.absolutePath());
         info.absolutePath());
     }
     }
   else
   else
     {
     {
     path = QFileDialog::getExistingDirectory(this, tr("Select Path"), 
     path = QFileDialog::getExistingDirectory(this, tr("Select Path"), 
-        this->value());
+        this->text());
     }
     }
   if(!path.isEmpty())
   if(!path.isEmpty())
     {
     {
-    this->LineEdit.setText(path);
+    this->setText(path);
     }
     }
 }
 }
 
 

+ 9 - 6
Source/QtDialog/QCMakeCacheView.h

@@ -27,6 +27,7 @@
 #include <QSortFilterProxyModel>
 #include <QSortFilterProxyModel>
 
 
 class QCMakeCacheModel;
 class QCMakeCacheModel;
+class QToolButton;
 
 
 
 
 /// Qt view class for cache properties
 /// Qt view class for cache properties
@@ -44,6 +45,7 @@ public slots:
   void setSearchFilter(const QString&);
   void setSearchFilter(const QString&);
 
 
 protected:
 protected:
+  void contextMenuEvent(QContextMenuEvent* e);
   QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
   QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
   void showEvent(QShowEvent* e);
   void showEvent(QShowEvent* e);
   bool Init;
   bool Init;
@@ -66,16 +68,18 @@ public slots:
   void setProperties(const QCMakeCachePropertyList& props);
   void setProperties(const QCMakeCachePropertyList& props);
   void clear();
   void clear();
   void setEditEnabled(bool);
   void setEditEnabled(bool);
+  bool removeRows(int row, int count, const QModelIndex& idx = QModelIndex());
 
 
 public:
 public:
   // satisfy [pure] virtuals
   // satisfy [pure] virtuals
   int columnCount ( const QModelIndex & parent ) const;
   int columnCount ( const QModelIndex & parent ) const;
-  QVariant data ( const QModelIndex & index, int role ) const;
+  QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole) const;
   QModelIndex parent ( const QModelIndex & index ) const;
   QModelIndex parent ( const QModelIndex & index ) const;
   int rowCount ( const QModelIndex & parent ) const;
   int rowCount ( const QModelIndex & parent ) const;
   QVariant headerData ( int section, Qt::Orientation orient, int role ) const;
   QVariant headerData ( int section, Qt::Orientation orient, int role ) const;
   Qt::ItemFlags flags ( const QModelIndex& index ) const;
   Qt::ItemFlags flags ( const QModelIndex& index ) const;
   bool setData ( const QModelIndex& index, const QVariant& value, int role );
   bool setData ( const QModelIndex& index, const QVariant& value, int role );
+  QModelIndex buddy ( const QModelIndex& index ) const;
 
 
   // flag if a cache property has been modified
   // flag if a cache property has been modified
   bool modifiedValues() const;
   bool modifiedValues() const;
@@ -105,18 +109,17 @@ public:
 };
 };
 
 
 /// Editor widget for editing paths or file paths
 /// Editor widget for editing paths or file paths
-class QCMakeCachePathEditor : public QWidget
+class QCMakeCachePathEditor : public QLineEdit
 {
 {
   Q_OBJECT
   Q_OBJECT
-  Q_PROPERTY(QString value READ value USER true)
 public:
 public:
-  QCMakeCachePathEditor(const QString& file, bool isFilePath, QWidget* p);
-  QString value() const { return this->LineEdit.text(); }
+  QCMakeCachePathEditor(bool isFilePath, QWidget* p);
 protected slots:
 protected slots:
   void chooseFile();
   void chooseFile();
 protected:
 protected:
-  QLineEdit LineEdit;
+  void resizeEvent(QResizeEvent* e);
   bool IsFilePath;
   bool IsFilePath;
+  QToolButton* ToolButton;
 };
 };
 
 
 #endif
 #endif