OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / debugger / breakwindow.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "breakwindow.h"
35 #include "breakhandler.h"
36
37 #include "debuggeractions.h"
38 #include "debuggercore.h"
39 #include "ui_breakpoint.h"
40 #include "ui_breakcondition.h"
41
42 #include <utils/pathchooser.h>
43 #include <utils/qtcassert.h>
44 #include <utils/savedaction.h>
45
46 #include <QtCore/QDebug>
47
48 #include <QtGui/QAction>
49 #include <QtGui/QIntValidator>
50 #include <QtGui/QKeyEvent>
51 #include <QtGui/QMenu>
52
53 namespace Debugger {
54 namespace Internal {
55
56
57 ///////////////////////////////////////////////////////////////////////
58 //
59 // BreakpointDialog: Show a dialog for editing breakpoints. Shows controls
60 // for the file-and-line, function and address parameters depending on the
61 // breakpoint type. The controls not applicable to the current type
62 // (say function name for file-and-line) are disabled and cleared out.
63 // However,the values are saved and restored once the respective mode
64 // is again choosen, which is done using m_savedParameters and
65 // setters/getters taking the parts mask enumeration parameter.
66 //
67 ///////////////////////////////////////////////////////////////////////
68
69 class BreakpointDialog : public QDialog
70 {
71     Q_OBJECT
72 public:
73     explicit BreakpointDialog(QWidget *parent);
74     bool showDialog(BreakpointParameters *data);
75
76     void setParameters(const BreakpointParameters &data);
77     BreakpointParameters parameters() const;
78
79 public slots:
80     void typeChanged(int index);
81
82 private:
83     enum DialogPart {
84         FileAndLinePart = 0x1,
85         FunctionPart = 0x2,
86         AddressPart = 0x4,
87         ConditionPart = 0x8,
88         AllParts = FileAndLinePart|FunctionPart|AddressPart|ConditionPart
89     };
90
91     void setPartsEnabled(unsigned partsMask);
92     void clearOtherParts(unsigned partsMask);
93     void getParts(unsigned partsMask, BreakpointParameters *data) const;
94     void setParts(unsigned partsMask, const BreakpointParameters &data);
95
96     void setType(BreakpointType type);
97     BreakpointType type() const;
98
99     Ui::BreakpointDialog m_ui;
100     BreakpointParameters m_savedParameters;
101     BreakpointType m_previousType;
102 };
103
104 BreakpointDialog::BreakpointDialog(QWidget *parent)
105   : QDialog(parent), m_previousType(UnknownType)
106 {
107     // Match BreakpointType (omitting unknown type).
108     m_ui.setupUi(this);
109     QStringList types;
110     types << tr("File and Line Number") << tr("Function Name") << tr("Address")
111           << tr("throw") << tr("catch") << tr("Function \"main()\"")
112           << tr("Address (Watchpoint)");
113     QTC_ASSERT(types.size() == Watchpoint, return; )
114     m_ui.comboBoxType->addItems(types);
115     m_ui.pathChooserFileName->setExpectedKind(Utils::PathChooser::File);
116     connect(m_ui.comboBoxType, SIGNAL(activated(int)), SLOT(typeChanged(int)));
117     m_ui.lineEditIgnoreCount->setValidator(
118         new QIntValidator(0, 2147483647, m_ui.lineEditIgnoreCount));
119 }
120
121 void BreakpointDialog::setType(BreakpointType type)
122 {
123     const int comboIndex = type - 1; // Skip UnknownType.
124     if (comboIndex != m_ui.comboBoxType->currentIndex()) {
125         m_ui.comboBoxType->setCurrentIndex(comboIndex);
126         typeChanged(comboIndex);
127     }
128 }
129
130 BreakpointType BreakpointDialog::type() const
131 {
132     const int type = m_ui.comboBoxType->currentIndex() + 1; // Skip unknown type.
133     return static_cast<BreakpointType>(type);
134 }
135
136 void BreakpointDialog::setParameters(const BreakpointParameters &data)
137 {
138     m_savedParameters = data;
139     setType(data.type);
140     setParts(AllParts, data);
141 }
142
143 BreakpointParameters BreakpointDialog::parameters() const
144 {
145     BreakpointParameters data(type());
146     getParts(AllParts, &data);
147     return data;
148 }
149
150 void BreakpointDialog::setPartsEnabled(unsigned partsMask)
151 {
152     m_ui.labelFileName->setEnabled(partsMask & FileAndLinePart);
153     m_ui.pathChooserFileName->setEnabled(partsMask & FileAndLinePart);
154     m_ui.labelLineNumber->setEnabled(partsMask & FileAndLinePart);
155     m_ui.lineEditLineNumber->setEnabled(partsMask & FileAndLinePart);
156     m_ui.labelUseFullPath->setEnabled(partsMask & FileAndLinePart);
157     m_ui.checkBoxUseFullPath->setEnabled(partsMask & FileAndLinePart);
158
159     m_ui.labelFunction->setEnabled(partsMask & FunctionPart);
160     m_ui.lineEditFunction->setEnabled(partsMask & FunctionPart);
161
162     m_ui.labelAddress->setEnabled(partsMask & AddressPart);
163     m_ui.lineEditAddress->setEnabled(partsMask & AddressPart);
164
165     m_ui.labelCondition->setEnabled(partsMask & ConditionPart);
166     m_ui.labelIgnoreCount->setEnabled(partsMask & ConditionPart);
167     m_ui.labelThreadSpec->setEnabled(partsMask & ConditionPart);
168     m_ui.lineEditCondition->setEnabled(partsMask & ConditionPart);
169     m_ui.lineEditIgnoreCount->setEnabled(partsMask & ConditionPart);
170     m_ui.lineEditThreadSpec->setEnabled(partsMask & ConditionPart);
171 }
172
173 void BreakpointDialog::clearOtherParts(unsigned partsMask)
174 {
175     partsMask = ~partsMask;
176     if (partsMask & FileAndLinePart) {
177         m_ui.pathChooserFileName->setPath(QString());
178         m_ui.lineEditLineNumber->clear();
179         m_ui.checkBoxUseFullPath->setChecked(false);
180     }
181
182     if (partsMask & FunctionPart)
183         m_ui.lineEditFunction->clear();
184
185     if (partsMask & AddressPart)
186         m_ui.lineEditAddress->clear();
187
188     if (partsMask & ConditionPart) {
189         m_ui.lineEditCondition->setText(QString());
190         m_ui.lineEditIgnoreCount->setText(QString());
191         m_ui.lineEditThreadSpec->setText(QString());
192     }
193 }
194
195 void BreakpointDialog::getParts(unsigned partsMask, BreakpointParameters *data) const
196 {
197     data->enabled = m_ui.checkBoxEnabled->isChecked();
198     data->tracepoint = m_ui.checkBoxTracepoint->isChecked();
199
200     if (partsMask & FileAndLinePart) {
201         data->lineNumber = m_ui.lineEditLineNumber->text().toInt();
202         data->useFullPath = m_ui.checkBoxUseFullPath->isChecked();
203         data->fileName = m_ui.pathChooserFileName->path();
204     }
205     if (partsMask & FunctionPart)
206         data->functionName = m_ui.lineEditFunction->text();
207
208     if (partsMask & AddressPart)
209         data->address = m_ui.lineEditAddress->text().toULongLong(0, 0);
210
211     if (partsMask & ConditionPart) {
212         data->condition = m_ui.lineEditCondition->text().toUtf8();
213         data->ignoreCount = m_ui.lineEditIgnoreCount->text().toInt();
214         data->threadSpec =
215             BreakHandler::threadSpecFromDisplay(m_ui.lineEditThreadSpec->text());
216     }
217 }
218
219 void BreakpointDialog::setParts(unsigned mask, const BreakpointParameters &data)
220 {
221     m_ui.checkBoxEnabled->setChecked(data.enabled);
222     m_ui.checkBoxUseFullPath->setChecked(data.useFullPath);
223
224     if (mask & FileAndLinePart) {
225         m_ui.pathChooserFileName->setPath(data.fileName);
226         m_ui.lineEditLineNumber->setText(QString::number(data.lineNumber));
227         m_ui.checkBoxTracepoint->setChecked(data.tracepoint);
228     }
229
230     if (mask & FunctionPart)
231         m_ui.lineEditFunction->setText(data.functionName);
232
233     if (mask & AddressPart) {
234         if (data.address) {
235             m_ui.lineEditAddress->setText(
236                 QString::fromAscii("0x%1").arg(data.address, 0, 16));
237         } else {
238             m_ui.lineEditAddress->clear();
239         }
240     }
241
242     if (mask & ConditionPart) {
243         m_ui.lineEditCondition->setText(QString::fromUtf8(data.condition));
244         m_ui.lineEditIgnoreCount->setText(QString::number(data.ignoreCount));
245         m_ui.lineEditThreadSpec->
246             setText(BreakHandler::displayFromThreadSpec(data.threadSpec));
247     }
248 }
249
250 void BreakpointDialog::typeChanged(int)
251 {
252     BreakpointType previousType = m_previousType;
253     const BreakpointType newType = type();
254     m_previousType = newType;
255     // Save current state.
256     switch(previousType) {
257     case UnknownType:
258         break;
259     case BreakpointByFileAndLine:
260         getParts(FileAndLinePart, &m_savedParameters);
261         break;
262     case BreakpointByFunction:
263         getParts(FunctionPart, &m_savedParameters);
264         break;
265     case BreakpointAtThrow:
266     case BreakpointAtCatch:
267     case BreakpointAtMain:
268         break;
269     case BreakpointByAddress:
270     case Watchpoint:
271         getParts(AddressPart, &m_savedParameters);
272         break;
273     }
274
275     // Enable and set up new state from saved values.
276     switch (newType) {
277     case UnknownType:
278         break;
279     case BreakpointByFileAndLine:
280         setParts(FileAndLinePart|ConditionPart, m_savedParameters);
281         setPartsEnabled(FileAndLinePart|ConditionPart);
282         clearOtherParts(FileAndLinePart|ConditionPart);
283         break;
284     case BreakpointByFunction:
285         setParts(FunctionPart|ConditionPart, m_savedParameters);
286         setPartsEnabled(FunctionPart|ConditionPart);
287         clearOtherParts(FunctionPart|ConditionPart);
288         break;
289     case BreakpointAtThrow:
290     case BreakpointAtCatch:
291         clearOtherParts(ConditionPart);
292         setPartsEnabled(ConditionPart);
293         break;
294     case BreakpointAtMain:
295         m_ui.lineEditFunction->setText(QLatin1String("main")); // Just for display
296         clearOtherParts(0);
297         setPartsEnabled(0);
298         break;
299     case BreakpointByAddress:
300     case Watchpoint:
301         setParts(AddressPart|ConditionPart, m_savedParameters);
302         setPartsEnabled(AddressPart|ConditionPart);
303         clearOtherParts(AddressPart|ConditionPart);
304         break;
305     }
306 }
307
308 bool BreakpointDialog::showDialog(BreakpointParameters *data)
309 {
310     setParameters(*data);
311     if (exec() != QDialog::Accepted)
312         return false;
313
314     // Check if changed.
315     const BreakpointParameters newParameters = parameters();
316     if (data->equals(newParameters))
317         return false;
318
319     *data = newParameters;
320     return true;
321 }
322
323
324 ///////////////////////////////////////////////////////////////////////
325 //
326 // BreakWindow
327 //
328 ///////////////////////////////////////////////////////////////////////
329
330 BreakWindow::BreakWindow(QWidget *parent)
331   : QTreeView(parent)
332 {
333     m_alwaysResizeColumnsToContents = false;
334
335     QAction *act = debuggerCore()->action(UseAlternatingRowColors);
336     setFrameStyle(QFrame::NoFrame);
337     setAttribute(Qt::WA_MacShowFocusRect, false);
338     setWindowTitle(tr("Breakpoints"));
339     setWindowIcon(QIcon(QLatin1String(":/debugger/images/debugger_breakpoints.png")));
340     setAlternatingRowColors(act->isChecked());
341     setRootIsDecorated(false);
342     setIconSize(QSize(10, 10));
343     setSelectionMode(QAbstractItemView::ExtendedSelection);
344
345     connect(this, SIGNAL(activated(QModelIndex)),
346         SLOT(rowActivated(QModelIndex)));
347     connect(act, SIGNAL(toggled(bool)),
348         SLOT(setAlternatingRowColorsHelper(bool)));
349     connect(debuggerCore()->action(UseAddressInBreakpointsView),
350         SIGNAL(toggled(bool)),
351         SLOT(showAddressColumn(bool)));
352 }
353
354 void BreakWindow::showAddressColumn(bool on)
355 {
356     setColumnHidden(7, !on);
357 }
358
359 void BreakWindow::keyPressEvent(QKeyEvent *ev)
360 {
361     if (ev->key() == Qt::Key_Delete) {
362         QItemSelectionModel *sm = selectionModel();
363         QTC_ASSERT(sm, return);
364         QModelIndexList si = sm->selectedIndexes();
365         if (si.isEmpty())
366             si.append(currentIndex());
367         const BreakpointIds ids = breakHandler()->findBreakpointsByIndex(si);
368         int row = qMin(model()->rowCount() - ids.size() - 1, currentIndex().row());
369         deleteBreakpoints(ids);
370         setCurrentIndex(si.at(0).sibling(row, 0));
371     }
372     QTreeView::keyPressEvent(ev);
373 }
374
375 void BreakWindow::resizeEvent(QResizeEvent *ev)
376 {
377     QTreeView::resizeEvent(ev);
378 }
379
380 void BreakWindow::mouseDoubleClickEvent(QMouseEvent *ev)
381 {
382     QModelIndex indexUnderMouse = indexAt(ev->pos());
383     if (indexUnderMouse.isValid() && indexUnderMouse.column() >= 4) {
384         BreakpointId id = breakHandler()->findBreakpointByIndex(indexUnderMouse);
385         editBreakpoints(BreakpointIds() << id);
386     }
387     QTreeView::mouseDoubleClickEvent(ev);
388 }
389
390 void BreakWindow::setModel(QAbstractItemModel *model)
391 {
392     QTreeView::setModel(model);
393     resizeColumnToContents(0); // Number
394     resizeColumnToContents(3); // Line
395     resizeColumnToContents(6); // Ignore count
396 }
397
398 void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
399 {
400     QMenu menu;
401     QItemSelectionModel *sm = selectionModel();
402     QTC_ASSERT(sm, return);
403     QModelIndexList selectedIndices = sm->selectedIndexes();
404     QModelIndex indexUnderMouse = indexAt(ev->pos());
405     if (selectedIndices.isEmpty() && indexUnderMouse.isValid())
406         selectedIndices.append(indexUnderMouse);
407
408     BreakHandler *handler = breakHandler();
409     BreakpointIds selectedIds = handler->findBreakpointsByIndex(selectedIndices);
410
411     const int rowCount = model()->rowCount();
412     const unsigned engineCapabilities = BreakOnThrowAndCatchCapability;
413     // FIXME BP: model()->data(QModelIndex(), EngineCapabilitiesRole).toUInt();
414
415     QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu);
416     deleteAction->setEnabled(!selectedIds.isEmpty());
417
418     QAction *deleteAllAction = new QAction(tr("Delete All Breakpoints"), &menu);
419     deleteAllAction->setEnabled(model()->rowCount() > 0);
420
421     // Delete by file: Find indices of breakpoints of the same file.
422     QAction *deleteByFileAction = 0;
423     BreakpointIds breakpointsInFile;
424     if (indexUnderMouse.isValid()) {
425         const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2);
426         const QString file = index.data().toString();
427         if (!file.isEmpty()) {
428             for (int i = 0; i < rowCount; i++)
429                 if (index.data().toString() == file)
430                     breakpointsInFile.append(handler->findBreakpointByIndex(index));
431             if (breakpointsInFile.size() > 1) {
432                 deleteByFileAction =
433                     new QAction(tr("Delete Breakpoints of \"%1\"").arg(file), &menu);
434                 deleteByFileAction->setEnabled(true);
435             }
436         }
437     }
438     if (!deleteByFileAction) {
439         deleteByFileAction = new QAction(tr("Delete Breakpoints of File"), &menu);
440         deleteByFileAction->setEnabled(false);
441     }
442
443     QAction *adjustColumnAction =
444         new QAction(tr("Adjust Column Widths to Contents"), &menu);
445
446     QAction *alwaysAdjustAction =
447         new QAction(tr("Always Adjust Column Widths to Contents"), &menu);
448
449     alwaysAdjustAction->setCheckable(true);
450     alwaysAdjustAction->setChecked(m_alwaysResizeColumnsToContents);
451
452     QAction *editBreakpointAction =
453         new QAction(tr("Edit Breakpoint..."), &menu);
454     editBreakpointAction->setEnabled(!selectedIds.isEmpty());
455
456     int threadId = 0;
457     // FIXME BP: m_engine->threadsHandler()->currentThreadId();
458     QString associateTitle = threadId == -1
459         ?  tr("Associate Breakpoint With All Threads")
460         :  tr("Associate Breakpoint With Thread %1").arg(threadId);
461     QAction *associateBreakpointAction = new QAction(associateTitle, &menu);
462     associateBreakpointAction->setEnabled(!selectedIds.isEmpty());
463
464     QAction *synchronizeAction =
465         new QAction(tr("Synchronize Breakpoints"), &menu);
466     synchronizeAction->setEnabled(debuggerCore()->hasSnapshots());
467
468     bool enabled = selectedIds.isEmpty() || handler->isEnabled(selectedIds.at(0));
469
470     const QString str5 = selectedIds.size() > 1
471         ? enabled
472             ? tr("Disable Selected Breakpoints")
473             : tr("Enable Selected Breakpoints")
474         : enabled
475             ? tr("Disable Breakpoint")
476             : tr("Enable Breakpoint");
477     QAction *toggleEnabledAction = new QAction(str5, &menu);
478     toggleEnabledAction->setEnabled(!selectedIds.isEmpty());
479
480     QAction *addBreakpointAction =
481         new QAction(tr("Add Breakpoint..."), this);
482     QAction *breakAtThrowAction =
483         new QAction(tr("Set Breakpoint at \"throw\""), this);
484     QAction *breakAtCatchAction =
485         new QAction(tr("Set Breakpoint at \"catch\""), this);
486
487     menu.addAction(addBreakpointAction);
488     menu.addAction(deleteAction);
489     menu.addAction(editBreakpointAction);
490     menu.addAction(associateBreakpointAction);
491     menu.addAction(toggleEnabledAction);
492     menu.addSeparator();
493     menu.addAction(deleteAllAction);
494     //menu.addAction(deleteByFileAction);
495     menu.addSeparator();
496     menu.addAction(synchronizeAction);
497     if (engineCapabilities & BreakOnThrowAndCatchCapability) {
498         menu.addSeparator();
499         menu.addAction(breakAtThrowAction);
500         menu.addAction(breakAtCatchAction);
501     }
502     menu.addSeparator();
503     menu.addAction(debuggerCore()->action(UseToolTipsInBreakpointsView));
504     menu.addAction(debuggerCore()->action(UseAddressInBreakpointsView));
505     menu.addAction(adjustColumnAction);
506     menu.addAction(alwaysAdjustAction);
507     menu.addSeparator();
508     menu.addAction(debuggerCore()->action(SettingsDialog));
509
510     QAction *act = menu.exec(ev->globalPos());
511
512     if (act == deleteAction)
513         deleteBreakpoints(selectedIds);
514     else if (act == deleteAllAction)
515         deleteBreakpoints(handler->allBreakpointIds());
516     else if (act == deleteByFileAction)
517         deleteBreakpoints(breakpointsInFile);
518     else if (act == adjustColumnAction)
519         resizeColumnsToContents();
520     else if (act == alwaysAdjustAction)
521         setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
522     else if (act == editBreakpointAction)
523         editBreakpoints(selectedIds);
524     else if (act == associateBreakpointAction)
525         associateBreakpoint(selectedIds, threadId);
526     else if (act == synchronizeAction)
527         ; //synchronizeBreakpoints();
528     else if (act == toggleEnabledAction)
529         setBreakpointsEnabled(selectedIds, !enabled);
530     else if (act == addBreakpointAction)
531         addBreakpoint();
532     else if (act == breakAtThrowAction)
533         handler->appendBreakpoint(BreakpointParameters(BreakpointAtThrow));
534     else if (act == breakAtCatchAction)
535         handler->appendBreakpoint(BreakpointParameters(BreakpointAtCatch));
536 }
537
538 void BreakWindow::setBreakpointsEnabled(const BreakpointIds &ids, bool enabled)
539 {
540     BreakHandler *handler = breakHandler();
541     foreach (const BreakpointId id, ids)
542         handler->setEnabled(id, enabled);
543 }
544
545 void BreakWindow::deleteBreakpoints(const BreakpointIds &ids)
546 {
547     BreakHandler *handler = breakHandler();
548     foreach (const BreakpointId id, ids)
549        handler->removeBreakpoint(id);
550 }
551
552 void BreakWindow::editBreakpoint(BreakpointId id, QWidget *parent)
553 {
554     BreakpointDialog dialog(parent);
555     BreakpointParameters data = breakHandler()->breakpointData(id);
556     if (dialog.showDialog(&data))
557         breakHandler()->setBreakpointData(id, data);
558 }
559
560 void BreakWindow::addBreakpoint()
561 {
562     BreakpointParameters data(BreakpointByFileAndLine);
563     BreakpointDialog dialog(this);
564     if (dialog.showDialog(&data))
565         breakHandler()->appendBreakpoint(data);
566 }
567
568 void BreakWindow::editBreakpoints(const BreakpointIds &ids)
569 {
570     QTC_ASSERT(!ids.isEmpty(), return);
571
572     const BreakpointId id = ids.at(0);
573
574     if (ids.size() == 1) {
575         editBreakpoint(id, this);
576         return;
577     }
578
579     // This allows to change properties of multiple breakpoints at a time.
580     QDialog dlg(this);
581     Ui::BreakCondition ui;
582     ui.setupUi(&dlg);
583     dlg.setWindowTitle(tr("Edit Breakpoint Properties"));
584     ui.lineEditIgnoreCount->setValidator(
585         new QIntValidator(0, 2147483647, ui.lineEditIgnoreCount));
586
587     BreakHandler *handler = breakHandler();
588     const QString oldCondition = QString::fromLatin1(handler->condition(id));
589     const QString oldIgnoreCount = QString::number(handler->ignoreCount(id));
590     const QString oldThreadSpec =
591         BreakHandler::displayFromThreadSpec(handler->threadSpec(id));
592
593     ui.lineEditCondition->setText(oldCondition);
594     ui.lineEditIgnoreCount->setText(oldIgnoreCount);
595     ui.lineEditThreadSpec->setText(oldThreadSpec);
596
597     if (dlg.exec() == QDialog::Rejected)
598         return;
599
600     const QString newCondition = ui.lineEditCondition->text();
601     const QString newIgnoreCount = ui.lineEditIgnoreCount->text();
602     const QString newThreadSpec = ui.lineEditThreadSpec->text();
603
604     if (newCondition == oldCondition && newIgnoreCount == oldIgnoreCount
605             && newThreadSpec == oldThreadSpec)
606         return;
607
608     foreach (const BreakpointId id, ids) {
609         handler->setCondition(id, newCondition.toLatin1());
610         handler->setIgnoreCount(id, newIgnoreCount.toInt());
611         handler->setThreadSpec(id,
612             BreakHandler::threadSpecFromDisplay(newThreadSpec));
613     }
614 }
615
616 void BreakWindow::associateBreakpoint(const BreakpointIds &ids, int threadId)
617 {
618     BreakHandler *handler = breakHandler();
619     foreach (const BreakpointId id, ids)
620         handler->setThreadSpec(id, threadId);
621 }
622
623 void BreakWindow::resizeColumnsToContents()
624 {
625     for (int i = model()->columnCount(); --i >= 0; )
626         resizeColumnToContents(i);
627 }
628
629 void BreakWindow::setAlwaysResizeColumnsToContents(bool on)
630 {
631     m_alwaysResizeColumnsToContents = on;
632     QHeaderView::ResizeMode mode = on
633         ? QHeaderView::ResizeToContents : QHeaderView::Interactive;
634     for (int i = model()->columnCount(); --i >= 0; )
635         header()->setResizeMode(i, mode);
636 }
637
638 void BreakWindow::rowActivated(const QModelIndex &index)
639 {
640     breakHandler()->gotoLocation(breakHandler()->findBreakpointByIndex(index));
641 }
642
643 } // namespace Internal
644 } // namespace Debugger
645
646 #include "breakwindow.moc"