gSAFE  1.3.8
dconsole.cpp
1 /* gSAFE - LIB
2  general Sql dAtabase FrontEnd
3  http://hyperprog.com/gsafe/
4 
5  (C) 2006-2013 Peter Deak (hyper80@gmail.com)
6 
7  License: GPLv2 http://www.gnu.org/licenses/gpl-2.0.html
8 
9  dconsole.cpp
10 */
11 
12 #ifndef GSAFE_DISABLE_DEBUG
13 #include <QtGui>
14 
15 #include <QtCore>
16 
17 #ifndef DCONSOLE_NO_SQL
18 #include <QtSql>
19 #endif // DCONSOLE_NO_SQL
20 
21 #ifndef COMPILED_WITH_QT4X
22 #include <QtWidgets>
23 #endif //COMPILED_WITH_QT4X
24 
25 #endif //GSAFE_DISABLE_DEBUG
26 
27 #include "dconsole.h"
28 
29 //#define FILE_DEBUG 1
30 
31 #ifndef GSAFE_DISABLE_DEBUG
33 #endif //GSAFE_DISABLE_DEBUG
34 
35 #ifndef DCONSOLE_NO_SQL
36 void sqldebug(QString s)
37 {
38 #ifndef GSAFE_DISABLE_DEBUG
39  if(HDebugConsole::myself == NULL)
40  return;
42 #else
43  Q_UNUSED(s);
44 #endif //GSAFE_DISABLE_DEBUG
45 }
46 #endif // DCONSOLE_NO_SQL
47 
48 void sdebug(QString s)
49 {
50 #ifndef GSAFE_DISABLE_DEBUG
51  if(HDebugConsole::myself == NULL)
52  return;
54 #else
55  Q_UNUSED(s);
56 #endif //GSAFE_DISABLE_DEBUG
57 }
58 
59 void dconsole(void)
60 {
61 #ifndef GSAFE_DISABLE_DEBUG
62  if(HDebugConsole::myself == NULL)
63  {
64  HDebugConsole *dw=new HDebugConsole(0);
65  dw->show();
66  }
67 #endif //GSAFE_DISABLE_DEBUG
68 }
69 
70 void dconsole_close(void)
71 {
72 #ifndef GSAFE_DISABLE_DEBUG
73  if(HDebugConsole::myself != NULL)
74  {
75  HDebugConsole::myself->close();
76  delete HDebugConsole::myself;
77  HDebugConsole::myself=NULL;
78  }
79 #endif //GSAFE_DISABLE_DEBUG
80 }
81 
82 void dconsole_popup(QString t,QString txt)
83 {
84  #ifndef GSAFE_DISABLE_DEBUG
85  QMessageBox::warning(NULL,t,txt);
86  #else
87  Q_UNUSED(t);
88  Q_UNUSED(txt);
89  #endif //GSAFE_DISABLE_DEBUG
90 }
91 
92 QMultiMap<QString,HDConsoleCommandHolder *> user_commands;
93 QMultiMap<QString,QString> user_commands_descr;
94 
95 void register_dconsole_command(QString command,HDConsoleCommandHolder *interpreter,QString descr)
96 {
97  if(!command.isEmpty() && interpreter != NULL)
98  {
99  user_commands.insert(command,interpreter);
100  user_commands_descr.insert(command,descr);
101  }
102 }
103 
104 void unregister_dconsole_command(QString command)
105 {
106  if(!command.isEmpty())
107  {
108  user_commands.remove(command);
109  user_commands_descr.remove(command);
110  }
111 }
112 
114 {
115  user_commands.clear();
116  user_commands_descr.clear();
117 }
118 
119 #ifndef GSAFE_DISABLE_DEBUG
120 
121 /* *********************************************************************************
122  * HDebugConsole related class
123  * ********************************************************************************* */
124 
125 /* pimpl class of HDebugConsole */
126 class HDebugConsolePrivate
127 {
128  friend class HDebugConsole;
129 
130 private:
131  HDebugConsolePrivate(HDebugConsole *parent)
132  { pp = parent; }
133  ~HDebugConsolePrivate()
134  { pp = NULL; }
135 
136 private:
137  HDebugConsole *pp;
138  QString databasename;
139  bool disabled;
140 
141 #ifndef DCONSOLE_NO_SQL
142  QPushButton *pushSql;
143 #endif // DCONSOLE_NO_SQL
144  QPushButton *pushText,*pushSyncwrite,*pushClear;
145  HConsolePanel *cf;
146 
147  QMap<QString,void (HDebugConsolePrivate::*)(QString)> commands_exec;
148  QMap<QString,QString> commands_dscr;
149 
150  //console command handlers:
151  void command_help(QString fcl);
152  void command_exit(QString fcl);
153  void command_close(QString fcl);
154  void command_clear(QString fcl);
155  void command_filters(QString fcl);
156  void command_state(QString fcl);
157  void command_enable(QString fcl);
158  void command_disable(QString fcl);
159  void command_synw(QString fcl);
160  void command_write(QString fcl);
161  void command_save(QString fcl);
162  void command_run(QString fcl);
163 
164 #ifndef DCONSOLE_NO_SQL
165  void command_alldb(QString fcl);
166  void command_dbinfo(QString fcl);
167  void command_setdb(QString fcl);
168  void command_show(QString fcl);
169 #endif // DCONSOLE_NO_SQL
170 
171 };
172 
174 :QWidget(parent)
175 {
176  p = new HDebugConsolePrivate(this);
177  setWindowTitle("HDebugConsole");
178  p->databasename = "";
179  myself = this;
180  p->disabled = false;
181 
182  setAttribute(Qt::WA_DeleteOnClose);
183  QVBoxLayout *qvbl = new QVBoxLayout(this);
184  QHBoxLayout *qhbl = new QHBoxLayout(0);
185  p->cf = new HConsolePanel(this);
186 
187 #ifndef DCONSOLE_NO_SQL
188  p->pushSql = new QPushButton(tr("Sql"),this);
189  p->pushSql->setCheckable(true);
190  p->pushSql->setChecked(true);
191  qhbl->addWidget(p->pushSql);
192 #endif // DCONSOLE_NO_SQL
193  p->pushText = new QPushButton(tr("Text"),this);
194  p->pushText->setCheckable(true);
195  p->pushText->setChecked(true);
196  p->pushSyncwrite = new QPushButton(tr("SyncWrite:\"syndebug.txt\""),this);
197  p->pushSyncwrite->setCheckable(true);
198  p->pushSyncwrite->setChecked(false);
199  p->pushClear = new QPushButton(tr("Clear"),this);
200  qhbl->addWidget(p->pushText);
201  qhbl->addWidget(p->pushSyncwrite);
202  qhbl->addStretch();
203  qhbl->addWidget(p->pushClear);
204 
205  qvbl->setMargin(0);
206  qvbl->setSpacing(0);
207  qvbl->addLayout(qhbl);
208  qvbl->addWidget(p->cf);
209 
210  connect(p->pushClear,SIGNAL(clicked()),p->cf,SLOT(clearText()));
211  connect(p->cf,SIGNAL(commandEntered(QString)),this,SLOT(execCommand(QString)));
212  connect(p->cf,SIGNAL(tabPressed(QString)),this,SLOT(tabPressed(QString)));
213  p->cf->setTextTypeColor(1,QColor(255,150,150));
214  p->cf->setTextTypeColor(2,QColor(200,200,200));
215 
216  p->cf->setColor("cursor",Qt::white);
217  p->cf->setColor("cmdtext",QColor(0,255,0));
218  p->cf->setTextTypeColor(DCONSOLE_TYPE_MESSAGE ,QColor(210,210,210));
219  p->cf->setTextTypeColor(DCONSOLE_TYPE_TEXT ,QColor(200,200,0));
220  p->cf->setTextTypeColor(DCONSOLE_TYPE_SQL ,QColor(255,0,0));
221  p->cf->setTextTypeColor(DCONSOLE_TYPE_RESULT ,QColor(100,100,255));
222  p->cf->setTextTypeColor(DCONSOLE_TYPE_CMD ,QColor(0,230,0));
223  p->cf->setTextTypeColor(DCONSOLE_TYPE_QTDEBUG ,QColor(255,127,30));
224 
225  p->cf->addText("START",DCONSOLE_TYPE_MESSAGE);
226 
227  //Registering console commands
228  p->commands_exec["help"] = &HDebugConsolePrivate::command_help;
229  p->commands_dscr["help"] = " help - List the available commands";
230 
231  p->commands_exec["exit"] = &HDebugConsolePrivate::command_exit;
232  p->commands_dscr["exit"] = " exit - Exit main program (The debugged program too)";
233 
234  p->commands_exec["close"] = &HDebugConsolePrivate::command_close;
235  p->commands_dscr["close"] = " close - Close the debug window (only)";
236 
237  p->commands_exec["clear"] = &HDebugConsolePrivate::command_clear;
238  p->commands_dscr["clear"] = " clear - Clears the debug window\'s text";
239 
240  p->commands_exec["filters"] = &HDebugConsolePrivate::command_filters;
241  p->commands_dscr["filters"] = " filters - Show available debug filters";
242 
243  p->commands_exec["state"] = &HDebugConsolePrivate::command_state;
244  p->commands_dscr["state"] = " state <filter> - Show the state of the \"filter\" kind of output filter";
245 
246  p->commands_exec["enable"] = &HDebugConsolePrivate::command_enable;
247  p->commands_dscr["enable"] = " enable <filter> - Enable the \"filter\" kind of output";
248 
249  p->commands_exec["disable"] = &HDebugConsolePrivate::command_disable;
250  p->commands_dscr["disable"] = " disable <filter> - Disable the \"filter\" kind of output";
251 
252  p->commands_exec["synw"] = &HDebugConsolePrivate::command_synw;
253  p->commands_dscr["synw"] = " synw - Query the state or clear the content of syndebug.txt\n"
254  " synw off - Disable the writing of syndebug.txt\n"
255  " synw on - Enable the writing of syndebug.txt\n"
256  " synw clear - Clear the content of syndebug.txt";
257 
258  p->commands_exec["write"] = &HDebugConsolePrivate::command_write;
259  p->commands_dscr["write"] = " write <text> - Write \"text\" to the console";
260 
261  p->commands_exec["save"] = &HDebugConsolePrivate::command_save;
262  p->commands_dscr["save"] = " save - Save the content of debug window to debug.txt";
263 
264  p->commands_exec["run"] = &HDebugConsolePrivate::command_run;
265  p->commands_dscr["run"] = " run <custom> - Run the \"custom\" program command";
266 
267 #ifndef DCONSOLE_NO_SQL
268  p->commands_exec["alldb"] = &HDebugConsolePrivate::command_alldb;
269  p->commands_dscr["alldb"] = " alldb - Show all available database connections";
270 
271  p->commands_exec["dbinfo"] = &HDebugConsolePrivate::command_dbinfo;
272  p->commands_dscr["dbinfo"] = " dbinfo - Show the current connected database information";
273 
274  p->commands_exec["setdb"] = &HDebugConsolePrivate::command_setdb;
275  p->commands_dscr["setdb"] = " setdb - Sets the current database to default (not the program but console)\n"
276  " setdb <dbname> - Sets the current database to \"dbname\"";
277 
278  p->commands_exec["show"] = &HDebugConsolePrivate::command_show;
279  p->commands_dscr["show"] = " show - Show all table in the current database\n"
280  " show <tablename> - Show the fields of table named \"tablename\"";
281 
282 #endif // DCONSOLE_NO_SQL
283 
284  resize(660,420);
285  #ifdef FILE_DEBUG
286  pushSyncwrite->setChecked(true);
287  #endif
288 
289 #ifndef COMPILED_WITH_QT4X
290  qInstallMessageHandler(dconsoleMessageHandler);
291 #else
292  qInstallMsgHandler(dconsoleMessageHandler);
293 #endif
294 }
295 
297 {
298 #ifndef COMPILED_WITH_QT4X
299  qInstallMessageHandler(0);
300 #else
301  qInstallMsgHandler(0);
302 #endif
303 
304  delete p;
305  p = NULL;
306  myself = NULL;
307 }
308 
310 {
311  if(enabled)
312  {
313  p->pushText->setDisabled(false);
314  p->pushSyncwrite->setDisabled(false);
315 #ifndef DCONSOLE_NO_SQL
316  p->pushSql->setDisabled(false);
317 #endif // DCONSOLE_NO_SQL
318  }
319  else
320  {
321  p->pushText->setDisabled(true);
322  p->pushSyncwrite->setDisabled(true);
323 #ifndef DCONSOLE_NO_SQL
324  p->pushSql->setDisabled(true);
325 #endif // DCONSOLE_NO_SQL
326  }
327  p->disabled = !enabled;
328 }
329 
331 {
332  return p->cf;
333 }
334 
335 void HDebugConsole::popup(QString title,QString str)
336 {
337  QMessageBox::warning(NULL,title,str);
338 }
339 
340 //#define FILE_DEBUG
341 void HDebugConsole::add_text(QString s,int type)
342 {
343  if(p->pushSyncwrite->isChecked())
344  {
345  FILE *dbgf;
346 
347  dbgf = fopen("syndebug.txt","a");
348  fseek(dbgf,0,SEEK_END);
349  fprintf(dbgf,"\n%s\n",s.toLocal8Bit().constData());
350  fclose(dbgf);
351  }
352 
353 #ifndef DCONSOLE_NO_SQL
354  if(p->pushSql->isChecked() && type == DCONSOLE_TYPE_SQL)
355  p->cf->addText(s,DCONSOLE_TYPE_SQL);
356 
357 #endif // DCONSOLE_NO_SQL
358 
359  if(p->pushText->isChecked() && type == DCONSOLE_TYPE_TEXT)
360  p->cf->addText(s,DCONSOLE_TYPE_TEXT);
361 
362  if(type == DCONSOLE_TYPE_QTDEBUG)
363  p->cf->addText(s,DCONSOLE_TYPE_QTDEBUG);
364 
365  QApplication::processEvents();
366 }
367 
368 void HDebugConsole::closeEvent(QCloseEvent *e)
369 {
370  myself = NULL;
371  QWidget::closeEvent(e);
372 }
373 
374 #ifndef DCONSOLE_NO_SQL
376 {
377  if(myself != NULL)
378  myself->add_text(s,DCONSOLE_TYPE_SQL);
379 }
380 #endif // DCONSOLE_NO_SQL
381 
383 {
384  if(myself != NULL)
385  myself->add_text(s,DCONSOLE_TYPE_TEXT);
386 }
387 
388 int HDebugConsole::execCommand(QString query)
389 {
390  if(p->disabled)
391  return 0;
392 
393  query = query.simplified();
394  if(query == "")
395  {
396  p->cf->addText(".",DCONSOLE_TYPE_MESSAGE);
397  return 0;
398  }
399 
400  QStringList qparts = query.split(" ",QString::SkipEmptyParts);
401  if(qparts.count() > 0)
402  {
403  if(p->commands_exec.find(qparts[0]) != p->commands_exec.end())
404  {
405  void (HDebugConsolePrivate::*cmdFunc)(QString);
406 
407  p->cf->addText(p->cf->promptString() + query , DCONSOLE_TYPE_CMD);
408  cmdFunc = p->commands_exec[qparts[0]];
409  (*p.*cmdFunc)(query.mid(qparts[0].length(),-1).simplified());
410  return 0;
411  }
412  }
413 
414 #ifndef DCONSOLE_NO_SQL
415  int i,cn;
416  QVariant v;
417 
418  cn=0;
419  p->cf->addText(p->cf->promptString() + query , DCONSOLE_TYPE_CMD);
420  p->cf->addText("Exec Console sumbitted query...",DCONSOLE_TYPE_MESSAGE);
421  p->cf->addText("\""+query+"\"",DCONSOLE_TYPE_SQL);
422 
423  QSqlDatabase db;
424  if(p->databasename.isEmpty())
425  db = QSqlDatabase::database();
426  else
427  db = QSqlDatabase::database(p->databasename);
428 
429  db.transaction();
430  QSqlQuery q(db);
431  q.exec(query);
432  QString result;
433 
434  if(q.lastError().type() == QSqlError::NoError)
435  {
436  p->cf->addText("Succesfull executed. Dumping data:",DCONSOLE_TYPE_MESSAGE);
437 
438  while(q.next())
439  {
440  if(!q.record().isEmpty())
441  {
442  cn = q.record().count();
443  result.append("\n");
444  for(i=0;i<cn;++i)
445  {
446  v = q.value(i);
447  if(v.isValid())
448  {
449  if(i != 0)
450  result.append(" | ");
451  result.append(v.toString());
452  }
453  }
454  }
455  }
456  p->cf->addText(result,DCONSOLE_TYPE_RESULT);
457  p->cf->addText(QString("(%1 rows affected/%2 size)")
458  .arg(q.numRowsAffected())
459  .arg(q.size())
460  ,DCONSOLE_TYPE_MESSAGE);
461  p->cf->addText("End query: \""+query+"\"",DCONSOLE_TYPE_MESSAGE);
462  db.commit();
463  }
464  else
465  {
466  p->cf->addText(QString("\nError: %1").arg(q.lastError().text()),DCONSOLE_TYPE_MESSAGE);
467  db.rollback();
468  }
469  #else
470  p->cf->addText(QString("Unknown command: %1").arg(query),DCONSOLE_TYPE_MESSAGE);
471  #endif // DCONSOLE_NO_SQL
472  return 0;
473 }
474 
475 int HDebugConsole::tabPressed(QString query)
476 {
477  if(query.isEmpty() || p->disabled)
478  return 0;
479 
480  //Handle special ommand "run" which executes user defined commands
481  //We search in these user defined commands
482  if(query.startsWith("run "))
483  {
484  if(user_commands.size() > 0)
485  {
486  int mnum = 0;
487  QString cmd;
488  QMultiMap<QString,HDConsoleCommandHolder *>::const_iterator i = user_commands.constBegin();
489  while(i != user_commands.constEnd())
490  {
491  if( QString("run %1").arg(i.key()).startsWith(query) )
492  {
493  ++mnum;
494  cmd = i.key();
495  }
496  ++i;
497  }
498 
499  if(mnum == 1)
500  {
501  p->cf->setCommandLineText(QString("run %1").arg(cmd));
502  return 0;
503  }
504 
505  if(mnum > 1)
506  {
507  p->cf->addText("",DCONSOLE_TYPE_MESSAGE);
508  for(i = user_commands.constBegin();i != user_commands.constEnd();++i)
509  if(QString("run %1").arg(i.key()).startsWith(query))
510  p->cf->addText((QString("run %1 - %2")
511  .arg(i.key())
512  .arg(user_commands_descr.value(i.key())))
513  ,DCONSOLE_TYPE_MESSAGE);
514  }
515  }
516  return 0;
517  }
518 
519  int mnum=0;
520  QString cmd;
521  QStringList cmds = p->commands_dscr.keys();
522  QList<QString>::iterator i;
523  for(i = cmds.begin();i != cmds.end();++i)
524  if(i->startsWith(query))
525  {
526  ++mnum;
527  cmd = *i;
528  }
529 
530  if(mnum == 1)
531  {
532  p->cf->setCommandLineText(cmd == "run" ? QString("run ") : cmd);
533  return 0;
534  }
535 
536  if(mnum > 1)
537  {
538  p->cf->addText("",DCONSOLE_TYPE_MESSAGE);
539  for(i = cmds.begin();i != cmds.end();++i)
540  if(i->startsWith(query))
541  p->cf->addText((QString("%1").arg(p->commands_dscr[*i])),DCONSOLE_TYPE_MESSAGE);
542  }
543  return 0;
544 }
545 
546 #ifndef COMPILED_WITH_QT4X
547 void dconsoleMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
548 {
549  QString mm;
550  QString contmsg;
551 
552  contmsg = QString("(Category:%1, File:%2, Function:%3, Line:%4, Ver:%5)")
553  .arg(context.category)
554  .arg(context.file)
555  .arg(context.function)
556  .arg(context.line)
557  .arg(context.version);
558 
559  switch (type)
560  {
561  case QtDebugMsg:
562  mm = QString("Qt-Debug: %1\n%2").arg(msg).arg(contmsg);
563  break;
564  case QtWarningMsg:
565  mm = QString("Qt-Warning: %1\n%2").arg(msg).arg(contmsg);
566  break;
567  case QtCriticalMsg:
568  mm = QString("Qt-Critical: %1\n%2").arg(msg).arg(contmsg);
569  break;
570  case QtFatalMsg:
571  mm = QString("Qt-Fatal: %1\n%2").arg(msg).arg(contmsg);
572  break;
573  }
574 
575  if(HDebugConsole::myself == NULL)
576  {
577  fprintf(stderr,"%s",mm.toLocal8Bit().constData());
578  return;
579  }
580 
581  HDebugConsole::myself->add_text(mm,DCONSOLE_TYPE_QTDEBUG);
582 
583 }
584 #else
585 void dconsoleMessageHandler(QtMsgType type, const char *msg)
586 {
587  QString mm;
588  switch (type)
589  {
590  case QtDebugMsg:
591  mm = QString("Qt-Debug: %1").arg(msg);
592  break;
593  case QtWarningMsg:
594  mm = QString("Qt-Warning: %1").arg(msg);
595  break;
596  case QtCriticalMsg:
597  mm = QString("Qt-Critical: %1").arg(msg);
598  break;
599  case QtFatalMsg:
600  mm = QString("Qt-Fatal: %1").arg(msg);
601  break;
602  }
603 
604  if(HDebugConsole::myself == NULL)
605  {
606  fprintf(stderr,"%s",mm.toLocal8Bit().constData());
607  return;
608  }
609 
610  HDebugConsole::myself->add_text(mm,DCONSOLE_TYPE_QTDEBUG);
611 }
612 
613 #endif //COMPILED_WITH_QT4X
614 
615 /* **************************************************************************
616  * HDebugConsole command handlers
617  * ************************************************************************** */
618 #define MOUT(a) cf->addText(a,DCONSOLE_TYPE_MESSAGE)
619 
620 void HDebugConsolePrivate::command_help(QString fcl)
621 {
622  if(!fcl.isEmpty())
623  {
624  MOUT("This function doesn\'t accept parameters");
625  return;
626  }
627  MOUT("HDebugConsole, commands:");
628  QStringList keys = commands_dscr.keys();
629  keys.sort();
630  QList<QString>::iterator i;
631  for(i=keys.begin();i != keys.end();++i)
632  MOUT(QString("%1").arg(commands_dscr.value(*i)));
633 
634 #ifndef DCONSOLE_NO_SQL
635  MOUT(" \"SQL\" - Execute the SQL command");
636 #endif // DCONSOLE_NO_SQL
637  if(user_commands.size() > 0)
638  {
639  MOUT(" -- CUSTOM/PROGRAM COMMANDS -- ");
640  QMultiMap<QString,HDConsoleCommandHolder *>::const_iterator i = user_commands.constBegin();
641  while(i != user_commands.constEnd())
642  {
643  MOUT(QString(" run %1%2%3")
644  .arg(i.key())
645  .arg( user_commands_descr.value(i.key()) == "" ? "" : " - ")
646  .arg(user_commands_descr.value(i.key())));
647  ++i;
648  }
649  }
650  MOUT("");
651 }
652 
653 void HDebugConsolePrivate::command_exit(QString fcl)
654 {
655  if(!fcl.isEmpty())
656  {
657  MOUT("This function doesn\'t accept parameters");
658  return;
659  }
660  QApplication::exit(0);
661 }
662 
663 void HDebugConsolePrivate::command_close(QString fcl)
664 {
665  if(!fcl.isEmpty())
666  {
667  MOUT("This function doesn\'t accept parameters");
668  return;
669  }
670  pp->close();
671 }
672 
673 void HDebugConsolePrivate::command_clear(QString fcl)
674 {
675  if(!fcl.isEmpty())
676  {
677  MOUT("This function doesn\'t accept parameters");
678  return;
679  }
680  cf->clearText();
681 }
682 
683 void HDebugConsolePrivate::command_filters(QString fcl)
684 {
685  if(!fcl.isEmpty())
686  {
687  MOUT("This function doesn\'t accept parameters");
688  return;
689  }
690 #ifndef DCONSOLE_NO_SQL
691  MOUT(".\nAvailable filters: sql text\n");
692 #else
693  MOUT(".\nAvailable filters: text\n");
694 #endif // DCONSOLE_NO_SQL
695 }
696 
697 void HDebugConsolePrivate::command_state(QString fcl)
698 {
699 #ifndef DCONSOLE_NO_SQL
700  if(fcl == "sql")
701  {
702  MOUT(QString("SQL output is %1").arg(pushSql->isChecked() ? "enabled" : "disabled"));
703  return;
704  }
705 #endif // DCONSOLE_NO_SQL
706  if(fcl == "text")
707  {
708  MOUT(QString("TEXT output is %1.").arg(pushText->isChecked() ? "enabled" : "disabled"));
709  return;
710  }
711  MOUT("Unknown or missing filter name. Exec \"filters\" command to see available filters!");
712 }
713 
714 void HDebugConsolePrivate::command_enable(QString fcl)
715 {
716 #ifndef DCONSOLE_NO_SQL
717  if(fcl == "sql")
718  {
719  pushSql->setChecked(true);
720  MOUT("SQL output is enabled");
721  return;
722  }
723 #endif // DCONSOLE_NO_SQL
724 
725  if(fcl == "text")
726  {
727  pushText->setChecked(true);
728  MOUT("TEXT output is enabled");
729  return;
730  }
731  MOUT("Unknown or missing filter name. Exec \"filters\" command to see available filters!");
732 }
733 
734 void HDebugConsolePrivate::command_disable(QString fcl)
735 {
736 #ifndef DCONSOLE_NO_SQL
737  if(fcl == "sql")
738  {
739  pushSql->setChecked(false);
740  MOUT("SQL output is disabled");
741  return;
742  }
743 #endif // DCONSOLE_NO_SQL
744  if(fcl == "text")
745  {
746  pushText->setChecked(false);
747  MOUT("TEXT output is disabled");
748  return;
749  }
750  MOUT("Unknown or missing filter name. Exec \"filters\" command to see available filters!");
751 }
752 
753 void HDebugConsolePrivate::command_synw(QString fcl)
754 {
755  Q_UNUSED(fcl);
756 
757  if(fcl.isEmpty())
758  {
759  MOUT(QString("Syncronized backup file writing: %1")
760  .arg(pushSyncwrite->isChecked() ? "on" : "off"));
761  return;
762  }
763  if(fcl == "on")
764  {
765  pushSyncwrite->setChecked(true);
766  MOUT(QString("Enabled syncronized backup file writing (syndebug.txt)"));
767  return;
768  }
769  if(fcl == "off")
770  {
771  pushSyncwrite->setChecked(false);
772  MOUT(QString("Disabled syncronized backup file writing"));
773  return;
774  }
775  if(fcl == "clear")
776  {
777  FILE *dbgf;
778  dbgf = fopen("syndebug.txt","w");
779  fseek(dbgf,0,SEEK_SET);
780  fprintf(dbgf,"\n");
781  fclose(dbgf);
782  MOUT(QString("The content of syndebug.txt has been cleared"));
783  return;
784  }
785  MOUT("Wrong parameter! Accepted parameters: <empty>,on,off,clear");
786 }
787 
788 void HDebugConsolePrivate::command_write(QString fcl)
789 {
790  sdebug(fcl);
791 }
792 
793 void HDebugConsolePrivate::command_save(QString fcl)
794 {
795  if(!fcl.isEmpty())
796  {
797  MOUT("This function doesn\'t accept parameters");
798  return;
799  }
800  FILE *dbgf;
801  dbgf = fopen("debug.txt","w");
802  fseek(dbgf,0,SEEK_SET);
803  cf->selectAll();
804  fprintf(dbgf,"\n%s\n",cf->selectedText().toLocal8Bit().constData());
805  cf->clearSelection();
806  fclose(dbgf);
807  MOUT("Saving console text to debug.txt is done.\n");
808 }
809 
810 void HDebugConsolePrivate::command_run(QString fcl)
811 {
812  QMultiMap<QString,HDConsoleCommandHolder *>::iterator i;
813 
814  i = user_commands.find(fcl);
815  if(i == user_commands.end())
816  {
817  MOUT(" Error: Command not found!");
818  }
819  else
820  {
821  MOUT(QString("Starting command \"%1\"...").arg(fcl));
822  HDConsoleCommandHolder *dcch = *i;
824  MOUT("finished.");
825  }
826  MOUT("");
827 }
828 
829 #ifndef DCONSOLE_NO_SQL
830 void HDebugConsolePrivate::command_alldb(QString fcl)
831 {
832  if(!fcl.isEmpty())
833  {
834  MOUT("This function doesn\'t accept parameters");
835  return;
836  }
837  QStringList l = QSqlDatabase::connectionNames();
838  QStringList::iterator i=l.begin();
839  MOUT(QString("Available databases (%1) :").arg(l.count()));
840  while(i != l.end())
841  {
842  MOUT(" " + *i);
843  ++i;
844  }
845 }
846 
847 void HDebugConsolePrivate::command_dbinfo(QString fcl)
848 {
849  if(!fcl.isEmpty())
850  {
851  MOUT("This function doesn\'t accept parameters");
852  return;
853  }
854  QSqlDatabase db;
855  if(databasename.isEmpty())
856  db = QSqlDatabase::database();
857  else
858  db = QSqlDatabase::database(databasename);
859  if(db.isOpen())
860  {
861  MOUT(QString("Current OPENED database connection is:\nConnection name=%1\nDriver=%2\nName=%3\nHost=%4\nUser=%5\n")
862  .arg(db.connectionName())
863  .arg(db.driverName())
864  .arg(db.databaseName())
865  .arg(db.hostName())
866  .arg(db.userName()));
867  }
868  else
869  {
870  MOUT(QString("There is no opened database!"));
871  }
872 }
873 
874 void HDebugConsolePrivate::command_setdb(QString fcl)
875 {
876  QStringList l = QSqlDatabase::connectionNames();
877  if(!fcl.isEmpty())
878  {
879  if(l.indexOf(fcl) == -1)
880  {
881  MOUT("Unknown database name. Exec \"alldb\" command to see available databases!");
882  return;
883  }
884  }
885  MOUT(QString("Setting database to default (in console) \"%1\"...").arg(fcl));
886  databasename = fcl;
887 }
888 
889 void HDebugConsolePrivate::command_show(QString fcl)
890 {
891  QSqlDatabase db;
892  if(databasename.isEmpty())
893  db = QSqlDatabase::database();
894  else
895  db = QSqlDatabase::database(databasename);
896 
897  if(!db.isOpen())
898  {
899  MOUT("There is no opened database!");
900  return;
901  }
902 
903  if(fcl.isEmpty())
904  {
905  MOUT(QString("Tables in the %1 database:")
906  .arg(databasename.isEmpty() ? QString("default") : QString("\"%1\"").arg(databasename)));
907  cf->addText(db.tables().join("\n"),DCONSOLE_TYPE_RESULT);
908  MOUT("");
909  }
910  else
911  {
912  QSqlRecord r = db.record(fcl);
913  if(r.isEmpty())
914  MOUT(QString("There is no %1 table in %2 database")
915  .arg(fcl)
916  .arg(databasename.isEmpty() ? QString("default") : QString("\"%1\"").arg(databasename)));
917  int i = 0;
918  MOUT(QString("Fields of table: %1").arg(fcl));
919  for(i=0;i<r.count();++i)
920  {
921  cf->addText(QString("%1\t\t%2\t\t(default:%3)")
922  .arg(r.field(i).name())
923  .arg(QVariant::typeToName(r.field(i).type()))
924  .arg(r.field(i).defaultValue().toString())
925  ,DCONSOLE_TYPE_RESULT);
926  }
927  MOUT("");
928  }
929 }
930 
931 #endif // DCONSOLE_NO_SQL
932 
933 #undef MOUT
934 
935 int HDebugConsole::checkIfIClose(void)
936 {
937  bool found=false;
938  QList<QWidget *>::const_iterator i = QApplication::topLevelWidgets().begin();
939  while(i != QApplication::topLevelWidgets().end())
940  {
941  if (*i != this && (*i)->isVisible())
942  found = true;
943  ++i;
944  }
945  if(!found)
946  close();
947  return 0;
948 }
949 
950 /* *****************************************************************************
951  * *****************************************************************************
952  * HConsolePanel and related classes *
953  * *****************************************************************************
954  * ***************************************************************************** */
955 
956 //Holds a console line in memory. Only used by HConsoleLine(Private)
957 class HConsoleLine
958 {
959  friend class HConsolePanel;
960  friend class HConsolePanelPrivate;
961 
962 private:
963  HConsoleLine();
964  ~HConsoleLine();
965  HConsoleLine(QString& l,HConsoleLine *current = NULL);
966 
967  QString line;
968  char type;
969  bool autole;
970  short int width;
971  int serial;
972 
973  HConsoleLine *next;
974  HConsoleLine *prev;
975 };
976 
977 //pimpl class of HConsolePanel.
978 class HConsolePanelPrivate
979 {
980  friend class HConsolePanel;
981 
982 private:
983  HConsolePanelPrivate(HConsolePanel *ppointer) { pp = ppointer; }
984 
985 private:
986  void fitConsole(void);
987  void calcCmdLnTop(void);
988  void calcScrollBar();
989 
990  int calcStringWidth(QString s);
991  inline int calcStringBreakPos(QString s);
992  void stringReplaceTabToSpace(QString &t);
993 
994  HConsoleLine* lineObjectByDisplayPos(int inLine,char& type);
995  void getLCfromXY(int x,int y,int& l,int& c,int& scroll,char& t);
996 
997  void addTextPart(QString& t,bool hardend,char type);
998  void addLine(QString& t,bool hardend,char type);
999 
1000  void addCommandLineTextPart(QString t,bool hardend);
1001  void addCommandLineLine(QString t,bool hardend);
1002  void setCommandLineLineBySerial(int serial,QString newtext);
1003  QString commandLineLineBySerial(int serial);
1004  HConsoleLine* commandLineObjectBySerial(int serial);
1005  QString cmdLineTextSkipsel(int& new_cursor_pos);
1006 
1007  void paintRows(QPainter *p);
1008  void paintBar(QPainter *p);
1009 
1010  void hoverHandler(int x,int y);
1011 
1012 private:
1013  HConsolePanel *pp;
1014 
1015  HConsoleLine *first,*top,*viewtop,*last;
1016  HConsoleLine *cfirst,*ctop,*clast;
1017 
1018  QColor bgColor,selectionColor,fontColor,cmdLineColor,cursorColor,marginColor,marginBgColor;
1019  QMap<char,QColor> typeColors;
1020  QList<QString> history;
1021  QList<QString>::iterator history_it;
1022  QFontMetrics *fm;
1023  QString promptStr;
1024  QString marginStr;
1025 
1026  int oldWindowWidth;
1027  int marginXl,marginXlfix,marginXr;
1028  bool fastfix;
1029  int fontsize;
1030  int lineCapacity;
1031  int lineHeight;
1032  int letterWidth;
1033  int lineBreakPosition;
1034  int maxLineLength;
1035  int maxCharWidth;
1036  int selectionHeight;
1037  int lhascdiffhalf;
1038  int tabstop;
1039  int addedSpaces;
1040  bool clecho;
1041 
1042  int cursorPos[2];
1043  int origCursorPos2;
1044  char mousePressedArea;
1045  bool holdMouseButton;
1046  int mouseOldX,mouseOldY,mouseOldCursor;
1047 
1048  int sbar_length;
1049  int sbar_maxlength;
1050  int sbar_minlength;
1051  int sbar_begin,sbar_obegin;
1052 
1053  bool selection;
1054  int selectionRange[6]; //row,col->row,col original-row-col
1055  bool cselection;
1056  int cselectionRange[6]; //row,col->row,col original-row-col
1057 };
1058 
1059 HConsoleLine::HConsoleLine()
1060 {
1061  line = "";
1062  next = NULL;
1063  prev = NULL;
1064  type = 0;
1065  serial = 0;
1066  autole = true;
1067 }
1068 
1069 HConsoleLine::HConsoleLine(QString& l,HConsoleLine *current)
1070 {
1071  line = l;
1072  next = NULL;
1073  prev = current;
1074  serial = 0;
1075  autole = true;
1076  if(prev != NULL)
1077  {
1078  prev->next = this;
1079  serial = prev->serial + 1;
1080  }
1081  type = 0;
1082 }
1083 
1084 HConsoleLine::~HConsoleLine()
1085 {
1086 }
1087 
1088 HConsolePanel::HConsolePanel(QWidget *parent) : QFrame(parent)
1089 {
1090  QString s;
1091  setFocusPolicy(Qt::StrongFocus);
1092  setFocus();
1093 
1094 
1095  QFont f = font();
1096  f.setFamily("Monospace");
1097  f.setStyleHint(QFont::TypeWriter);
1098  f.setPixelSize(14);
1099  f.setBold(true);
1100  setFont(f);
1101 
1102  setMinimumSize(200,150);
1103  setCursor(Qt::IBeamCursor);
1104 
1105  p = new HConsolePanelPrivate(this);
1106  p->clecho = true;
1107  p->fm = new QFontMetrics(font(),this);
1108 
1109  p->fontsize = 14;
1110  p->bgColor = Qt::black;
1111  p->selectionColor = Qt::blue;
1112  p->fontColor = Qt::yellow;
1113  p->cmdLineColor = Qt::green;
1114  p->marginColor = QColor(240,240,240);
1115  p->marginBgColor = Qt::black;
1116  p->cursorColor = Qt::yellow;
1117 
1118  p->last = p->top = p->first = NULL;
1119  s = "";
1120  p->cfirst = new HConsoleLine(s);
1121  p->ctop = p->clast = p->cfirst;
1122  p->cursorPos[0] = p->cfirst->serial;
1123  p->cursorPos[1] = 0;
1124  p->promptStr = "Console>";
1125  p->marginStr = "";
1126  p->marginXl = p->marginXlfix = 5;
1127  p->marginXr = 10;
1128 
1129  if(QFontInfo(font()).fixedPitch())
1130  p->fastfix = true;
1131 
1132  p->oldWindowWidth = 0;
1133  p->sbar_minlength = 10;
1134  p->fitConsole();
1135 
1136  p->history.clear();
1137  p->history_it = p->history.end();
1138  p->mousePressedArea = 0;
1139  p->tabstop = 8;
1140 
1141  p->holdMouseButton = false;
1142  p->mouseOldCursor = 0;
1143  setMouseTracking(true);
1144 }
1145 
1146 HConsolePanel::~HConsolePanel(void)
1147 {
1148  HConsoleLine *d,*r = p->first;
1149  while(r != NULL)
1150  {
1151  d = r;
1152  r = r->next;
1153  delete d;
1154  }
1155 
1156  r = p->cfirst;
1157  while(r != NULL)
1158  {
1159  d = r;
1160  r = r->next;
1161  delete d;
1162  }
1163 
1164  delete p->fm; //delete QFontMetrics
1165  delete p; //delete pimpl object
1166 }
1167 
1168 int HConsolePanelPrivate::calcStringWidth(QString s)
1169 {
1170  if(fastfix)
1171  return s.length() * letterWidth;
1172  return fm->width(s);
1173 }
1174 
1175 int HConsolePanelPrivate::calcStringBreakPos(QString s)
1176 {
1177  if(fastfix)
1178  return lineBreakPosition;
1179  int ll = s.length();
1180  while(fm->width(s.left(ll)) > maxLineLength)
1181  --ll;
1182  return ll;
1183 }
1184 
1185 void HConsolePanel::setMarginText(QString margin)
1186 {
1187  p->marginStr = margin;
1188  p->fitConsole();
1189 }
1190 
1191 void HConsolePanelPrivate::fitConsole(void)
1192 {
1193  QString str;
1194  int cursorLines = 0;
1195  QString cursortxt;
1196  int displayLines = 0;
1197 
1198  cursortxt = pp->commandLineText();
1199 
1200  selection = false;
1201  cselection = false;
1202  viewtop = NULL;
1203  maxCharWidth = fm->maxWidth();
1204  lineHeight = fm->height();
1205  letterWidth = fm->averageCharWidth();
1206  lhascdiffhalf = (int) floor((lineHeight - fm->ascent()) / 2);
1207  selectionHeight = fm->ascent() + lhascdiffhalf;
1208  lineCapacity = (int) ((pp->height()-(2+1+fm->descent())) / lineHeight);
1209  marginXl = marginXlfix + calcStringWidth(marginStr);
1210  maxLineLength = pp->width() - (4 + marginXr + marginXl);
1211  lineBreakPosition = (int)floor( maxLineLength / letterWidth );
1212  mousePressedArea = 0;
1213  sbar_maxlength = pp->height() - 12;
1214 
1215  //Do automation line break/merege if the horisontal space changed
1216  if(oldWindowWidth != pp->width())
1217  {
1218  int newSerial = 0;
1219  int textwidth = 0;
1220  QString textline = "";
1221  HConsoleLine *rbegin,*rend,*r=first;
1222 
1223  oldWindowWidth = pp->width();
1224  while(r != NULL)
1225  {
1226  bool merged_basline,splitted;
1227  textline = r->line;
1228  textwidth = r->width;
1229  rbegin = r;
1230 
1231  //Merged the autowrapped rows into textline
1232  merged_basline = false;
1233  while(r->autole && r->next != NULL)
1234  {
1235  r = r->next;
1236  textline += r->line;
1237  textwidth += r->width;
1238  merged_basline = true;
1239  } //r on the last line which added to the textline
1240 
1241  //Split line if too long for the current window width
1242  splitted = false;
1243  while(!textline.isEmpty() && textwidth > maxLineLength)
1244  {
1245  int ll = calcStringBreakPos(textline);
1246 
1247  str = textline.left(ll);
1248  HConsoleLine *rnew = new HConsoleLine(str);
1249  rnew->width = calcStringWidth(rnew->line);
1250  rnew->type = rbegin->type;
1251  rnew->autole = true;
1252  rnew->serial = newSerial++;
1253 
1254  rnew->prev = rbegin->prev;
1255  rnew->next = rbegin;
1256  if(rbegin->prev != NULL)
1257  rbegin->prev->next = rnew;
1258  else
1259  first = rnew;
1260  rbegin->prev = rnew;
1261 
1262  textline = textline.mid(ll,-1);
1263  textwidth = calcStringWidth(textline);
1264  splitted = true;
1265  }
1266 
1267  if(splitted || merged_basline)
1268  {
1269  rbegin->line = textline;
1270  rbegin->width = textwidth;
1271  rbegin->autole = false;
1272  rbegin->serial = newSerial++;
1273  }
1274 
1275  if(merged_basline) //Delete old lineparts
1276  {
1277  rbegin->next = r->next; //skip from chain
1278  if(r->next != NULL)
1279  r->next->prev = rbegin;
1280 
1281  rend = r;
1282  r = r->next; //Set r for the next cycle because the current r will be deleted (it was linepart)
1283  while(rend != NULL && rend != rbegin) //free from memory
1284  {
1285  HConsoleLine *delme;
1286  delme = rend;
1287  rend = rend->prev;
1288  delete delme;
1289  }
1290  last = rbegin; //This is the last examined permanent row
1291  continue;
1292  }
1293 
1294  if(!splitted)
1295  r->serial = newSerial++;
1296  last = r; //This is the last examined row
1297  r = r->next;
1298  }
1299  }
1300 
1301  pp->setCommandLineText(cursortxt,true);
1302  cursorLines = clast->serial + 1;
1303  top = last;
1304  if(top != NULL)
1305  {
1306  while(top->prev != NULL && displayLines < (lineCapacity-(cursorLines+1)))
1307  {
1308  top = top->prev;
1309  ++displayLines;
1310  }
1311  ++displayLines; //because the upper cycle doesn't count the *top line.
1312  }
1313 
1314  calcScrollBar();
1315  calcCmdLnTop();
1316 }
1317 
1318 void HConsolePanelPrivate::calcScrollBar()
1319 {
1320  if(last == NULL || last->serial + 1 < lineCapacity)
1321  {
1322  sbar_begin = 0;
1323  sbar_length = sbar_maxlength;
1324  }
1325  else
1326  {
1327  sbar_length = int((double(lineCapacity) / double(last->serial + 1)) * double(sbar_maxlength));
1328  if(sbar_length < sbar_minlength)
1329  sbar_length = sbar_minlength;
1330  sbar_begin = int((double((viewtop != NULL ? viewtop->serial : top->serial)) / double(top->serial)) * double(sbar_maxlength-sbar_length));
1331  }
1332 }
1333 
1334 void HConsolePanelPrivate::calcCmdLnTop(void)
1335 {
1336  HConsoleLine *cr = clast;
1337  int ll = 0;
1338  int displayLines = 0;
1339  if(last != NULL)
1340  displayLines = last->serial - top->serial + 1;
1341  while(cr->prev != NULL)
1342  {
1343  if(displayLines + ll++ >= lineCapacity && cursorPos[0] >= cr->serial)
1344  break;
1345  cr = cr->prev;
1346  }
1347  ctop = cr;
1348 }
1349 
1351 {
1352  p->clecho = !disable;
1353 }
1354 
1355 void HConsolePanel::paintEvent(QPaintEvent *e)
1356 {
1357  Q_UNUSED(e);
1358  QPainter *painter = new QPainter(this);
1359  p->paintRows(painter);
1360  p->paintBar(painter);
1361  painter->end();
1362  delete painter;
1363 }
1364 
1365 void HConsolePanelPrivate::paintRows(QPainter *p)
1366 {
1367  int x=0,y=2;
1368  char cmdline;
1369  int l;
1370  bool mSelSign;
1371  int *mSelRange;
1372 
1373  p->fillRect(0,0,pp->width(),pp->height(),bgColor);
1374  x = marginXl;
1375  y += lineHeight;
1376 
1377  HConsoleLine* r;
1378  l = 0;
1379  for(cmdline = 0;cmdline < 2;++cmdline)
1380  {
1381  if(!cmdline)
1382  {
1383  r = viewtop == NULL ? top : viewtop;
1384  mSelSign = selection;
1385  mSelRange = selectionRange;
1386  }
1387  else
1388  {
1389  r = ctop;
1390  mSelSign = cselection;
1391  mSelRange = cselectionRange;
1392  if(!clecho)
1393  {
1394  r = NULL;
1395  p->setPen(cmdLineColor);
1396  p->drawText(x,y,promptStr);
1397  }
1398  }
1399 
1400  if(cmdline || viewtop != NULL || lineCapacity > clast->serial + 1)
1401  while(r != NULL)
1402  {
1403  if(mSelSign && mSelRange[0] == r->serial && mSelRange[2] == r->serial) //selection begin-end
1404  {
1405  int ss,ee;
1406  ss=mSelRange[1];
1407  if(ss < 0)
1408  ss = 0;
1409  ee = mSelRange[3];
1410  if(ee > r->line.length())
1411  ee = r->line.length();
1412 
1413  p->fillRect(x+calcStringWidth((cmdline && r == cfirst ? promptStr : QString()) + r->line.left(ss)),
1414  y-selectionHeight,
1415  calcStringWidth(r->line.left(ee).mid(ss,-1)),
1416  selectionHeight+lhascdiffhalf,
1417  selectionColor);
1418 
1419  }
1420  else if(mSelSign && mSelRange[0] == r->serial) //selection begin
1421  {
1422  int ss = mSelRange[1];
1423  if(ss < 0)
1424  ss = 0;
1425 
1426  p->fillRect(x+calcStringWidth((cmdline && r == cfirst ? promptStr : QString()) + r->line.left(ss)),
1427  y-selectionHeight,
1428  calcStringWidth(r->line) - calcStringWidth((r->line).left(ss)),
1429  selectionHeight+lhascdiffhalf,selectionColor);
1430  }
1431  else if(mSelSign && mSelRange[0] < r->serial && mSelRange[2] > r->serial) //selection in
1432  {
1433  p->fillRect(x,y-selectionHeight,
1434  calcStringWidth(r->line),selectionHeight+lhascdiffhalf,selectionColor);
1435  }
1436  else if(mSelSign && mSelRange[2] == r->serial) //selection end
1437  {
1438  int ee = mSelRange[3];
1439  if(ee > r->line.length())
1440  ee = r->line.length();
1441 
1442  p->fillRect(x,y-selectionHeight,
1443  calcStringWidth(r->line.left(ee)),selectionHeight+lhascdiffhalf,selectionColor);
1444  }
1445 
1446  p->setPen(marginColor);
1447  if(!cmdline)
1448  {
1449  if(!marginStr.isEmpty())
1450  {
1451  QString s = marginStr;
1452  s.replace(QRegExp("%[0]*s"),QString("%1").arg(r->serial+1));
1453  p->fillRect(0,y-selectionHeight,marginXl-marginXlfix,lineHeight+lhascdiffhalf,marginBgColor);
1454  p->drawText(0,y,s);
1455  }
1456  if(r->type == 0)
1457  p->setPen(fontColor);
1458  else
1459  p->setPen(typeColors.find(r->type) == typeColors.end() ? fontColor : typeColors[r->type] );
1460  p->drawText(x,y,r->line);
1461  }
1462  else
1463  {
1464  if(cursorPos[0] == r->serial && pp->hasFocus())
1465  {
1466  int xpos;
1467  p->setPen(cursorColor);
1468  xpos = x+calcStringWidth(r->line.left(cursorPos[1]))+calcStringWidth(r == cfirst ? promptStr : QString(""));
1469  p->drawLine(xpos,y-selectionHeight,xpos,y+lhascdiffhalf);
1470  p->drawLine(xpos+1,y-selectionHeight,xpos+1,y+lhascdiffhalf);
1471  }
1472  p->setPen(cmdLineColor);
1473  p->drawText(x,y,(r == cfirst ? promptStr : QString("")) + r->line);
1474  }
1475 
1476  y += lineHeight;
1477  r = r->next;
1478 
1479  if(++l >= lineCapacity)
1480  return;
1481  }
1482  }
1483 }
1484 
1485 void HConsolePanelPrivate::paintBar(QPainter *p)
1486 {
1487  p->setPen(QColor(150,150,150));
1488  p->setBrush(QBrush(QColor(50,50,50),Qt::SolidPattern));
1489  p->drawRoundedRect(marginXl+maxLineLength+2,4,marginXr,pp->height()-8,5,5);
1490  p->setBrush(QBrush(QColor(150,150,150),Qt::SolidPattern));
1491  p->drawRoundedRect(marginXl+maxLineLength+4,6+sbar_begin,marginXr-4,sbar_length,3,3);
1492  p->setBrush(Qt::NoBrush);
1493 }
1494 
1495 void HConsolePanel::setColor(QString section,QColor color)
1496 {
1497  if(section == "background")
1498  p->bgColor = color;
1499  if(section == "selection")
1500  p->selectionColor = color;
1501  if(section == "standardtext")
1502  p->fontColor = color;
1503  if(section == "cmdtext")
1504  p->cmdLineColor = color;
1505  if(section == "margin")
1506  p->marginColor = color;
1507  if(section == "cursor")
1508  p->cursorColor = color;
1509  if(section == "marginbg")
1510  p->marginBgColor = color;
1511 }
1512 
1513 void HConsolePanel::setTextTypeColor(char type,QColor color)
1514 {
1515  p->typeColors[type] = color;
1516 }
1517 
1519 {
1520  addText(text);
1521 }
1522 
1524 {
1525  p->tabstop = count;
1526 }
1527 
1528 void HConsolePanel::addText(QString t,char type)
1529 {
1530  p->addedSpaces = 0;
1531  if(t.contains("\n"))
1532  {
1533  QStringList lines = t.split("\n");
1534  QList<QString>::iterator i=lines.begin();
1535  for(;i!=lines.end();++i)
1536  p->addTextPart(*i,true,type);
1537  }
1538  else
1539  p->addTextPart(t,true,type);
1540  p->calcScrollBar();
1541  update();
1542 }
1543 
1544 void HConsolePanelPrivate::stringReplaceTabToSpace(QString &t)
1545 {
1546  int fl,tp;
1547  while((tp = t.indexOf("\t")) != -1)
1548  {
1549  fl = int( ceil(double(tp)/double(tabstop)) * tabstop) - tp;
1550  if(fl == 0)
1551  fl = tabstop;
1552  addedSpaces += fl - 1;
1553  t.replace(tp,1,QString().fill(' ',fl));
1554  }
1555 }
1556 
1557 void HConsolePanelPrivate::addTextPart(QString& t,bool hardend,char type)
1558 {
1559  stringReplaceTabToSpace(t);
1560  if(maxLineLength < calcStringWidth(t))
1561  {
1562  QString fitted,leaved;
1563  int s = calcStringBreakPos(t);
1564  fitted = t.left(s);
1565  leaved = t.mid(s,-1);
1566  addLine(fitted,false,type);
1567  addTextPart(leaved,hardend,type);
1568  return;
1569  }
1570  addLine(t,hardend,type);
1571 }
1572 
1573 void HConsolePanelPrivate::addLine(QString& t,bool hardend,char type)
1574 {
1575  viewtop = NULL;
1576  last = new HConsoleLine(t,last);
1577  if(first == NULL)
1578  first = top = last;
1579  last->width = calcStringWidth(t);
1580  last->type = type;
1581  if(hardend)
1582  last->autole = false;
1583 
1584  if(last->serial - top->serial + 1 >= lineCapacity)
1585  top = top->next;
1586 }
1587 
1589 {
1590  HConsoleLine *d,*r = p->first;
1591  while(r != NULL)
1592  {
1593  d = r;
1594  r = r->next;
1595  delete d;
1596  }
1597  p->top = p->first = p->last = NULL;
1598  p->fitConsole();
1599  update();
1600 }
1601 
1602 void HConsolePanel::resizeEvent(QResizeEvent *e)
1603 {
1604  p->fitConsole();
1605  QFrame::resizeEvent(e);
1606 }
1607 
1608 void HConsolePanel::scrollUp(int lineCount)
1609 {
1610  for(;lineCount > 0;--lineCount)
1611  {
1612  if(p->viewtop == NULL)
1613  {
1614  if(p->top != NULL)
1615  p->viewtop = p->top->prev;
1616  }
1617  else
1618  {
1619  if(p->viewtop->prev != NULL)
1620  p->viewtop = p->viewtop->prev;
1621  if(p->viewtop == p->top)
1622  p->viewtop = NULL;
1623  }
1624  }
1625  p->calcScrollBar();
1626  update();
1627 }
1628 
1629 void HConsolePanel::scrollDown(int lineCount)
1630 {
1631  for(;lineCount > 0;--lineCount)
1632  {
1633  if(p->viewtop != NULL)
1634  {
1635  if(p->viewtop->next == p->top)
1636  p->viewtop = NULL;
1637  else
1638  p->viewtop = p->viewtop->next;
1639  if(p->viewtop == p->top)
1640  p->viewtop = NULL;
1641  }
1642  }
1643  p->calcScrollBar();
1644  update();
1645 }
1646 
1648 {
1649  p->viewtop = p->first;
1650  p->calcScrollBar();
1651  update();
1652 }
1653 
1655 {
1656  p->viewtop = NULL;
1657  p->calcScrollBar();
1658  update();
1659 }
1660 
1662 {
1663  p->viewtop = NULL;
1664  HConsoleLine *r = p->first;
1665  while(r != NULL && r->serial < p->top->serial)
1666  {
1667  if(r->serial == serial)
1668  {
1669  p->viewtop = r;
1670  break;
1671  }
1672  r = r->next;
1673  }
1674  p->calcScrollBar();
1675  update();
1676 }
1677 
1679 {
1680  if(p->last == NULL)
1681  return -1;
1682  return p->last->serial;
1683 }
1684 
1686 {
1687  if(p->top == NULL)
1688  return -1;
1689  return p->viewtop == NULL ? p->top->serial : p->viewtop->serial;
1690 }
1691 
1692 QString HConsolePanel::lineBySerial(int serial,bool withWraps,bool onDisplay)
1693 {
1694  HConsoleLine* r = p->first;
1695  if(onDisplay)
1696  r = p->viewtop == NULL ? p->top : p->viewtop;
1697  if(serial == -1)
1698  return QString();
1699  while(r != NULL)
1700  {
1701  if(r->serial == serial)
1702  {
1703  if(withWraps && r->autole)
1704  {
1705  QString rline = r->line;
1706  while(r->autole && r->next != NULL )
1707  {
1708  rline += r->next->line;
1709  r = r->next;
1710  }
1711  return rline;
1712  }
1713  return r->line;
1714  }
1715  r = r->next;
1716  }
1717  return QString();
1718 }
1719 
1721 {
1722  if(p->first == NULL)
1723  return;
1724  p->selectionRange[0] = p->first->serial;
1725  p->selectionRange[1] = 0;
1726  p->selectionRange[2] = p->last->serial;
1727  p->selectionRange[3] = p->last->line.length();
1728  p->selection = true;
1729  p->cselection = false;
1730  update();
1731 }
1732 
1734 {
1735  p->selection = false;
1736  p->cselection = false;
1737 }
1738 
1740 {
1741  if(!p->selection && !p->cselection)
1742  return QString();
1743 
1744  int *mSelRange=NULL;
1745  QString sel="";
1746  HConsoleLine* r=NULL;
1747 
1748  if(p->cselection)
1749  {
1750  mSelRange = p->cselectionRange;
1751  r = p->cfirst;
1752  }
1753  if(p->selection)
1754  {
1755  mSelRange = p->selectionRange;
1756  r = p->first;
1757  }
1758  if(mSelRange == NULL)
1759  return QString();
1760  while(r != NULL)
1761  {
1762  if(mSelRange[0] == r->serial && mSelRange[2] == r->serial) //selection begin-end
1763  {
1764  int ss,ee;
1765  ss=mSelRange[1];
1766  if(ss < 0)
1767  ss = 0;
1768  ee = mSelRange[3];
1769  if(ee > r->line.length())
1770  ee = r->line.length();
1771 
1772  return r->line.left(ee).mid(ss,-1);
1773  }
1774  else if(mSelRange[0] == r->serial) //selection begin
1775  {
1776  int ss = mSelRange[1];
1777  if(ss < 0)
1778  ss = 0;
1779  sel += r->line.mid(ss,-1) + (r->autole ? "" : "\n");
1780 
1781  }
1782  else if(mSelRange[0] < r->serial && mSelRange[2] > r->serial) //selection in
1783  {
1784  sel += r->line + (r->autole ? "" : "\n");
1785  }
1786  else if(mSelRange[2] == r->serial) //selection end
1787  {
1788  int ee = mSelRange[3];
1789  if(ee > r->line.length())
1790  ee = r->line.length();
1791 
1792  sel += r->line.left(ee);
1793  return sel;
1794  }
1795  r = r->next;
1796  }
1797  return sel;
1798 }
1799 
1801 {
1802  if(!p->selection && !p->cselection)
1803  return;
1804  QClipboard * cb = QApplication::clipboard();
1805  cb->setText(selectedText());
1806 }
1807 
1808 HConsoleLine* HConsolePanelPrivate::lineObjectByDisplayPos(int inLine,char& type)
1809 {
1810  HConsoleLine* r = viewtop == NULL ? top : viewtop;
1811  type = 1;
1812  int ll = 0;
1813 
1814  if(viewtop != NULL || lineCapacity > clast->serial + 1)
1815  while(r != NULL)
1816  {
1817  if(ll == inLine)
1818  return r;
1819  r = r->next;
1820  ++ll;
1821  }
1822  type = 2;
1823  r = ctop;
1824  while(r != NULL)
1825  {
1826  if(ll == inLine)
1827  return r;
1828  r = r->next;
1829  ++ll;
1830  }
1831  type = 0;
1832  return NULL;
1833 }
1834 
1835 void HConsolePanelPrivate::getLCfromXY(int x,int y,int& l,int& c,int& scroll,char& t)
1836 {
1837  int displayLines = 0;
1838  int dl,sl;
1839  HConsoleLine *lineObj;
1840 
1841  if(last != NULL)
1842  displayLines = last->serial - ( viewtop != NULL ? viewtop->serial : top->serial ) + 1;
1843  if(displayLines > lineCapacity)
1844  displayLines = lineCapacity;
1845 
1846  scroll = 0;
1847  if(x<0)
1848  x = 0;
1849  if(t == 0 && x > marginXl + maxLineLength )
1850  {
1851  t = 0;
1852  l = 0; c = 0;
1853  scroll = 0;
1854  return;
1855  }
1856  if(y<0)
1857  {
1858  y = 0;
1859  if(top->serial > 0)
1860  scroll = -1;
1861  }
1862 
1863  dl = (int) floor((y-2)/lineHeight);
1864  if(t == 1 && dl>displayLines-1)
1865  {
1866  dl = displayLines-1;
1867  if(viewtop != NULL && viewtop->serial < top->serial)
1868  scroll = 1;
1869  }
1870  if((t == 0 || t == 2) && dl > displayLines+clast->serial)
1871  {
1872  dl = displayLines+clast->serial;
1873  if(cfirst != ctop)
1874  scroll = 1;
1875  }
1876  lineObj = lineObjectByDisplayPos(dl,t);
1877  if(lineObj == NULL)
1878  {
1879  l = 0; c = 0; t = 0;
1880  return;
1881  }
1882  l = lineObj->serial;
1883  if(lineObj->line.isEmpty())
1884  {
1885  c = 0;
1886  return;
1887  }
1888  QString prefix="";
1889  if(lineObj == cfirst)
1890  prefix = promptStr;
1891  sl = lineObj->line.length();
1892  for( c=1 ; calcStringWidth(prefix + lineObj->line.left(c)) - calcStringWidth(lineObj->line.at(c-1))/2 < x - marginXl ; ++c )
1893  if(sl <= c)
1894  {
1895  c = sl;
1896  return;
1897  }
1898  --c; //because the selection ponint placewd _before_ the numberred character.
1899  return;
1900 }
1901 
1902 void HConsolePanel::mousePressEvent(QMouseEvent *e)
1903 {
1904  if(e->button() != Qt::LeftButton)
1905  return;
1906 
1907  int l,c,scroll;
1908  char type;
1909  type = 0;
1910  p->getLCfromXY(e->x(),e->y(),l,c,scroll,type);
1911  p->mousePressedArea = type;
1912  p->holdMouseButton = true;
1913  if(type == 0)
1914  {
1915  p->mouseOldX = e->x();
1916  p->mouseOldY = e->y();
1917  p->sbar_obegin = p->sbar_begin;
1918  return;
1919  }
1920  if(type == 2 && scroll == 0)
1921  {
1922  p->cursorPos[0] = l;
1923  p->cursorPos[1] = c;
1924  p->origCursorPos2 = p->cursorPos[1];
1925  }
1926  if(type == 1)
1927  {
1928  p->selectionRange[4] = p->selectionRange[0] = l; //fromRow
1929  p->selectionRange[5] = p->selectionRange[1] = c; //fromRow
1930  }
1931  if(type == 2)
1932  {
1933  p->cselectionRange[4] = p->cselectionRange[0] = l; //fromRow
1934  p->cselectionRange[5] = p->cselectionRange[1] = c; //fromRow
1935  }
1936  p->selection = false;
1937  p->cselection = false;
1938  update();
1939 }
1940 
1941 void HConsolePanel::mouseReleaseEvent(QMouseEvent *e)
1942 {
1943  p->holdMouseButton = false;
1944  p->mousePressedArea = 0;
1945 
1946  if(e->button() == Qt::RightButton)
1947  {
1948  QMenu *m=new QMenu(this);
1949  m->addAction(tr("Scroll to top"),this,SLOT(scrollTop()));
1950  m->addAction(tr("Scroll to bottom"),this,SLOT(scrollReset()));
1951  m->addSeparator();
1952  m->addAction(tr("Select all"),this,SLOT(selectAll()));
1953  m->addAction(tr("Clear selection"),this,SLOT(clearSelection()));
1954  m->addSeparator();
1955  m->addAction(tr("Copy"),this,SLOT(copySelection()));
1956  m->addAction(tr("Paste to command line"),this,SLOT(pasteToCommandLine()));
1957  m->addSeparator();
1958  m->addAction(tr("Clear all text"),this,SLOT(clearText()));
1959 
1960  m->exec(mapToGlobal(e->pos()));
1961  delete m;
1962  }
1963 }
1964 
1965 void HConsolePanelPrivate::hoverHandler(int x,int y)
1966 {
1967  if(x < 0 && x > pp->width())
1968  {
1969  mouseOldCursor = 0;
1970  return;
1971  }
1972  if(x > 0 && x < marginXl+maxLineLength && mouseOldCursor != 1)
1973  {
1974  pp->setCursor(Qt::IBeamCursor);
1975  mouseOldCursor = 1;
1976  return;
1977  }
1978  if(x > marginXl+maxLineLength && x < pp->width() && mouseOldCursor != 2)
1979  {
1980  pp->setCursor(Qt::PointingHandCursor);
1981  mouseOldCursor = 2;
1982  return;
1983  }
1984 }
1985 
1986 void HConsolePanel::mouseMoveEvent(QMouseEvent *e)
1987 {
1988  if(!p->holdMouseButton)
1989  {
1990  p->hoverHandler(e->x(),e->y());
1991  return;
1992  }
1993 
1994  int l,c,s;
1995  char type;
1996  if(p->mousePressedArea == 0)
1997  {
1998  if(p->mouseOldX > p->marginXl + p->maxLineLength + 2 &&
1999  p->mouseOldX < p->marginXl + p->maxLineLength + 2 + p->marginXr &&
2000  p->mouseOldY > 2 &&
2001  p->mouseOldY < height() - 2)
2002  {
2003  int nb = p->sbar_obegin + (e->y() - p->mouseOldY);
2004  if(nb < 0)
2005  nb = 0;
2006  if(nb > p->sbar_maxlength)
2007  nb = p->sbar_maxlength;
2008  scrollToSerial(int((double(nb)/ double(p->sbar_maxlength-p->sbar_length))*double(p->top->serial)));
2009  }
2010  return;
2011  }
2012 
2013  type = p->mousePressedArea;
2014  p->getLCfromXY(e->x(),e->y(),l,c,s,type);
2015  if(s == -1)
2016  {
2017  scrollUp(1);
2018  p->getLCfromXY(e->x(),e->y(),l,c,s,type);
2019  }
2020  if(s == 1)
2021  {
2022  scrollDown(1);
2023  p->getLCfromXY(e->x(),e->y(),l,c,s,type);
2024  }
2025 
2026  if(type == 0)
2027  return;
2028 
2029  int *mSelRange = NULL;
2030  bool sel=false;
2031  if(type == 1)
2032  {
2033  sel = p->selection;
2034  mSelRange = p->selectionRange;
2035  }
2036  if(type == 2)
2037  {
2038  sel = p->cselection;
2039  mSelRange = p->cselectionRange;
2040  }
2041 
2042  if(mSelRange == NULL)
2043  return;
2044  if(!sel || mSelRange[2] != l || mSelRange[3] != c)
2045  {
2046  if(mSelRange[4] < l || (mSelRange[4] == l && mSelRange[5] < c))
2047  {
2048  mSelRange[2] = l;
2049  mSelRange[3] = c;
2050  mSelRange[0] = mSelRange[4];
2051  mSelRange[1] = mSelRange[5];
2052  }
2053  else
2054  {
2055  mSelRange[0] = l;
2056  mSelRange[1] = c;
2057  mSelRange[2] = mSelRange[4];
2058  mSelRange[3] = mSelRange[5];
2059  }
2060 
2061  p->selection = type == 1 ? true : false;
2062  p->cselection = type == 2 ? true : false;
2063  update();
2064  }
2065 }
2066 
2067 void HConsolePanel::mouseDoubleClickEvent(QMouseEvent *e)
2068 {
2069  if(e->button() != Qt::LeftButton)
2070  return;
2071 
2072  int l,c,i,s;
2073  int *mSelRange = NULL;
2074  char type;
2075  type = 0;
2076  p->getLCfromXY(e->x(),e->y(),l,c,s,type);
2077  if(type == 0 || s != 0)
2078  {
2079  p->selection = false;
2080  p->cselection = false;
2081  update();
2082  return;
2083  }
2084 
2085  QString line;
2086  if(type == 1)
2087  {
2088  line = lineBySerial(l,false,true);
2089  mSelRange = p->selectionRange;
2090  }
2091  if(type == 2)
2092  {
2093  line = p->commandLineLineBySerial(l);
2094  mSelRange = p->cselectionRange;
2095  }
2096 
2097  if(c >= line.length() || line.at(c).isSpace())
2098  {
2099  p->selection = false;
2100  p->cselection = false;
2101  update();
2102  return;
2103  }
2104 
2105  if(mSelRange == NULL)
2106  return;
2107 
2108  mSelRange[0] = l;
2109  mSelRange[2] = l;
2110  mSelRange[1] = 0;
2111 
2112  for(i=c;i>0;--i)
2113  if(line.at(i).isSpace())
2114  {
2115  mSelRange[1] = i+1;
2116  break;
2117  }
2118 
2119  mSelRange[3] = line.length();
2120  for(i=c;i<line.length();++i)
2121  if(line.at(i).isSpace())
2122  {
2123  mSelRange[3] = i;
2124  break;
2125  }
2126 
2127  p->selection = type == 1 ? true : false;
2128  p->cselection = type == 2 ? true : false;
2129  update();
2130 }
2131 
2132 HConsoleLine* HConsolePanelPrivate::commandLineObjectBySerial(int serial)
2133 {
2134  HConsoleLine* r = cfirst;
2135  if(serial == -1)
2136  return NULL;
2137  while(r != NULL)
2138  {
2139  if(r->serial == serial)
2140  return r;
2141  r = r->next;
2142  }
2143  return NULL;
2144 }
2145 
2146 QString HConsolePanelPrivate::commandLineLineBySerial(int serial)
2147 {
2148  HConsoleLine* r = commandLineObjectBySerial(serial);
2149  if(r == NULL)
2150  return QString();
2151  return r->line;
2152 }
2153 
2154 void HConsolePanelPrivate::setCommandLineLineBySerial(int serial,QString newtext)
2155 {
2156  HConsoleLine* r = cfirst;
2157  if(serial == -1)
2158  return;
2159  while(r != NULL)
2160  {
2161  if(r->serial == serial)
2162  {
2163  r->line = newtext;
2164  return;
2165  }
2166  r = r->next;
2167  }
2168 }
2169 
2171 {
2172  p->cfirst->line = "";
2173  HConsoleLine *todel=NULL,*cr = p->cfirst->next;
2174  while(cr != NULL)
2175  {
2176  todel = cr;
2177  cr = cr->next;
2178  delete todel;
2179  }
2180  p->cfirst->next = NULL; //we just erased above
2181  p->ctop = p->clast = p->cfirst;
2182  p->cfirst->autole = true;
2183  p->cursorPos[0] = p->cfirst->serial;
2184  p->cursorPos[1] = 0;
2185  p->origCursorPos2 = p->cursorPos[1];
2186  p->calcCmdLnTop();
2187 }
2188 
2189 void HConsolePanel::setCommandLineText(QString t,bool disableupdate)
2190 {
2191  resetCommandLine();
2192  p->viewtop = NULL;
2193  p->calcScrollBar();
2194  if(!t.isEmpty())
2195  {
2196  if(t.contains("\n"))
2197  {
2198  QStringList lines = t.split("\n");
2199  QList<QString>::iterator i=lines.begin();
2200  for(;i!=lines.end();++i)
2201  p->addCommandLineTextPart(*i,true);
2202  }
2203  else
2204  p->addCommandLineTextPart(t,true);
2205  }
2206  p->cursorPos[0] = p->clast->serial;
2207  p->cursorPos[1] = p->clast->line.length();
2208  p->origCursorPos2 = p->cursorPos[1];
2209  if(!disableupdate)
2210  {
2211  p->fitConsole();
2212  update();
2213  }
2214 }
2215 
2216 void HConsolePanelPrivate::addCommandLineTextPart(QString t,bool hardend)
2217 {
2218  stringReplaceTabToSpace(t);
2219  if(maxLineLength < calcStringWidth( (cfirst == clast && cfirst->line.isEmpty() ? promptStr : QString()) + t ))
2220  {
2221  int s = calcStringBreakPos( (cfirst == clast && cfirst->line.isEmpty() ? promptStr : QString()) + t );
2222  s -= (cfirst == clast && cfirst->line.isEmpty() ? promptStr.length() : 0);
2223  addCommandLineLine(t.left(s),false);
2224  addCommandLineTextPart(t.mid(s,-1),hardend);
2225  return;
2226  }
2227  addCommandLineLine(t,hardend);
2228 }
2229 
2230 void HConsolePanelPrivate::addCommandLineLine(QString t,bool hardend)
2231 {
2232  if(cfirst->next == NULL && cfirst == clast && cfirst->line.isEmpty())
2233  {
2234  cfirst->line = t;
2235  cfirst->autole = !hardend;
2236  }
2237  else
2238  {
2239  clast = new HConsoleLine(t,clast);
2240  if(hardend)
2241  clast->autole = false;
2242  }
2243 }
2244 
2246 {
2247  QString c = QString();
2248  HConsoleLine* cr = p->cfirst;
2249  while(cr != NULL)
2250  {
2251  c += cr->line + ((cr->next != NULL && !cr->autole) ? "\n" : "");
2252  cr = cr->next;
2253  }
2254  return c;
2255 }
2256 
2258 {
2259  int cp=0;
2260  HConsoleLine* cr = p->cfirst;
2261  while(cr != NULL)
2262  {
2263  if(p->cursorPos[0] > cr->serial)
2264  cp += ( cr->line.length() + (cr->autole ? 0 : 1) );
2265  if(p->cursorPos[0] == cr->serial)
2266  return cp + p->cursorPos[1];
2267  cr = cr->next;
2268  }
2269  return -1;
2270 }
2271 
2273 {
2274  if(c == -1)
2275  return;
2276  HConsoleLine* cr = p->cfirst;
2277  while(cr != NULL)
2278  {
2279  if(c > cr->line.length())
2280  c -= ( cr->line.length() + (cr->autole ? 0 : 1) );
2281  else
2282  {
2283  p->cursorPos[0] = cr->serial;
2284  p->cursorPos[1] = c;
2285  p->origCursorPos2 = p->cursorPos[1];
2286  return;
2287  }
2288  cr = cr->next;
2289  }
2290  p->calcCmdLnTop();
2291 }
2292 
2294 {
2295  if(p->cursorPos[0] == p->clast->serial &&
2296  !text.contains("\n") &&
2297  !text.contains("\t") &&
2298  !p->cselection &&
2299  p->maxLineLength > p->calcStringWidth(
2300  (p->cursorPos[0] == p->cfirst->serial ? p->promptStr : QString()) +
2301  p->clast->line + text )
2302  )
2303  {
2304  //Fast insert/add method (run when the cursor stay in the row)
2305  if(p->cursorPos[1] == p->clast->line.length())
2306  p->clast->line.append(text);
2307  else
2308  p->clast->line.insert(p->cursorPos[1],text);
2309 
2310  p->clast->width = p->calcStringWidth(p->clast->line);
2311  p->cursorPos[1] += text.length();
2312  p->origCursorPos2 = p->cursorPos[1];
2313  update();
2314  return;
2315  }
2316 
2317  int abs;
2318  QString c;
2319  abs = cursorPosition();
2320  c = p->cselection ? p->cmdLineTextSkipsel(abs) : commandLineText();
2321  c.insert(abs,text);
2322  p->addedSpaces = 0;
2323  setCommandLineText(c);
2324  setCursorPosition(abs+text.length()+p->addedSpaces);
2325  p->calcCmdLnTop();
2326  p->cselection = false;
2327  p->addedSpaces = 0;
2328  update();
2329 }
2330 
2331 void HConsolePanel::deleteFromCursor(bool forwardDel)
2332 {
2333  if(p->cselection)
2334  {
2336  return;
2337  }
2338 
2339  if(p->cursorPos[0] == p->clast->serial)
2340  {
2341  if(p->cfirst == p->clast && p->clast->line.isEmpty())
2342  return;
2343 
2344  if(!forwardDel && p->cursorPos[1] > 0)
2345  {
2346  p->clast->line.remove(p->cursorPos[1]-1,1);
2347  p->cursorPos[1] = p->cursorPos[1] - 1;
2348  p->origCursorPos2 = p->cursorPos[1];
2349  update();
2350  return;
2351  }
2352  if(forwardDel)
2353  {
2354  if(p->cursorPos[1] >= p->clast->line.length())
2355  return;
2356  p->clast->line.remove(p->cursorPos[1],1);
2357  p->origCursorPos2 = p->cursorPos[1];
2358  update();
2359  return;
2360  }
2361  }
2362 
2363  int abs;
2364  QString c;
2365  c = commandLineText();
2366  abs = cursorPosition();
2367 
2368  if(!forwardDel && abs > 0)
2369  {
2370  --abs;
2371  c.remove(abs,1);
2372  }
2373 
2374  if(forwardDel && abs < c.length())
2375  c.remove(abs,1);
2376 
2377  setCommandLineText(c);
2378  setCursorPosition(abs);
2379  p->calcCmdLnTop();
2380  update();
2381 }
2382 
2384 {
2385  if(!p->cselection)
2386  return;
2387 
2388  int abs;
2389  QString c;
2390  c = p->cmdLineTextSkipsel(abs);
2391  setCommandLineText(c);
2392  setCursorPosition(abs);
2393  p->calcCmdLnTop();
2394  p->cselection = false;
2395  update();
2396 }
2397 
2398 void HConsolePanel::cursorLeft(int charCount,bool inSelection)
2399 {
2400  HConsoleLine *l;
2401 
2402  if(!inSelection)
2403  p->cselection = false;
2404 
2405  if(inSelection && !p->cselection)
2406  {
2407  p->cselectionRange[0] = p->cursorPos[0];
2408  p->cselectionRange[1] = p->cursorPos[1];
2409  p->cselectionRange[4] = p->cursorPos[0];
2410  p->cselectionRange[5] = p->cursorPos[1];
2411  }
2412 
2413  for(;charCount > 0;--charCount)
2414  {
2415  if(p->cursorPos[1] > 0)
2416  {
2417  --p->cursorPos[1];
2418  }
2419  else if(p->cursorPos[0] > p->cfirst->serial)
2420  {
2421  --p->cursorPos[0];
2422  l = p->commandLineObjectBySerial(p->cursorPos[0]);
2423  p->cursorPos[1] = l == NULL ? 0 : l->line.length();
2424  }
2425  }
2426 
2427  p->origCursorPos2 = p->cursorPos[1];
2428 
2429  if(inSelection)
2430  {
2431  if(p->cselectionRange[4] < p->cursorPos[0] ||
2432  (p->cselectionRange[4] == p->cursorPos[0] && p->cselectionRange[5] < p->cursorPos[1]))
2433  {
2434  p->cselectionRange[2] = p->cursorPos[0];
2435  p->cselectionRange[3] = p->cursorPos[1];
2436  p->cselectionRange[0] = p->cselectionRange[4];
2437  p->cselectionRange[1] = p->cselectionRange[5];
2438  }
2439  else
2440  {
2441  p->cselectionRange[0] = p->cursorPos[0];
2442  p->cselectionRange[1] = p->cursorPos[1];
2443  p->cselectionRange[2] = p->cselectionRange[4];
2444  p->cselectionRange[3] = p->cselectionRange[5];
2445  }
2446  p->cselection = true;
2447  p->selection = false;
2448  }
2449  p->calcCmdLnTop();
2450  update();
2451 }
2452 
2453 void HConsolePanel::cursorRight(int charCount,bool inSelection)
2454 {
2455  HConsoleLine *l;
2456 
2457  if(!inSelection)
2458  p->cselection = false;
2459 
2460  if(inSelection && !p->cselection)
2461  {
2462  p->cselectionRange[0] = p->cursorPos[0];
2463  p->cselectionRange[1] = p->cursorPos[1];
2464  p->cselectionRange[4] = p->cursorPos[0];
2465  p->cselectionRange[5] = p->cursorPos[1];
2466  }
2467 
2468  for(;charCount > 0;--charCount)
2469  {
2470  l = p->commandLineObjectBySerial(p->cursorPos[0]);
2471  if(l == NULL)
2472  return;
2473  if(p->cursorPos[0] == p->clast->serial)
2474  {
2475  if(p->cursorPos[1] < l->line.length())
2476  {
2477  ++p->cursorPos[1];
2478  }
2479  }
2480  else
2481  {
2482  if(p->cursorPos[1] < l->line.length())
2483  {
2484  ++p->cursorPos[1];
2485  }
2486  else
2487  {
2488  ++p->cursorPos[0];
2489  p->cursorPos[1] = 0;
2490  }
2491  }
2492  }
2493 
2494  p->origCursorPos2 = p->cursorPos[1];
2495 
2496  if(inSelection)
2497  {
2498  if(p->cselectionRange[4] < p->cursorPos[0] ||
2499  (p->cselectionRange[4] == p->cursorPos[0] && p->cselectionRange[5] < p->cursorPos[1]))
2500  {
2501  p->cselectionRange[2] = p->cursorPos[0];
2502  p->cselectionRange[3] = p->cursorPos[1];
2503  p->cselectionRange[0] = p->cselectionRange[4];
2504  p->cselectionRange[1] = p->cselectionRange[5];
2505  }
2506  else
2507  {
2508  p->cselectionRange[0] = p->cursorPos[0];
2509  p->cselectionRange[1] = p->cursorPos[1];
2510  p->cselectionRange[2] = p->cselectionRange[4];
2511  p->cselectionRange[3] = p->cselectionRange[5];
2512  }
2513  p->cselection = true;
2514  p->selection = false;
2515  }
2516  p->calcCmdLnTop();
2517  update();
2518 }
2519 
2520 QString HConsolePanelPrivate::cmdLineTextSkipsel(int& new_cursor_pos)
2521 {
2522  if(!cselection)
2523  return pp->commandLineText();
2524 
2525  bool sb = false;
2526  QString c="";
2527  new_cursor_pos = 0;
2528  HConsoleLine* r = cfirst;
2529  while(r != NULL)
2530  {
2531  if(cselectionRange[0] == r->serial && cselectionRange[2] == r->serial) //selection begin-end
2532  {
2533  int ss,ee;
2534  ss=cselectionRange[1];
2535  if(ss < 0)
2536  ss = 0;
2537  ee = cselectionRange[3];
2538  if(ee > r->line.length())
2539  ee = r->line.length();
2540 
2541  c += r->line.left(ss);
2542  c += r->line.mid(ee,-1) + ((r->next != NULL && !r->autole) ? "\n" : "");
2543  new_cursor_pos += r->line.left(ss).length();
2544  sb = true;
2545  }
2546  else if(cselectionRange[0] == r->serial) //selection begin
2547  {
2548  int ss = cselectionRange[1];
2549  if(ss < 0)
2550  ss = 0;
2551  c += r->line.left(ss);
2552  new_cursor_pos += r->line.left(ss).length();
2553  sb = true;
2554  }
2555  else if(cselectionRange[0] < r->serial && cselectionRange[2] > r->serial) //selection in
2556  {
2557  ;//skipped text
2558  }
2559  else if(cselectionRange[2] == r->serial) //selection end
2560  {
2561  int ee = cselectionRange[3];
2562  if(ee > r->line.length())
2563  ee = r->line.length();
2564 
2565  c += r->line.mid(ee,-1) + ((r->next != NULL && !r->autole) ? "\n" : "");
2566  }
2567  else
2568  {
2569  if(!sb)
2570  new_cursor_pos += ( r->line.length() + (r->autole ? 0 : 1) );
2571  c += r->line + ((r->next != NULL && !r->autole) ? "\n" : "");
2572  }
2573  r = r->next;
2574  }
2575  return c;
2576 }
2577 
2579 {
2580  const QClipboard *clipboard = QApplication::clipboard();
2581  const QMimeData *mimeData = clipboard->mimeData();
2582 
2583  addTextToCursor(mimeData->text());
2584 }
2585 
2586 void HConsolePanel::wheelEvent(QWheelEvent *e)
2587 {
2588  int l,c,scroll;
2589  char t = 0;
2590  if(p->first == NULL)
2591  return;
2592  p->getLCfromXY(e->x(),e->y(),l,c,scroll,t);
2593  if(t == 2 && p->cfirst != p->clast)
2594  {
2595  p->viewtop = NULL;
2596  if(e->delta()>0 && p->cursorPos[0] > p->cfirst->serial)
2597  p->cursorPos[0] -= 1;
2598  if(e->delta()<0 && p->cursorPos[0] < p->clast->serial)
2599  p->cursorPos[0] += 1;
2600 
2601  p->cursorPos[1] = p->origCursorPos2;
2602  if(p->cursorPos[1] > p->commandLineLineBySerial(p->cursorPos[0]).length())
2603  p->cursorPos[1] = p->commandLineLineBySerial(p->cursorPos[0]).length();
2604  p->calcCmdLnTop();
2605  update();
2606  }
2607  else
2608  {
2609  if(e->delta()<0)
2610  scrollDown(e->modifiers() == Qt::ShiftModifier ? 10 : 1);
2611  if(e->delta()>0)
2612  scrollUp(e->modifiers() == Qt::ShiftModifier ? 10 : 1);
2613  }
2614 }
2615 
2616 void HConsolePanel::keyPressEvent(QKeyEvent *e)
2617 {
2618  if(e->key() == Qt::Key_PageUp && e->modifiers() == Qt::ShiftModifier)
2619  {
2620  scrollUp(5);
2621  return;
2622  }
2623  if(e->key() == Qt::Key_PageDown && e->modifiers() == Qt::ShiftModifier)
2624  {
2625  scrollDown(5);
2626  return;
2627  }
2628 
2629  if(e->key() == Qt::Key_A && e->modifiers() == Qt::ControlModifier)
2630  {
2631  selectAll();
2632  return;
2633  }
2634 
2635  if((e->key() == Qt::Key_Insert && e->modifiers() == Qt::ControlModifier) ||
2636  (e->key() == Qt::Key_C && e->modifiers() == Qt::ControlModifier))
2637  {
2638  copySelection();
2639  return;
2640  }
2641 
2642  if((e->key() == Qt::Key_Insert && e->modifiers() == Qt::ShiftModifier) ||
2643  (e->key() == Qt::Key_V && e->modifiers() == Qt::ControlModifier))
2644  {
2646  return;
2647  }
2648 
2649  if(e->key() == Qt::Key_Home)
2650  {
2651  if(p->cfirst == p->clast && p->cfirst->line.isEmpty() && p->first != p->top)
2652  {
2653  p->viewtop = p->first;
2654  p->calcScrollBar();
2655  update();
2656  return;
2657  }
2658  if(e->modifiers() == Qt::ShiftModifier)
2659  {
2660  p->cselectionRange[2] = p->cursorPos[0];
2661  p->cselectionRange[3] = p->cursorPos[1];
2662  p->cselectionRange[4] = p->cselectionRange[0];
2663  p->cselectionRange[5] = p->cselectionRange[1];
2664  }
2665  p->viewtop = NULL;
2666  p->selection = false;
2667  p->cselection = false;
2668  p->cursorPos[1] = 0;
2669  if(e->modifiers() == Qt::ShiftModifier)
2670  {
2671  p->cselectionRange[0] = p->cursorPos[0];
2672  p->cselectionRange[1] = p->cursorPos[1];
2673  if(p->cselectionRange[1] != p->cselectionRange[3])
2674  p->cselection = true;
2675  }
2676  p->calcScrollBar();
2677  update();
2678  return;
2679  }
2680  if(e->key() == Qt::Key_End)
2681  {
2682  if(p->cfirst == p->clast && p->cfirst->line.isEmpty() && p->viewtop != NULL)
2683  {
2684  p->viewtop = NULL;
2685  p->calcScrollBar();
2686  update();
2687  return;
2688  }
2689  if(e->modifiers() == Qt::ShiftModifier)
2690  {
2691  p->cselectionRange[0] = p->cursorPos[0];
2692  p->cselectionRange[1] = p->cursorPos[1];
2693  p->cselectionRange[4] = p->cselectionRange[0];
2694  p->cselectionRange[5] = p->cselectionRange[1];
2695  }
2696  p->viewtop = NULL;
2697  p->selection = false;
2698  p->cselection = false;
2699  p->cursorPos[1] = p->commandLineLineBySerial(p->cursorPos[0]).length();
2700  if(e->modifiers() == Qt::ShiftModifier)
2701  {
2702  p->cselectionRange[2] = p->cursorPos[0];
2703  p->cselectionRange[3] = p->cursorPos[1];
2704  if(p->cselectionRange[1] != p->cselectionRange[3])
2705  p->cselection = true;
2706  }
2707  p->calcScrollBar();
2708  update();
2709  return;
2710  }
2711 
2712  if(e->key() == Qt::Key_Escape)
2713  {
2714  p->viewtop = NULL;
2715  p->selection = false;
2716  p->cselection = false;
2717  resetCommandLine();
2718  p->history_it = p->history.end();
2719  p->fitConsole();
2720  update();
2721  return;
2722  }
2723 
2724  if(e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete)
2725  {
2726  p->viewtop = NULL;
2727  p->calcScrollBar();
2728  deleteFromCursor(e->key() == Qt::Key_Delete ? true : false);
2729  return;
2730  }
2731 
2732  if(e->key() == Qt::Key_Up)
2733  {
2734  p->viewtop = NULL;
2735  p->calcScrollBar();
2736  p->cselection = false;
2737  if(!p->history.isEmpty())
2738  {
2739  if(p->history_it == p->history.end())
2740  {
2741  p->history_it = p->history.end();
2742  --p->history_it;
2743  }
2744  else
2745  {
2746  if(p->history_it != p->history.begin())
2747  --p->history_it;
2748  }
2749  setCommandLineText(*p->history_it);
2750  }
2751  return;
2752  }
2753 
2754  if(e->key() == Qt::Key_Down)
2755  {
2756  p->viewtop = NULL;
2757  p->calcScrollBar();
2758  p->cselection = false;
2759  if(!p->history.isEmpty() && p->history_it != p->history.end())
2760  {
2761  ++p->history_it;
2762  if(p->history_it == p->history.end())
2763  {
2764  resetCommandLine();
2765  update();
2766  }
2767  else
2768  setCommandLineText(*p->history_it);
2769  }
2770  return;
2771  }
2772 
2773  if(e->key() == Qt::Key_Left)
2774  {
2775  cursorLeft(1,e->modifiers() == Qt::ShiftModifier ? true : false);
2776  return;
2777  }
2778 
2779  if(e->key() == Qt::Key_Right)
2780  {
2781  cursorRight(1,e->modifiers() == Qt::ShiftModifier ? true : false);
2782  return;
2783  }
2784 
2785  if(e->key() == Qt::Key_B && e->modifiers() == Qt::ControlModifier)
2786  {
2787  biggerFontSize();
2788  return;
2789  }
2790 
2791  if(e->key() == Qt::Key_S && e->modifiers() == Qt::ControlModifier)
2792  {
2793  smallerFontSize();
2794  return;
2795  }
2796 
2797  if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter)
2798  {
2799  if(e->modifiers() == Qt::ShiftModifier)
2800  {
2801  addTextToCursor("\n");
2802  return;
2803  }
2804 
2805  p->viewtop = NULL;
2806  p->calcScrollBar();
2807  QString send = commandLineText();
2808  if(!send.isEmpty() && (p->history.isEmpty() || send != p->history.last()))
2809  {
2810  p->history.push_back(send);
2811  p->history_it = p->history.end();
2812  }
2813  resetCommandLine();
2814  update();
2815  emit commandEntered(send);
2816  return;
2817  }
2818 
2819  if(e->key() == Qt::Key_Shift || e->key() == Qt::Key_Alt || e->key() == Qt::Key_Control)
2820  return;
2821 
2822  //Keypress
2823  if(e->modifiers() != Qt::ControlModifier && e->modifiers() != Qt::AltModifier)
2824  {
2825  p->viewtop = NULL;
2826  p->calcScrollBar();
2827  addTextToCursor(e->text());
2828  }
2829 }
2830 
2831 bool HConsolePanel::event(QEvent *e)
2832 {
2833  if(e->type() == QEvent::KeyPress)
2834  {
2835  QKeyEvent *ke = static_cast<QKeyEvent *>(e);
2836  if(ke->key() == Qt::Key_Tab)
2837  {
2838  p->viewtop = NULL;
2839  p->calcScrollBar();
2840  QString send = commandLineText();
2841  update();
2842  emit tabPressed(send);
2843  return true;
2844  }
2845  if((ke->key() == Qt::Key_Plus && ke->modifiers() == Qt::ControlModifier) ||
2846  (ke->key() == Qt::Key_Plus && ke->modifiers() == (Qt::ControlModifier | Qt::KeypadModifier)))
2847  {
2848  biggerFontSize();
2849  return true;
2850  }
2851  if((ke->key() == Qt::Key_Minus && ke->modifiers() == Qt::ControlModifier) ||
2852  (ke->key() == Qt::Key_Minus && ke->modifiers() == (Qt::ControlModifier | Qt::KeypadModifier)))
2853  {
2854  smallerFontSize();
2855  return true;
2856  }
2857  if((ke->key() == Qt::Key_0 && ke->modifiers() == Qt::ControlModifier) ||
2858  (ke->key() == Qt::Key_0 && ke->modifiers() == (Qt::ControlModifier | Qt::KeypadModifier)))
2859  {
2860  normalFontSize();
2861  return true;
2862  }
2863  }
2864  return QWidget::event(e);
2865 }
2866 
2868 {
2869  p->promptStr = prm;
2870  update();
2871 }
2872 
2874 {
2875  return p->promptStr;
2876 }
2877 
2879 {
2880  p->fontsize = point;
2881  QFont f = font();
2882  f.setPixelSize(p->fontsize);
2883  setFont(f);
2884  delete p->fm;
2885  p->fm = new QFontMetrics(font(),this);
2886  p->fitConsole();
2887 }
2888 
2890 {
2891  return p->fontsize;
2892 }
2893 
2894 void HConsolePanel::biggerFontSize(void)
2895 {
2896  int s = fontSize() + 1;
2897  if(s > 25)
2898  s = 25;
2899  setFontSize(s);
2900 }
2901 
2902 void HConsolePanel::smallerFontSize(void)
2903 {
2904  int s = fontSize() - 1;
2905  if(s < 10)
2906  s = 10;
2907  setFontSize(s);
2908 }
2909 
2910 void HConsolePanel::normalFontSize(void)
2911 {
2912  setFontSize(14);
2913 }
2914 
2915 #endif //GSAFE_DISABLE_DEBUG
2916 
2917 //end code
void selectAll(void)
Definition: dconsole.cpp:1720
void commandEntered(QString commandText)
static HDebugConsole * myself
Definition: dconsole.h:181
void deleteCmdLineSelection(void)
Definition: dconsole.cpp:2383
static void popup(QString title, QString str)
Definition: dconsole.cpp:335
void deleteFromCursor(bool forwardDel=false)
Definition: dconsole.cpp:2331
int maxSerial(void)
Definition: dconsole.cpp:1678
HConsolePanel * consoleObject(void)
Definition: dconsole.cpp:330
void unregister_dconsole_command(QString command)
Definition: dconsole.cpp:104
void setCommandLineCharacterEcho(bool disable=false)
Definition: dconsole.cpp:1350
QString commandLineText(void)
Definition: dconsole.cpp:2245
void setMarginText(QString margin)
Definition: dconsole.cpp:1185
void dconsole_close(void)
Definition: dconsole.cpp:70
void pasteToCommandLine(void)
Definition: dconsole.cpp:2578
void sqldebug(QString s)
Definition: dconsole.cpp:36
void cursorLeft(int charCount=1, bool inSelection=false)
Definition: dconsole.cpp:2398
void addTextToCursor(QString text)
Definition: dconsole.cpp:2293
int cursorPosition(void)
Definition: dconsole.cpp:2257
void setTextTypeColor(char type, QColor color)
Definition: dconsole.cpp:1513
void copySelection(void)
Definition: dconsole.cpp:1800
void scrollUp(int lineCount=1)
Definition: dconsole.cpp:1608
void scrollReset(void)
Definition: dconsole.cpp:1654
void setTabStop(int count)
Definition: dconsole.cpp:1523
HDebugConsole(QWidget *parent)
Definition: dconsole.cpp:173
void setCursorPosition(int c)
Definition: dconsole.cpp:2272
void clearSelection(void)
Definition: dconsole.cpp:1733
void setPromptString(QString prm)
Definition: dconsole.cpp:2867
HConsolePanel(QWidget *parent)
Definition: dconsole.cpp:1088
QString promptString(void)
Definition: dconsole.cpp:2873
void setCommandLineText(QString t, bool disableupdate=false)
Definition: dconsole.cpp:2189
void resetCommandLine(void)
Definition: dconsole.cpp:2170
void add_text(QString s, int type)
Definition: dconsole.cpp:341
QString selectedText(void)
Definition: dconsole.cpp:1739
~HDebugConsole(void)
Definition: dconsole.cpp:296
void sdebug(QString s)
Definition: dconsole.cpp:48
virtual QString donsole_command_interpreter(QString commandString)=0
void setColor(QString section, QColor color)
Definition: dconsole.cpp:1495
void register_dconsole_command(QString command, HDConsoleCommandHolder *interpreter, QString descr)
Definition: dconsole.cpp:95
void addNormalText(QString text)
Definition: dconsole.cpp:1518
void scrollTop(void)
Definition: dconsole.cpp:1647
void setFontSize(int point)
Definition: dconsole.cpp:2878
int topSerial(void)
Definition: dconsole.cpp:1685
void cursorRight(int charCount=1, bool inSelection=false)
Definition: dconsole.cpp:2453
void tabPressed(QString commandText)
void scrollDown(int lineCount=1)
Definition: dconsole.cpp:1629
int fontSize(void)
Definition: dconsole.cpp:2889
void dconsole_popup(QString t, QString txt)
Definition: dconsole.cpp:82
static void debug_txt(QString s)
Definition: dconsole.cpp:382
void dconsole(void)
Definition: dconsole.cpp:59
void setCommandExecution(bool enabled=true)
Definition: dconsole.cpp:309
void clearText(void)
Definition: dconsole.cpp:1588
void scrollToSerial(int serial)
Definition: dconsole.cpp:1661
void addText(QString t, char type=0)
Definition: dconsole.cpp:1528
static void debug_sql(QString s)
Definition: dconsole.cpp:375
QString lineBySerial(int serial, bool withWraps=false, bool onDisplay=true)
Definition: dconsole.cpp:1692
void clear_dconsole_commands()
Definition: dconsole.cpp:113