2 #include "mainwindow.h"
3 #include "ui_mainwindow.h"
4 #include "ui_workmodedialog.h"
6 MainWindow::MainWindow(QWidget
*parent
)
7 : QMainWindow(parent
), ui(new Ui::MainWindowClass
), model( this ), workModeDialog( this )
10 ui
->tabWidget
->removeTab( 0 );
11 ui
->searchLineEdit
->setFocus();
14 categoryIcon
.addPixmap( style()->standardPixmap( QStyle::SP_DirClosedIcon
), QIcon::Normal
, QIcon::Off
);
15 categoryIcon
.addPixmap( style()->standardPixmap( QStyle::SP_DirOpenIcon
), QIcon::Normal
, QIcon::On
);
16 snippetIcon
.addPixmap( style()->standardPixmap( QStyle::SP_FileIcon
) );
19 ui
->action_Save
->setEnabled( false );
20 ui
->actionSave_all
->setEnabled( false );
21 ui
->action_Close
->setEnabled( false );
22 ui
->actionClos_e_all
->setEnabled( false );
24 // load snippets from snippets.xml and set up view
26 ui
->snippetTreeView
->setModel( &model
);
27 ui
->snippetTreeView
->expandAll();
28 workModeDialog
.m_ui
->treeView
->expandAll();
31 connect( ui
->searchLineEdit
, SIGNAL( textChanged(QString
) ),
32 this, SLOT(on_searchLineEdit_textChanged(QString
)) );
33 connect( &model
, SIGNAL( itemChanged( QStandardItem
* ) ),
34 this, SLOT( updateSnippetsTitle( QStandardItem
* ) ) );
35 disconnect( ui
->descTextEdit
);
38 MainWindow::~MainWindow()
40 on_actionClos_e_all_activated();
45 void MainWindow::on_action_Category_activated() {
47 QString name
= QInputDialog::getText( this, tr( "New category..." ), tr( "Enter the new category name. "
48 "It will be added as a child of selected category." ),
49 QLineEdit::Normal
, "", &ok
);
51 if( ok
&& !name
.isEmpty() ) {
52 // check if snippet's not selected
53 QStandardItem
* parent
= model
.itemFromIndex( ui
->snippetTreeView
->currentIndex() );
54 Snippet
* snippet
= snippetForItem
.value( parent
);
57 parent
= model
.invisibleRootItem();
58 snippet
= snippetForItem
.value( parent
);
60 if( !snippet
->isCategory() )
61 parent
= parent
->parent();
64 QStandardItem
* item
= new QStandardItem( categoryIcon
, name
);
65 ui
->snippetTreeView
->setExpanded( parent
->index(), true );
66 snippetForItem
.insert( item
, new Snippet( name
, true ) );
67 insertItem( item
, parent
);
71 void MainWindow::on_action_Snippet_activated() {
73 QString name
= QInputDialog::getText( this, tr( "New snippet..." ), tr( "Enter the new snippet name. "
74 "It will be added as a child of selected category." ),
75 QLineEdit::Normal
, "", &ok
);
77 if( ok
&& !name
.isEmpty() ) {
78 // check if snippet's not selected
79 QStandardItem
* parent
= model
.itemFromIndex( ui
->snippetTreeView
->currentIndex() );
80 Snippet
* snippet
= snippetForItem
.value( parent
);
83 QMessageBox::warning( this, tr( "Error inserting snippet" ), tr( "A snippet cannot be added to the root of the tree." ) );
86 if( !snippet
->isCategory() )
87 parent
= parent
->parent();
90 QStandardItem
* item
= new QStandardItem( snippetIcon
, name
);
91 ui
->snippetTreeView
->setExpanded( parent
->index(), true );
93 snippet
= new Snippet( name
);
94 snippetForItem
.insert( item
, snippet
);
95 insertItem( item
, parent
);
97 // open snippet for editing
98 on_snippetTreeView_activated( item
->index() );
102 void MainWindow::on_action_Save_activated() {
103 Snippet
* snippet
= findSnippetByTab( ui
->tabWidget
->currentIndex() );
104 snippet
->save( ui
->descTextEdit
->toPlainText() );
105 snippet
->setModified( false );
106 ui
->tabWidget
->setTabText( snippet
->tabNumber(), ui
->tabWidget
->tabText( snippet
->tabNumber() ).remove( 0, 1 ) );
109 ui
->action_Save
->setEnabled( false );
110 ui
->actionSave_all
->setEnabled( false );
111 ui
->action_Close
->setEnabled( true );
112 ui
->actionClos_e_all
->setEnabled( true );
115 void MainWindow::loadSnippets() {
116 model
.setColumnCount( 1 );
122 QDomDocument domDocument
;
123 QFile
file( "snippets.xml" );
124 if( !domDocument
.setContent( &file
, true, &errorStr
, &errorLine
, &errorColumn
) ) {
125 QMessageBox::information(window(), tr("Snippets XML file"), tr("Parse error at line %1, column %2:\n%3")
132 snippetForItem
.insert( model
.invisibleRootItem(), new Snippet( domDocument
.documentElement(), true ) );
134 QDomElement child
= domDocument
.documentElement().firstChildElement("category");
135 while ( !child
.isNull() ) {
136 parseCategoryElement( child
, model
.invisibleRootItem() );
137 child
= child
.nextSiblingElement( "category" );
141 void MainWindow::parseCategoryElement( const QDomElement
&element
, QStandardItem
* parent
) {
142 // create item with category's title
143 QStandardItem
* titleItem
= new QStandardItem( categoryIcon
, element
.firstChildElement("title").text() );
144 parent
->setChild( parent
->rowCount(), 0, titleItem
);
145 snippetForItem
.insert( titleItem
, new Snippet( element
, true ) );
147 // iterate over children of the element
148 QDomElement child
= element
.firstChildElement();
149 while( !child
.isNull() ) {
150 if( child
.tagName() == "category" ) {
151 parseCategoryElement( child
, titleItem
);
152 } else if( child
.tagName() == "snippet" ) {
153 // create item with snippet's title
154 QStandardItem
* title
= new QStandardItem( snippetIcon
, child
.firstChildElement("title").text() );
156 // insert item and snippet into the hash and the model
157 Snippet
* snippet
= new Snippet( child
);
158 snippetForItem
.insert( title
, snippet
);
159 titleItem
->setChild( titleItem
->rowCount(), 0, title
);
161 child
= child
.nextSiblingElement();
165 void MainWindow::on_snippetTreeView_activated( QModelIndex index
) {
166 Snippet
* snippet
= snippetForItem
.value( model
.itemFromIndex( index
) );
167 if( !snippet
->isCategory() ) {
168 if( snippet
->isOpened() ) {
169 ui
->tabWidget
->setCurrentIndex( snippet
->tabNumber() );
170 ui
->descTextEdit
->setPlainText( snippet
->tempDescription() );
171 ui
->descTextEdit
->setEnabled( true );
172 if( snippet
->isModified() ) {
173 ui
->action_Save
->setEnabled( true );
174 ui
->actionSave_all
->setEnabled( true );
178 QPlainTextEdit
* edit
= new QPlainTextEdit( snippet
->code() );
179 connect( edit
, SIGNAL( textChanged() ), this, SLOT( snippetsCodeModified() ) );
180 snippet
->setEdit( edit
);
181 snippet
->setOpened();
182 snippet
->setTab( ui
->tabWidget
->addTab( edit
, snippet
->title() ) );
183 ui
->tabWidget
->setCurrentIndex( snippet
->tabNumber() );
184 ui
->descTextEdit
->setPlainText( snippet
->description() );
185 ui
->descTextEdit
->setEnabled( true );
187 if( snippet
->isModified() ) {
188 ui
->action_Save
->setEnabled( true );
189 ui
->actionSave_all
->setEnabled( true );
193 ui
->action_Close
->setEnabled( true );
194 ui
->actionClos_e_all
->setEnabled( true );
196 connect( ui
->descTextEdit
, SIGNAL( textChanged() ),
197 this, SLOT( on_descTextEdit_textChanged() ) );
201 void MainWindow::insertItem( QStandardItem
* item
, QStandardItem
* parent
) {
203 if( snippetForItem
.value( item
)->isCategory() ) {
204 for( i
= 0; i
< parent
->rowCount() && snippetForItem
.value( parent
->child( i
, 0 ) )->isCategory()
205 && QString::compare( parent
->child( i
, 0 )->text(), item
->text(), Qt::CaseInsensitive
) < 0; i
++ ) ;
206 parent
->insertRow( i
, item
);
208 for( i
= 0; i
< parent
->rowCount() &&
209 ( ( snippetForItem
.value( parent
->child( i
, 0 ) )->isCategory() ) ||
210 ( !snippetForItem
.value( parent
->child( i
, 0 ) )->isCategory() && QString::compare( parent
->child( i
, 0 )->text(), item
->text(), Qt::CaseInsensitive
) < 0 ) ); i
++ ) ;
211 parent
->insertRow( i
, item
);
215 void MainWindow::snippetsCodeModified() {
216 Snippet
* snippet
= findSnippetByTab( ui
->tabWidget
->currentIndex() );
217 if( !snippet
->isModified() ) {
218 snippet
->setModified();
219 ui
->tabWidget
->setTabText( snippet
->tabNumber(),
220 QString( "*" ) + ui
->tabWidget
->tabText( snippet
->tabNumber() ) );
221 ui
->action_Save
->setEnabled( true );
222 ui
->actionSave_all
->setEnabled( true );
226 Snippet
* MainWindow::findSnippetByTab( int atab
) {
227 QHash
< QStandardItem
*, Snippet
* >::iterator i
;
228 for( i
= snippetForItem
.begin(); i
!= snippetForItem
.end(); i
++ )
229 if( i
.value()->isOpened() && i
.value()->tabNumber() == atab
)
234 void MainWindow::saveSnippets( const QString
& fileName
) {
236 if( fileName
.isEmpty() )
237 file
.setFileName( "snippets.xml" );
239 file
.setFileName( fileName
);
241 if( !file
.open( QIODevice::WriteOnly
| QIODevice::Truncate
) ) {
242 QMessageBox::critical( this, tr( "Error" ), tr( "Cannot open file snippets.xml for writing." ) );
245 QString
xml( "<snippets>\n" );
246 parseModel( model
.invisibleRootItem(), xml
);
247 xml
+= "</snippets>";
249 QTextStream
out( &file
);
253 void MainWindow::parseModel( QStandardItem
* parent
, QString
& xml
) {
254 for( int i
= 0; i
< parent
->rowCount(); i
++ ) {
255 Snippet
* snippet
= snippetForItem
.value( parent
->child( i
, 0 ) );
256 if( snippet
->isCategory() ) {
257 xml
+= "<category><title>" + toValidXml( snippet
->title() ) + "</title>\n";
258 parseModel( parent
->child( i
, 0 ), xml
);
259 xml
+= "</category>\n";
261 xml
+= "<snippet><title>" + toValidXml( snippet
->title() ) + "</title>\n";
262 xml
+= "<code>" + toValidXml( snippet
->code() ) + "</code>\n";
263 xml
+= "<description>" + toValidXml( snippet
->description() ) + "</description></snippet>\n";
268 void MainWindow::on_actionSave_all_activated() {
269 QHash
< QStandardItem
*, Snippet
* >::iterator i
;
270 int prevTab
= ui
->tabWidget
->currentIndex();
271 for( i
= snippetForItem
.begin(); i
!= snippetForItem
.end(); i
++ )
272 if( i
.value()->isOpened() ) {
273 ui
->tabWidget
->setCurrentIndex( i
.value()->tabNumber() );
274 on_action_Save_activated();
276 ui
->tabWidget
->setCurrentIndex( prevTab
);
279 void MainWindow::on_action_Close_activated() {
280 Snippet
* snippet
= findSnippetByTab( ui
->tabWidget
->currentIndex() );
282 if( snippet
->isModified() ) {
283 QMessageBox::StandardButton answer
= QMessageBox::question( this, tr( "Save?" ),
284 tr( "Snippet %1 has been modified." ).arg( snippet
->title() ),
285 QMessageBox::Save
| QMessageBox::Discard
| QMessageBox::Cancel
, QMessageBox::Save
);
286 if( answer
== QMessageBox::Save
)
287 on_action_Save_activated();
288 else if( answer
!= QMessageBox::Discard
)
292 ui
->tabWidget
->removeTab( snippet
->tabNumber() );
293 snippet
->setEdit( 0 );
294 snippet
->setOpened( false );
299 if( ui
->tabWidget
->count() ) {
300 ui
->action_Close
->setEnabled( true );
301 ui
->actionClos_e_all
->setEnabled( true );
303 if( findSnippetByTab( ui
->tabWidget
->currentIndex() )->isModified() ) {
304 ui
->action_Save
->setEnabled( true );
305 ui
->actionSave_all
->setEnabled( true );
308 connect( ui
->descTextEdit
, SIGNAL( textChanged() ),
309 this, SLOT( on_descTextEdit_textChanged() ) );
310 ui
->action_Close
->setEnabled( false );
311 ui
->actionClos_e_all
->setEnabled( false);
312 ui
->descTextEdit
->clear();
313 ui
->descTextEdit
->setEnabled( false );
317 void MainWindow::on_actionClos_e_all_activated() {
318 QHash
< QStandardItem
*, Snippet
* >::iterator i
;
319 for( i
= snippetForItem
.begin(); i
!= snippetForItem
.end(); i
++ )
320 if( i
.value()->isOpened() ) {
321 ui
->tabWidget
->setCurrentIndex( i
.value()->tabNumber() );
322 on_action_Close_activated();
326 void MainWindow::restoreTabNumbers() {
327 QHash
< QStandardItem
*, Snippet
* >::iterator i
;
328 for( i
= snippetForItem
.begin(); i
!= snippetForItem
.end(); i
++ )
329 if( i
.value()->isOpened() ) {
330 for( int k
= 0; k
< ui
->tabWidget
->count(); k
++ )
331 if( i
.value()->title() == ui
->tabWidget
->tabText( k
)
332 || "*" + i
.value()->title() == ui
->tabWidget
->tabText( k
) ) {
333 i
.value()->setTab( k
);
339 void MainWindow::on_action_Main_category_activated() {
341 QString name
= QInputDialog::getText( this, tr( "New category..." ), tr( "Enter the new category name. "
342 "It will be added to the root node." ),
343 QLineEdit::Normal
, "", &ok
);
345 if( ok
&& !name
.isEmpty() ) {
346 QStandardItem
* parent
= model
.invisibleRootItem();
349 QStandardItem
* item
= new QStandardItem( categoryIcon
, name
);
350 ui
->snippetTreeView
->setExpanded( parent
->index(), true );
351 snippetForItem
.insert( item
, new Snippet( name
, true ) );
352 insertItem( item
, parent
);
356 void MainWindow::on_action_Save_2_activated() {
360 void MainWindow::on_actionSave_snippets_as_activated() {
361 QString fileName
= QFileDialog::getSaveFileName( this, tr( "Save as..." ) );
362 if( !fileName
.isEmpty() )
363 saveSnippets( fileName
);
366 void MainWindow::on_action_Exit_activated() {
367 on_actionClos_e_all_activated();
371 void MainWindow::on_searchLineEdit_textChanged( QString searchString
) {
372 // check if we're in edit or work mode
373 if( workModeDialog
.isVisible() )
374 ui
->searchLineEdit
->setText( workModeDialog
.m_ui
->searchLineEdit
->text() );
376 workModeDialog
.m_ui
->searchLineEdit
->setText( ui
->searchLineEdit
->text() );
378 workModeDialog
.showSnippets();
380 showAllSnippets( model
.invisibleRootItem() );
381 if( !searchString
.isEmpty() )
382 searchModelForString( searchString
, model
.invisibleRootItem() );
384 if( !workModeDialog
.underMouse() )
385 QTimer::singleShot( 3000, &workModeDialog
, SLOT( hideSnippets() ) );
388 // returns false of all children of a parent were hidden during parse
389 bool MainWindow::searchModelForString( const QString
&searchString
, QStandardItem
* parent
) {
392 for( int i
= 0; i
< parent
->rowCount(); i
++ ) {
393 QStandardItem
* child
= parent
->child( i
, 0 );
394 Snippet
* snippet
= snippetForItem
.value( child
);
396 if( ui
->snippetTreeView
->isRowHidden( i
, parent
->index() ) )
398 else if( snippet
->isCategory() && !child
->text().contains( searchString
, Qt::CaseInsensitive
) ) {
399 if( child
->rowCount() ) {
400 if( !searchModelForString( searchString
, child
) ) {
401 ui
->snippetTreeView
->setRowHidden( i
, parent
->index(), true );
402 workModeDialog
.m_ui
->treeView
->setRowHidden( i
, parent
->index(), true );
406 ui
->snippetTreeView
->setRowHidden( i
, parent
->index(), true );
407 workModeDialog
.m_ui
->treeView
->setRowHidden( i
, parent
->index(), true );
410 } else if( !snippet
->isCategory()
411 && ( !child
->text().contains( searchString
, Qt::CaseInsensitive
) && !snippet
->code().contains( searchString
, Qt::CaseInsensitive
) ) ) {
412 ui
->snippetTreeView
->setRowHidden( i
, parent
->index(), true );
413 workModeDialog
.m_ui
->treeView
->setRowHidden( i
, parent
->index(), true );
418 if( hiddenCount
== parent
->rowCount() )
424 void MainWindow::showAllSnippets( QStandardItem
* parent
) {
425 for( int i
= 0; i
< parent
->rowCount(); i
++ ) {
426 ui
->snippetTreeView
->setRowHidden( i
, parent
->index(), false );
427 workModeDialog
.m_ui
->treeView
->setRowHidden( i
, parent
->index(), false );
428 showAllSnippets( parent
->child( i
, 0 ) );
432 void MainWindow::on_action_Delete_activated() {
433 if( ui
->snippetTreeView
->currentIndex().isValid() ) {
434 QStandardItem
* item
= model
.itemFromIndex( ui
->snippetTreeView
->currentIndex() );
436 QMessageBox::StandardButton answer
= QMessageBox::question( this, tr( "Delete" ),
437 tr( "Do you really want to delete element %1 and all its subelements?" ).arg( item
->text() ),
438 QMessageBox::Yes
| QMessageBox::No
);
439 if( answer
== QMessageBox::Yes
)
440 deleteChildItems( item
);
444 void MainWindow::deleteChildItems( QStandardItem
* parent
) {
445 while( parent
->hasChildren() )
446 deleteChildItems( parent
->child( 0, 0 ) );
448 if( snippetForItem
.value( parent
)->isOpened() ) {
449 Snippet
* prev
= findSnippetByTab( ui
->tabWidget
->currentIndex() );
450 ui
->tabWidget
->setCurrentIndex( snippetForItem
.value( parent
)->tabNumber() );
451 snippetForItem
.value( parent
)->setModified( false );
452 on_action_Close_activated();
454 ui
->tabWidget
->setCurrentIndex( prev
->tabNumber() );
457 delete snippetForItem
.value( parent
);
458 snippetForItem
.remove( parent
);
459 if( !parent
->parent() )
460 model
.removeRow( parent
->index().row() );
462 parent
->parent()->removeRow( parent
->index().row() );
465 void MainWindow::on_action_Work_activated() {
467 workModeDialog
.show();
469 mainWindowGeometry
= this->saveGeometry();
470 workModeDialog
.restoreGeometry( workModeDialogGeometry
);
472 qApp
->setActiveWindow( &workModeDialog
);
473 workModeDialog
.m_ui
->searchLineEdit
->setFocus();
476 void MainWindow::on_action_Normal_activated() {
478 workModeDialog
.hide();
480 workModeDialogGeometry
= workModeDialog
.saveGeometry();
481 this->restoreGeometry( mainWindowGeometry
);
484 void MainWindow::on_WorkModeDialog_finished( int ) {
486 on_action_Normal_activated();
489 void MainWindow::updateSnippetsTitle( QStandardItem
* item
) {
490 Snippet
* snippet
= snippetForItem
.value( item
);
491 snippet
->setTitle( item
->text() );
494 QString
MainWindow::toValidXml( QString string
) {
495 QString
temp( string
);
497 temp
.replace( "&", "&" );
498 temp
.replace( "<", "<" );
499 temp
.replace( ">", ">" );
504 void MainWindow::on_actionHide_categories_activated() {
505 if( ui
->leftDockWidget
->isVisible() )
506 ui
->leftDockWidget
->hide();
508 ui
->leftDockWidget
->show();
511 void MainWindow::on_actionHide_description_activated() {
512 if( ui
->descDockWidget
->isVisible() )
513 ui
->descDockWidget
->hide();
515 ui
->descDockWidget
->show();
518 void MainWindow::on_descTextEdit_textChanged() {
519 if( ui
->descTextEdit
->toPlainText().isEmpty() )
522 findSnippetByTab( ui
->tabWidget
->currentIndex() )->setTempDescription( ui
->descTextEdit
->toPlainText() );
524 if( findSnippetByTab( ui
->tabWidget
->currentIndex() )->description() != ui
->descTextEdit
->toPlainText() )
525 snippetsCodeModified();
528 void MainWindow::on_tabWidget_currentChanged( int index
) {
529 QStandardItem
* item
= snippetForItem
.key( findSnippetByTab( index
) );
531 on_snippetTreeView_activated( item
->index() );