1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the examples of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:BSD$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** BSD License Usage |
18 | ** Alternatively, you may use this file under the terms of the BSD license |
19 | ** as follows: |
20 | ** |
21 | ** "Redistribution and use in source and binary forms, with or without |
22 | ** modification, are permitted provided that the following conditions are |
23 | ** met: |
24 | ** * Redistributions of source code must retain the above copyright |
25 | ** notice, this list of conditions and the following disclaimer. |
26 | ** * Redistributions in binary form must reproduce the above copyright |
27 | ** notice, this list of conditions and the following disclaimer in |
28 | ** the documentation and/or other materials provided with the |
29 | ** distribution. |
30 | ** * Neither the name of The Qt Company Ltd nor the names of its |
31 | ** contributors may be used to endorse or promote products derived |
32 | ** from this software without specific prior written permission. |
33 | ** |
34 | ** |
35 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
36 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
37 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
38 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
39 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
40 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
41 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
42 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
43 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
44 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
45 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
46 | ** |
47 | ** $QT_END_LICENSE$ |
48 | ** |
49 | ****************************************************************************/ |
50 | |
51 | #include "mainwindow.h" |
52 | #include "treemodel.h" |
53 | |
54 | #include <QFile> |
55 | |
56 | MainWindow::MainWindow(QWidget *parent) |
57 | : QMainWindow(parent) |
58 | { |
59 | setupUi(this); |
60 | |
61 | const QStringList ({tr(s: "Title" ), tr(s: "Description" )}); |
62 | |
63 | QFile file(":/default.txt" ); |
64 | file.open(flags: QIODevice::ReadOnly); |
65 | TreeModel *model = new TreeModel(headers, file.readAll(), this); |
66 | file.close(); |
67 | |
68 | view->setModel(model); |
69 | for (int column = 0; column < model->columnCount(); ++column) |
70 | view->resizeColumnToContents(column); |
71 | |
72 | connect(sender: exitAction, signal: &QAction::triggered, qApp, slot: &QCoreApplication::quit); |
73 | |
74 | connect(sender: view->selectionModel(), signal: &QItemSelectionModel::selectionChanged, |
75 | receiver: this, slot: &MainWindow::updateActions); |
76 | |
77 | connect(sender: actionsMenu, signal: &QMenu::aboutToShow, receiver: this, slot: &MainWindow::updateActions); |
78 | connect(sender: insertRowAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::insertRow); |
79 | connect(sender: insertColumnAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::insertColumn); |
80 | connect(sender: removeRowAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::removeRow); |
81 | connect(sender: removeColumnAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::removeColumn); |
82 | connect(sender: insertChildAction, signal: &QAction::triggered, receiver: this, slot: &MainWindow::insertChild); |
83 | |
84 | updateActions(); |
85 | } |
86 | |
87 | void MainWindow::insertChild() |
88 | { |
89 | const QModelIndex index = view->selectionModel()->currentIndex(); |
90 | QAbstractItemModel *model = view->model(); |
91 | |
92 | if (model->columnCount(parent: index) == 0) { |
93 | if (!model->insertColumn(acolumn: 0, aparent: index)) |
94 | return; |
95 | } |
96 | |
97 | if (!model->insertRow(arow: 0, aparent: index)) |
98 | return; |
99 | |
100 | for (int column = 0; column < model->columnCount(parent: index); ++column) { |
101 | const QModelIndex child = model->index(row: 0, column, parent: index); |
102 | model->setData(index: child, value: QVariant(tr(s: "[No data]" )), role: Qt::EditRole); |
103 | if (!model->headerData(section: column, orientation: Qt::Horizontal).isValid()) |
104 | model->setHeaderData(section: column, orientation: Qt::Horizontal, value: QVariant(tr(s: "[No header]" )), role: Qt::EditRole); |
105 | } |
106 | |
107 | view->selectionModel()->setCurrentIndex(index: model->index(row: 0, column: 0, parent: index), |
108 | command: QItemSelectionModel::ClearAndSelect); |
109 | updateActions(); |
110 | } |
111 | |
112 | bool MainWindow::insertColumn() |
113 | { |
114 | QAbstractItemModel *model = view->model(); |
115 | int column = view->selectionModel()->currentIndex().column(); |
116 | |
117 | // Insert a column in the parent item. |
118 | bool changed = model->insertColumn(acolumn: column + 1); |
119 | if (changed) |
120 | model->setHeaderData(section: column + 1, orientation: Qt::Horizontal, value: QVariant("[No header]" ), role: Qt::EditRole); |
121 | |
122 | updateActions(); |
123 | |
124 | return changed; |
125 | } |
126 | |
127 | void MainWindow::insertRow() |
128 | { |
129 | const QModelIndex index = view->selectionModel()->currentIndex(); |
130 | QAbstractItemModel *model = view->model(); |
131 | |
132 | if (!model->insertRow(arow: index.row()+1, aparent: index.parent())) |
133 | return; |
134 | |
135 | updateActions(); |
136 | |
137 | for (int column = 0; column < model->columnCount(parent: index.parent()); ++column) { |
138 | const QModelIndex child = model->index(row: index.row() + 1, column, parent: index.parent()); |
139 | model->setData(index: child, value: QVariant(tr(s: "[No data]" )), role: Qt::EditRole); |
140 | } |
141 | } |
142 | |
143 | bool MainWindow::removeColumn() |
144 | { |
145 | QAbstractItemModel *model = view->model(); |
146 | const int column = view->selectionModel()->currentIndex().column(); |
147 | |
148 | // Insert columns in each child of the parent item. |
149 | const bool changed = model->removeColumn(acolumn: column); |
150 | if (changed) |
151 | updateActions(); |
152 | |
153 | return changed; |
154 | } |
155 | |
156 | void MainWindow::removeRow() |
157 | { |
158 | const QModelIndex index = view->selectionModel()->currentIndex(); |
159 | QAbstractItemModel *model = view->model(); |
160 | if (model->removeRow(arow: index.row(), aparent: index.parent())) |
161 | updateActions(); |
162 | } |
163 | |
164 | void MainWindow::updateActions() |
165 | { |
166 | const bool hasSelection = !view->selectionModel()->selection().isEmpty(); |
167 | removeRowAction->setEnabled(hasSelection); |
168 | removeColumnAction->setEnabled(hasSelection); |
169 | |
170 | const bool hasCurrent = view->selectionModel()->currentIndex().isValid(); |
171 | insertRowAction->setEnabled(hasCurrent); |
172 | insertColumnAction->setEnabled(hasCurrent); |
173 | |
174 | if (hasCurrent) { |
175 | view->closePersistentEditor(index: view->selectionModel()->currentIndex()); |
176 | |
177 | const int row = view->selectionModel()->currentIndex().row(); |
178 | const int column = view->selectionModel()->currentIndex().column(); |
179 | if (view->selectionModel()->currentIndex().parent().isValid()) |
180 | statusBar()->showMessage(text: tr(s: "Position: (%1,%2)" ).arg(a: row).arg(a: column)); |
181 | else |
182 | statusBar()->showMessage(text: tr(s: "Position: (%1,%2) in top level" ).arg(a: row).arg(a: column)); |
183 | } |
184 | } |
185 | |