26 #include <QApplication>
28 #include <QContextMenuEvent>
29 #include <QDragEnterEvent>
30 #include <QHeaderView>
40 m_only_edit_data =
false;
43 setUniformRowHeights(
true);
46 setDragDropMode(QAbstractItemView::DragDrop);
47 setDropIndicatorShown(
true);
48 setDefaultDropAction(Qt::MoveAction);
51 setEditTriggers(DoubleClicked | AnyKeyPressed);
56 m_action_undo =
new QAction(QIcon::fromTheme(
"edit-undo"),
"&Undo",
this);
57 m_action_redo =
new QAction(QIcon::fromTheme(
"edit-redo"),
"&Redo",
this);
58 m_action_cut =
new QAction(QIcon::fromTheme(
"edit-cut"),
"Cut",
this);
59 m_action_copy =
new QAction(QIcon::fromTheme(
"edit-copy"),
"Copy",
this);
60 m_action_paste =
new QAction(QIcon::fromTheme(
"edit-paste"),
"&Paste",
this);
61 m_action_move_up =
new QAction(QIcon::fromTheme(
"go-up"),
"Move Up",
this);
62 m_action_move_down =
new QAction(QIcon::fromTheme(
"go-down"),
"Move Down",
this);
63 m_action_insert =
new QAction(QIcon::fromTheme(
"list-add"),
"Insert",
this);
64 m_action_insert_child =
new QAction(QIcon::fromTheme(
"list-add"),
"Insert Child",
this);
65 m_action_remove =
new QAction(QIcon::fromTheme(
"list-remove"),
"Remove",
this);
66 m_action_find_dialog =
new QAction(QIcon::fromTheme(
"edit-find"),
"&Find...",
this);
67 m_action_clear_highlight =
new QAction(QIcon::fromTheme(
"edit-clear"),
"&Clear Highlight",
this);
68 m_action_expand_all =
new QAction(QIcon::fromTheme(
"list-add"),
"Expand All",
this);
69 m_action_expand_none =
new QAction(QIcon::fromTheme(
"list-remove"),
"Expand None",
this);
71 m_action_undo->setShortcut(QKeySequence(
"Ctrl+Z"));
72 m_action_undo->setShortcutContext(Qt::WidgetShortcut);
73 m_action_undo->setEnabled(
false);
74 m_action_redo->setShortcut(QKeySequence(
"Shift+Ctrl+Z"));
75 m_action_redo->setShortcutContext(Qt::WidgetShortcut);
76 m_action_redo->setEnabled(
false);
77 m_action_cut->setShortcut(QKeySequence(
"Ctrl+X"));
78 m_action_cut->setShortcutContext(Qt::WidgetShortcut);
79 m_action_cut->setEnabled(
false);
80 m_action_copy->setShortcut(QKeySequence(
"Ctrl+C"));
81 m_action_copy->setShortcutContext(Qt::WidgetShortcut);
82 m_action_copy->setEnabled(
false);
83 m_action_paste->setShortcut(QKeySequence(
"Ctrl+V"));
84 m_action_paste->setShortcutContext(Qt::WidgetShortcut);
85 m_action_paste->setEnabled(
false);
86 m_action_move_up->setEnabled(
false);
87 m_action_move_down->setEnabled(
false);
88 m_action_insert->setEnabled(
false);
89 m_action_insert_child->setEnabled(
false);
90 m_action_remove->setShortcut(QKeySequence(
"Del"));
91 m_action_remove->setShortcutContext(Qt::WidgetShortcut);
92 m_action_remove->setEnabled(
false);
93 m_action_find_dialog->setShortcut(QKeySequence(
"Ctrl+F"));
94 m_action_find_dialog->setShortcutContext(Qt::WidgetShortcut);
97 addAction(m_action_undo);
98 addAction(m_action_redo);
99 addAction(m_action_cut);
100 addAction(m_action_copy);
101 addAction(m_action_paste);
102 addAction(m_action_move_up);
103 addAction(m_action_move_down);
104 addAction(m_action_insert);
105 addAction(m_action_insert_child);
106 addAction(m_action_remove);
107 addAction(m_action_find_dialog);
108 addAction(m_action_clear_highlight);
110 connect(&m_undo_stack, SIGNAL(canUndoChanged(
bool)), m_action_undo, SLOT(setEnabled(
bool)));
111 connect(&m_undo_stack, SIGNAL(canRedoChanged(
bool)), m_action_redo, SLOT(setEnabled(
bool)));
112 connect(&m_undo_stack, SIGNAL(cleanChanged(
bool)),
this, SIGNAL(
CleanChanged(
bool)));
113 connect(&m_undo_stack, SIGNAL(indexChanged(
int)),
this, SIGNAL(
Edited()));
114 connect(m_action_undo, SIGNAL(triggered()), &m_undo_stack, SLOT(undo()));
115 connect(m_action_redo, SIGNAL(triggered()), &m_undo_stack, SLOT(redo()));
116 connect(m_action_cut, SIGNAL(triggered()),
this, SLOT(Cut()));
117 connect(m_action_copy, SIGNAL(triggered()),
this, SLOT(Copy()));
118 connect(m_action_paste, SIGNAL(triggered()),
this, SLOT(Paste()));
119 connect(m_action_move_up, SIGNAL(triggered()),
this, SLOT(MoveUp()));
120 connect(m_action_move_down, SIGNAL(triggered()),
this, SLOT(MoveDown()));
121 connect(m_action_insert, SIGNAL(triggered()),
this, SLOT(Insert()));
122 connect(m_action_insert_child, SIGNAL(triggered()),
this, SLOT(InsertChild()));
123 connect(m_action_remove, SIGNAL(triggered()),
this, SLOT(Remove()));
124 connect(m_action_find_dialog, SIGNAL(triggered()),
this, SLOT(FindDialog()));
125 connect(m_action_clear_highlight, SIGNAL(triggered()),
this, SLOT(ClearHighlight()));
126 connect(m_action_expand_all, SIGNAL(triggered()),
this, SLOT(expandAll()));
127 connect(m_action_expand_none, SIGNAL(triggered()),
this, SLOT(collapseAll()));
130 QClipboard* clipboard = QApplication::clipboard();
131 connect(clipboard, SIGNAL(dataChanged()),
this, SLOT(SetClipboardChanged()));
137 void PTreeView::ClearHighlight()
142 for (QModelIndexList::iterator i = m_results.begin(); i != m_results.end(); i++) {
143 model()->setData(*i, QVariant(), Qt::BackgroundRole);
147 m_result = m_results.end();
148 m_action_clear_highlight->setEnabled(
false);
154 menu.addAction(m_action_insert);
155 menu.addAction(m_action_insert_child);
157 menu.addAction(m_action_move_up);
158 menu.addAction(m_action_move_down);
160 menu.addAction(m_action_remove);
162 menu.addAction(m_action_cut);
163 menu.addAction(m_action_copy);
164 menu.addAction(m_action_paste);
165 menu.exec(event->globalPos());
168 void PTreeView::Copy()
171 QModelIndexList indexes = selectedIndexes();
172 if (indexes.empty()) {
175 QMimeData* mime = model()->mimeData(indexes);
176 QClipboard* clipboard = QApplication::clipboard();
177 clipboard->setMimeData(mime);
182 void PTreeView::Cut()
188 QModelIndexList indexes = selectedIndexes();
189 if (indexes.empty()) {
193 QModelIndex
const & index = indexes.first();
194 model()->removeRow(index.row(), model()->parent(index));
195 selectionModel()->clearSelection();
196 selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Clear);
199 void PTreeView::FindDialog()
201 if (!m_find_dialog) {
202 m_find_dialog =
new MyFindDialog(
this);
203 connect(m_find_dialog, SIGNAL(FindNext(QString
const &,
bool)),
204 this, SLOT(FindNext(QString
const &,
bool)));
206 m_find_dialog->show();
207 m_find_dialog->raise();
208 m_find_dialog->activateWindow();
212 void PTreeView::FindNext(QString
const & new_query,
bool match_case)
217 Qt::MatchFlags new_flags = Qt::MatchContains | Qt::MatchWrap | Qt::MatchRecursive;
219 new_flags |= Qt::MatchCaseSensitive;
221 if (new_query == m_query && new_flags == m_flags && m_result != m_results.end()) {
223 if (++m_result == m_results.end()) {
224 m_result = m_results.begin();
228 for (QModelIndexList::iterator i = m_results.begin(); i != m_results.end(); i++) {
229 model()->setData(*i, QVariant(), Qt::BackgroundRole);
231 if (new_query ==
"") {
234 m_results = model()->match(model()->index(0, 0),
235 Qt::DisplayRole, QVariant(new_query), -1, new_flags);
237 m_result = m_results.begin();
243 for (QModelIndexList::iterator i = m_results.begin(); i != m_results.end(); ++i) {
244 model()->setData(*i, QVariant(QBrush(QColor(255, 255, 0))), Qt::BackgroundRole);
248 if (m_results.size() == 1) {
249 emit
StatusChanged(QString::number(m_results.size()) +
" result found");
251 emit
StatusChanged(QString::number(m_results.size()) +
" results found");
254 if (m_result != m_results.end()) {
255 selectionModel()->select(*m_result, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
257 m_action_clear_highlight->setEnabled(
true);
259 m_action_clear_highlight->setEnabled(
false);
263 QAction* PTreeView::GetUndoAction()
const {
return m_action_undo;}
264 QAction* PTreeView::GetRedoAction()
const {
return m_action_redo;}
265 QAction* PTreeView::GetCutAction()
const {
return m_action_cut;}
266 QAction* PTreeView::GetCopyAction()
const {
return m_action_copy;}
267 QAction* PTreeView::GetPasteAction()
const {
return m_action_paste;}
268 QAction* PTreeView::GetMoveUpAction()
const {
return m_action_move_up;}
269 QAction* PTreeView::GetMoveDownAction()
const {
return m_action_move_down;}
270 QAction* PTreeView::GetInsertBeforeAction()
const {
return m_action_insert;}
271 QAction* PTreeView::GetInsertChildAction()
const {
return m_action_insert_child;}
272 QAction* PTreeView::GetRemoveAction()
const {
return m_action_remove;}
273 QAction* PTreeView::GetFindDialogAction()
const {
return m_action_find_dialog;}
274 QAction* PTreeView::GetClearHighlightAction()
const {
return m_action_clear_highlight;}
275 QAction* PTreeView::GetExpandAllAction()
const {
return m_action_expand_all;}
276 QAction* PTreeView::GetExpandNoneAction()
const {
return m_action_expand_none;}
279 void PTreeView::Insert()
281 QModelIndexList list = selectedIndexes();
283 for (
auto const & i : list) {
284 if (i.column() == 0) {
285 QModelIndex parent = model()->parent(i);
286 model()->insertRow(i.row(), parent);
287 QModelIndex inserted = model()->index(i.row(), 0, parent);
288 selectionModel()->select(inserted, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
289 selectionModel()->setCurrentIndex(inserted, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
293 model()->insertRow(0);
294 QModelIndex inserted = model()->index(0, 0);
295 selectionModel()->select(inserted, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
296 selectionModel()->setCurrentIndex(inserted, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
300 void PTreeView::InsertChild()
302 for (
auto const & i : selectedIndexes()) {
303 if (i.column() == 0) {
304 model()->insertRow(0, i);
311 return m_undo_stack.isClean();
314 bool PTreeView::IsOnlyEditData()
const
316 return m_only_edit_data;
319 void PTreeView::MoveDown()
321 for (
auto const & i : selectedIndexes()) {
322 if (i.column() == 0) {
323 if (PTreeModel* ptree_model = dynamic_cast<PTreeModel*>(model())) {
325 QModelIndex parent = ptree_model->parent(i);
326 ptree_model->MoveRow(row, parent, row+1, parent);
327 QModelIndex moved = ptree_model->index(row+1, 0, parent);
328 selectionModel()->select(moved, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
329 selectionModel()->setCurrentIndex(moved, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
335 void PTreeView::MoveUp()
337 for (
auto const & i : selectedIndexes()) {
338 if (i.column() == 0) {
339 if (PTreeModel* ptree_model = dynamic_cast<PTreeModel*>(model())) {
341 QModelIndex parent = ptree_model->parent(i);
342 ptree_model->MoveRow(row, parent, row-1, parent);
343 QModelIndex moved = ptree_model->index(row-1, 0, parent);
344 selectionModel()->select(moved, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
345 selectionModel()->setCurrentIndex(moved, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
351 void PTreeView::Paste()
354 QClipboard* clipboard = QApplication::clipboard();
355 QMimeData
const * mime = clipboard->mimeData();
357 QModelIndexList indexes = selectedIndexes();
358 if (indexes.empty()) {
360 model()->dropMimeData(mime, Qt::CopyAction, 0, 0, QModelIndex());
361 QModelIndex index = model()->index(0,0);
362 selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
363 selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
367 QModelIndex index = indexes.first();
368 model()->dropMimeData(mime, Qt::CopyAction, index.row(), index.column(), model()->parent(index));
369 selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
370 selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
376 void PTreeView::Remove()
378 for (
auto const & i : selectedIndexes()) {
379 if (i.column() == 0) {
380 model()->removeRow(i.row(), model()->parent(i));
383 selectionModel()->clearSelection();
384 selectionModel()->setCurrentIndex(QModelIndex(), QItemSelectionModel::Clear);
389 m_undo_stack.setClean();
392 void PTreeView::SetClipboardChanged()
395 QClipboard
const * clipboard = QApplication::clipboard();
396 if (QMimeData
const * mime = clipboard->mimeData())
397 if (mime->hasFormat(
"text/plain")) {
398 m_action_paste->setEnabled(
true);
402 m_action_paste->setEnabled(
false);
407 m_undo_stack.clear();
408 MyTreeView::setModel(m);
411 if (
PTreeModel* ptree_model = dynamic_cast<PTreeModel*>(m)) {
413 ptree_model->SetUndoStack(&m_undo_stack);
416 QItemSelectionModel* s = selectionModel();
417 connect(s, SIGNAL(selectionChanged(
const QItemSelection &,
const QItemSelection &)),
this, SLOT(SetSelectionChanged(
const QItemSelection &,
const QItemSelection &)));
419 if (!m_only_edit_data) {
420 m_action_insert->setEnabled(
true);
423 m_action_insert->setEnabled(
false);
427 SetClipboardChanged();
430 SetSelectionChanged(QItemSelection(), QItemSelection());
433 m_action_clear_highlight->setEnabled(
false);
436 void PTreeView::SetOnlyEditData(
bool b)
438 m_only_edit_data = b;
439 if (m_only_edit_data) {
440 setDragDropMode (DragOnly);
442 setDragDropMode (DragDrop);
446 void PTreeView::SetSelectionChanged(QItemSelection
const &, QItemSelection
const &)
448 if (model() && !selectedIndexes().empty()) {
449 m_action_copy->setEnabled(
true);
450 if (!m_only_edit_data) {
451 m_action_cut->setEnabled(
true);
452 m_action_paste->setEnabled(
true);
453 m_action_move_up->setEnabled(
true);
454 m_action_move_down->setEnabled(
true);
455 m_action_insert_child->setEnabled(
true);
456 m_action_remove->setEnabled(
true);
458 m_action_cut->setEnabled(
false);
459 m_action_paste->setEnabled(
false);
460 m_action_move_up->setEnabled(
false);
461 m_action_move_down->setEnabled(
false);
462 m_action_insert_child->setEnabled(
false);
463 m_action_remove->setEnabled(
false);
466 m_action_cut->setEnabled(
false);
467 m_action_copy->setEnabled(
false);
468 m_action_paste->setEnabled(
false);
469 m_action_move_up->setEnabled(
false);
470 m_action_move_down->setEnabled(
false);
471 m_action_insert_child->setEnabled(
false);
472 m_action_remove->setEnabled(
false);
see the online Qt documentation
void CorrectFocus()
Sets focus to the text input box so the user can start typing right away.
PTreeView(QWidget *parent=0)
Constructor.
Interface for MyFindDialog.
void StatusChanged(QString const &message)
Emitted when view has some message to share with, for example, a statusbar.
bool IsClean() const
Test whether the view's internal undo stack is in a clean state.
virtual void setModel(QAbstractItemModel *model)
Reimplemented from QTreeView, also enables/disables certain actions.
Qt model reflecting hierarchical structure of a ptree.
virtual void contextMenuEvent(QContextMenuEvent *)
Reimplemented from QWidget.
see the online Qt documentation
void SetClean()
Set the view's internal undo stack's current state to be the clean state.
QTreeView with methods to import/export widget layout (x,y,width, ...) in ptree format.
see the online Qt documentation
Interface for PTreeModel.
void CleanChanged(bool clean)
Emitted whenever the view's internal undo stack state changes from clean to non-clean, or from non-clean to clean.
Namespace for generic graphical shell for simulators.
void Edited()
Emitted whenever the data contained in the model changes.