From bd0f3345a938b35ce6a12f6150373b0955b8dd12 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 10 Jul 2011 15:24:15 -0500 Subject: Add Qt3 development HEAD version --- tools/assistant/LICENSE.GPL | 280 ++ tools/assistant/assistant.icns | Bin 0 -> 58954 bytes tools/assistant/assistant.ico | Bin 0 -> 10134 bytes tools/assistant/assistant.pro | 72 + tools/assistant/assistant.rc | 1 + tools/assistant/assistant_de.qm | Bin 0 -> 13929 bytes tools/assistant/assistant_de.ts | 1084 +++++ tools/assistant/assistant_fr.ts | 426 ++ tools/assistant/book/assistant.book | 6 + tools/assistant/book/assistant.leaf | 563 +++ tools/assistant/book/images/assistant.png | Bin 0 -> 53805 bytes tools/assistant/book/images/docwindow.png | Bin 0 -> 9727 bytes tools/assistant/book/images/general.png | Bin 0 -> 11239 bytes tools/assistant/book/images/pdf1.png | Bin 0 -> 8610 bytes tools/assistant/book/images/search.png | Bin 0 -> 6284 bytes tools/assistant/book/images/sidebar.png | Bin 0 -> 5041 bytes tools/assistant/book/images/toolbar1.png | Bin 0 -> 4184 bytes tools/assistant/book/images/web.png | Bin 0 -> 11826 bytes tools/assistant/config.cpp | 379 ++ tools/assistant/config.h | 152 + tools/assistant/docuparser.cpp | 397 ++ tools/assistant/docuparser.h | 151 + tools/assistant/finddialog.ui | 286 ++ tools/assistant/finddialog.ui.h | 108 + tools/assistant/helpdialog.ui | 506 ++ tools/assistant/helpdialogimpl.cpp | 1161 +++++ tools/assistant/helpdialogimpl.h | 171 + tools/assistant/helpwindow.cpp | 282 ++ tools/assistant/helpwindow.h | 87 + tools/assistant/images/addtab.png | Bin 0 -> 469 bytes tools/assistant/images/appicon.png | Bin 0 -> 2353 bytes tools/assistant/images/assistant.png | Bin 0 -> 1349 bytes tools/assistant/images/book.png | Bin 0 -> 861 bytes tools/assistant/images/closetab.png | Bin 0 -> 533 bytes tools/assistant/images/d_closetab.png | Bin 0 -> 396 bytes tools/assistant/images/designer.png | Bin 0 -> 1367 bytes tools/assistant/images/editcopy.png | Bin 0 -> 491 bytes tools/assistant/images/find.png | Bin 0 -> 856 bytes tools/assistant/images/home.png | Bin 0 -> 1081 bytes tools/assistant/images/linguist.png | Bin 0 -> 1157 bytes tools/assistant/images/next.png | Bin 0 -> 541 bytes tools/assistant/images/previous.png | Bin 0 -> 542 bytes tools/assistant/images/print.png | Bin 0 -> 766 bytes tools/assistant/images/qt.png | Bin 0 -> 975 bytes tools/assistant/images/splash.png | Bin 0 -> 50661 bytes tools/assistant/images/whatsthis.xpm | 26 + tools/assistant/images/zoomin.png | Bin 0 -> 900 bytes tools/assistant/images/zoomout.png | Bin 0 -> 919 bytes tools/assistant/index.cpp | 526 +++ tools/assistant/index.h | 131 + tools/assistant/lib/lib.pro | 23 + tools/assistant/lib/qassistantclient.cpp | 334 ++ tools/assistant/lib/qassistantclient.h | 80 + tools/assistant/main.cpp | 342 ++ tools/assistant/mainwindow.ui | 670 +++ tools/assistant/mainwindow.ui.h | 698 +++ tools/assistant/profile.cpp | 124 + tools/assistant/profile.h | 130 + tools/assistant/settingsdialog.ui | 516 ++ tools/assistant/settingsdialogimpl.cpp | 122 + tools/assistant/settingsdialogimpl.h | 63 + tools/assistant/tabbedbrowser.ui | 141 + tools/assistant/tabbedbrowser.ui.h | 347 ++ tools/assistant/topicchooser.ui | 182 + tools/assistant/topicchooserimpl.cpp | 70 + tools/assistant/topicchooserimpl.h | 60 + tools/designer/LICENSE.GPL | 280 ++ tools/designer/app/app.pro | 26 + tools/designer/app/designer.icns | Bin 0 -> 56873 bytes tools/designer/app/designer.ico | Bin 0 -> 10134 bytes tools/designer/app/designer.rc | 2 + tools/designer/app/main.cpp | 228 + tools/designer/designer.pro | 14 + tools/designer/designer/about.ui | 222 + tools/designer/designer/actiondnd.cpp | 743 +++ tools/designer/designer/actiondnd.h | 242 + tools/designer/designer/actioneditor.ui | 230 + tools/designer/designer/actioneditorimpl.cpp | 325 ++ tools/designer/designer/actioneditorimpl.h | 86 + tools/designer/designer/actionlistview.cpp | 115 + tools/designer/designer/actionlistview.h | 88 + tools/designer/designer/asciivalidator.cpp | 101 + tools/designer/designer/asciivalidator.h | 59 + tools/designer/designer/command.cpp | 2402 ++++++++++ tools/designer/designer/command.h | 1266 +++++ tools/designer/designer/configtoolboxdialog.ui | 329 ++ tools/designer/designer/configtoolboxdialog.ui.h | 222 + tools/designer/designer/connectiondialog.ui | 226 + tools/designer/designer/connectiondialog.ui.h | 318 ++ tools/designer/designer/connectionitems.cpp | 524 +++ tools/designer/designer/connectionitems.h | 227 + tools/designer/designer/connectiontable.cpp | 61 + tools/designer/designer/connectiontable.h | 53 + tools/designer/designer/createtemplate.ui | 236 + tools/designer/designer/customwidgeteditor.ui | 1385 ++++++ tools/designer/designer/customwidgeteditorimpl.cpp | 845 ++++ tools/designer/designer/customwidgeteditorimpl.h | 105 + tools/designer/designer/database.cpp | 129 + tools/designer/designer/database.h | 90 + tools/designer/designer/database2.h | 95 + tools/designer/designer/dbconnection.ui | 229 + tools/designer/designer/dbconnectioneditor.ui | 154 + tools/designer/designer/dbconnectionimpl.cpp | 87 + tools/designer/designer/dbconnectionimpl.h | 64 + tools/designer/designer/dbconnections.ui | 328 ++ tools/designer/designer/dbconnectionsimpl.cpp | 201 + tools/designer/designer/dbconnectionsimpl.h | 67 + tools/designer/designer/defs.cpp | 91 + tools/designer/designer/defs.h | 49 + tools/designer/designer/designer.pro | 443 ++ tools/designer/designer/designer_de.ts | 4969 ++++++++++++++++++++ tools/designer/designer/designer_fr.ts | 4969 ++++++++++++++++++++ tools/designer/designer/designer_pch.h | 44 + tools/designer/designer/designerapp.cpp | 181 + tools/designer/designer/designerapp.h | 65 + tools/designer/designer/designerappiface.cpp | 1100 +++++ tools/designer/designer/designerappiface.h | 284 ++ tools/designer/designer/editfunctions.ui | 721 +++ tools/designer/designer/editfunctionsimpl.cpp | 536 +++ tools/designer/designer/editfunctionsimpl.h | 101 + tools/designer/designer/finddialog.ui | 281 ++ tools/designer/designer/finddialog.ui.h | 68 + tools/designer/designer/formfile.cpp | 924 ++++ tools/designer/designer/formfile.h | 153 + tools/designer/designer/formsettings.ui | 556 +++ tools/designer/designer/formsettingsimpl.cpp | 125 + tools/designer/designer/formsettingsimpl.h | 56 + tools/designer/designer/formwindow.cpp | 2761 +++++++++++ tools/designer/designer/formwindow.h | 328 ++ tools/designer/designer/gotolinedialog.ui | 176 + tools/designer/designer/gotolinedialog.ui.h | 57 + tools/designer/designer/hierarchyview.cpp | 1500 ++++++ tools/designer/designer/hierarchyview.h | 251 + tools/designer/designer/iconvieweditor.ui | 464 ++ tools/designer/designer/iconvieweditorimpl.cpp | 170 + tools/designer/designer/iconvieweditorimpl.h | 65 + .../designer/images/designer_adjustsize.png | Bin 0 -> 495 bytes .../designer/designer/images/designer_appicon.png | Bin 0 -> 2341 bytes tools/designer/designer/images/designer_arrow.png | Bin 0 -> 216 bytes .../designer/images/designer_background.png | Bin 0 -> 6724 bytes tools/designer/designer/images/designer_book.png | Bin 0 -> 825 bytes .../designer/images/designer_buttongroup.png | Bin 0 -> 648 bytes .../designer/designer/images/designer_checkbox.png | Bin 0 -> 817 bytes .../designer/designer/images/designer_combobox.png | Bin 0 -> 549 bytes .../designer/images/designer_connecttool.png | Bin 0 -> 553 bytes tools/designer/designer/images/designer_cross.png | Bin 0 -> 164 bytes .../designer/images/designer_customwidget.png | Bin 0 -> 1133 bytes .../designer/images/designer_d_adjustsize.png | Bin 0 -> 527 bytes tools/designer/designer/images/designer_d_book.png | Bin 0 -> 557 bytes .../designer/images/designer_d_buttongroup.png | Bin 0 -> 482 bytes .../designer/images/designer_d_checkbox.png | Bin 0 -> 547 bytes .../designer/images/designer_d_combobox.png | Bin 0 -> 420 bytes .../designer/images/designer_d_connecttool.png | Bin 0 -> 450 bytes .../designer/images/designer_d_customwidget.png | Bin 0 -> 629 bytes .../designer/images/designer_d_databrowser.png | Bin 0 -> 600 bytes .../designer/images/designer_d_datatable.png | Bin 0 -> 592 bytes .../designer/images/designer_d_dataview.png | Bin 0 -> 663 bytes .../designer/images/designer_d_dateedit.png | Bin 0 -> 452 bytes .../designer/images/designer_d_datetimeedit.png | Bin 0 -> 665 bytes tools/designer/designer/images/designer_d_dial.png | Bin 0 -> 706 bytes tools/designer/designer/images/designer_d_down.png | Bin 0 -> 441 bytes .../designer/images/designer_d_editbreaklayout.png | Bin 0 -> 635 bytes .../designer/images/designer_d_editcopy.png | Bin 0 -> 515 bytes .../designer/images/designer_d_editcut.png | Bin 0 -> 800 bytes .../designer/images/designer_d_editdelete.png | Bin 0 -> 682 bytes .../designer/images/designer_d_editgrid.png | Bin 0 -> 425 bytes .../designer/images/designer_d_edithlayout.png | Bin 0 -> 272 bytes .../images/designer_d_edithlayoutsplit.png | Bin 0 -> 328 bytes .../designer/images/designer_d_editlower.png | Bin 0 -> 450 bytes .../designer/images/designer_d_editpaste.png | Bin 0 -> 598 bytes .../designer/images/designer_d_editraise.png | Bin 0 -> 454 bytes .../designer/images/designer_d_editslots.png | Bin 0 -> 534 bytes .../designer/images/designer_d_editvlayout.png | Bin 0 -> 272 bytes .../images/designer_d_editvlayoutsplit.png | Bin 0 -> 333 bytes .../designer/images/designer_d_filenew.png | Bin 0 -> 298 bytes .../designer/images/designer_d_fileopen.png | Bin 0 -> 406 bytes .../designer/images/designer_d_filesave.png | Bin 0 -> 267 bytes .../designer/designer/images/designer_d_folder.png | Bin 0 -> 841 bytes tools/designer/designer/images/designer_d_form.png | Bin 0 -> 274 bytes .../designer/designer/images/designer_d_frame.png | Bin 0 -> 427 bytes .../designer/images/designer_d_groupbox.png | Bin 0 -> 465 bytes tools/designer/designer/images/designer_d_help.png | Bin 0 -> 786 bytes tools/designer/designer/images/designer_d_home.png | Bin 0 -> 743 bytes .../designer/images/designer_d_iconview.png | Bin 0 -> 547 bytes .../designer/designer/images/designer_d_image.png | Bin 0 -> 482 bytes .../designer/designer/images/designer_d_label.png | Bin 0 -> 670 bytes .../designer/designer/images/designer_d_layout.png | Bin 0 -> 496 bytes .../designer/images/designer_d_lcdnumber.png | Bin 0 -> 452 bytes tools/designer/designer/images/designer_d_left.png | Bin 0 -> 422 bytes tools/designer/designer/images/designer_d_line.png | Bin 0 -> 327 bytes .../designer/images/designer_d_lineedit.png | Bin 0 -> 445 bytes .../designer/images/designer_d_listbox.png | Bin 0 -> 410 bytes .../designer/images/designer_d_listview.png | Bin 0 -> 639 bytes .../designer/images/designer_d_multilineedit.png | Bin 0 -> 479 bytes .../designer/images/designer_d_newform.png | Bin 0 -> 443 bytes .../designer/images/designer_d_ordertool.png | Bin 0 -> 533 bytes .../designer/images/designer_d_pixlabel.png | Bin 0 -> 619 bytes .../designer/images/designer_d_pointer.png | Bin 0 -> 476 bytes .../designer/designer/images/designer_d_print.png | Bin 0 -> 589 bytes .../designer/images/designer_d_progress.png | Bin 0 -> 375 bytes .../designer/images/designer_d_project.png | Bin 0 -> 915 bytes .../designer/images/designer_d_pushbutton.png | Bin 0 -> 445 bytes .../designer/images/designer_d_radiobutton.png | Bin 0 -> 605 bytes tools/designer/designer/images/designer_d_redo.png | Bin 0 -> 465 bytes .../designer/images/designer_d_richtextedit.png | Bin 0 -> 562 bytes .../designer/designer/images/designer_d_right.png | Bin 0 -> 425 bytes .../designer/images/designer_d_scrollbar.png | Bin 0 -> 364 bytes .../designer/images/designer_d_searchfind.png | Bin 0 -> 501 bytes .../designer/images/designer_d_setbuddy.png | Bin 0 -> 427 bytes .../designer/designer/images/designer_d_slider.png | Bin 0 -> 548 bytes .../designer/designer/images/designer_d_spacer.png | Bin 0 -> 519 bytes .../designer/images/designer_d_spinbox.png | Bin 0 -> 477 bytes .../designer/designer/images/designer_d_table.png | Bin 0 -> 512 bytes .../designer/images/designer_d_tabwidget.png | Bin 0 -> 404 bytes .../designer/images/designer_d_textbold.png | Bin 0 -> 517 bytes .../designer/images/designer_d_textbrowser.png | Bin 0 -> 534 bytes .../designer/images/designer_d_textcenter.png | Bin 0 -> 453 bytes .../designer/images/designer_d_textedit.png | Bin 0 -> 526 bytes .../designer/images/designer_d_textfont.png | Bin 0 -> 412 bytes .../designer/designer/images/designer_d_texth1.png | Bin 0 -> 475 bytes .../designer/designer/images/designer_d_texth2.png | Bin 0 -> 537 bytes .../designer/designer/images/designer_d_texth3.png | Bin 0 -> 508 bytes .../designer/images/designer_d_textitalic.png | Bin 0 -> 452 bytes .../designer/images/designer_d_textjustify.png | Bin 0 -> 442 bytes .../designer/images/designer_d_textlarger.png | Bin 0 -> 537 bytes .../designer/images/designer_d_textleft.png | Bin 0 -> 442 bytes .../designer/images/designer_d_textlinebreak.png | Bin 0 -> 526 bytes .../designer/images/designer_d_textparagraph.png | Bin 0 -> 543 bytes .../designer/images/designer_d_textright.png | Bin 0 -> 443 bytes .../designer/images/designer_d_textsmaller.png | Bin 0 -> 512 bytes .../designer/images/designer_d_textteletext.png | Bin 0 -> 462 bytes .../designer/images/designer_d_textunderline.png | Bin 0 -> 497 bytes .../designer/images/designer_d_textview.png | Bin 0 -> 529 bytes .../designer/images/designer_d_timeedit.png | Bin 0 -> 827 bytes .../designer/images/designer_d_toolbox.png | Bin 0 -> 465 bytes .../designer/images/designer_d_toolbutton.png | Bin 0 -> 670 bytes tools/designer/designer/images/designer_d_undo.png | Bin 0 -> 471 bytes tools/designer/designer/images/designer_d_up.png | Bin 0 -> 444 bytes .../designer/images/designer_d_widgetstack.png | Bin 0 -> 558 bytes .../designer/images/designer_d_wizarddata.png | Bin 0 -> 294 bytes .../designer/images/designer_d_wizarddialog.png | Bin 0 -> 421 bytes .../designer/images/designer_d_wordwrap.png | Bin 0 -> 506 bytes .../designer/images/designer_databrowser.png | Bin 0 -> 907 bytes .../designer/images/designer_datatable.png | Bin 0 -> 923 bytes .../designer/designer/images/designer_dataview.png | Bin 0 -> 1039 bytes .../designer/designer/images/designer_dateedit.png | Bin 0 -> 505 bytes .../designer/images/designer_datetimeedit.png | Bin 0 -> 1074 bytes tools/designer/designer/images/designer_dial.png | Bin 0 -> 994 bytes tools/designer/designer/images/designer_down.png | Bin 0 -> 595 bytes .../designer/images/designer_editbreaklayout.png | Bin 0 -> 744 bytes .../designer/designer/images/designer_editcopy.png | Bin 0 -> 485 bytes .../designer/designer/images/designer_editcut.png | Bin 0 -> 649 bytes .../designer/images/designer_editdelete.png | Bin 0 -> 833 bytes .../designer/designer/images/designer_editgrid.png | Bin 0 -> 513 bytes .../designer/images/designer_edithlayout.png | Bin 0 -> 295 bytes .../designer/images/designer_edithlayoutsplit.png | Bin 0 -> 344 bytes .../designer/images/designer_editlower.png | Bin 0 -> 609 bytes .../designer/images/designer_editpaste.png | Bin 0 -> 907 bytes .../designer/images/designer_editraise.png | Bin 0 -> 614 bytes .../designer/images/designer_editslots.png | Bin 0 -> 690 bytes .../designer/images/designer_editvlayout.png | Bin 0 -> 289 bytes .../designer/images/designer_editvlayoutsplit.png | Bin 0 -> 355 bytes .../designer/designer/images/designer_filenew.png | Bin 0 -> 313 bytes .../designer/designer/images/designer_fileopen.png | Bin 0 -> 681 bytes .../designer/designer/images/designer_filesave.png | Bin 0 -> 328 bytes tools/designer/designer/images/designer_folder.png | Bin 0 -> 1366 bytes tools/designer/designer/images/designer_form.png | Bin 0 -> 301 bytes tools/designer/designer/images/designer_frame.png | Bin 0 -> 400 bytes .../designer/designer/images/designer_groupbox.png | Bin 0 -> 439 bytes tools/designer/designer/images/designer_hand.png | Bin 0 -> 197 bytes tools/designer/designer/images/designer_help.png | Bin 0 -> 1561 bytes tools/designer/designer/images/designer_home.png | Bin 0 -> 1083 bytes tools/designer/designer/images/designer_hsplit.png | Bin 0 -> 203 bytes tools/designer/designer/images/designer_ibeam.png | Bin 0 -> 162 bytes .../designer/designer/images/designer_iconview.png | Bin 0 -> 613 bytes tools/designer/designer/images/designer_image.png | Bin 0 -> 769 bytes tools/designer/designer/images/designer_label.png | Bin 0 -> 953 bytes tools/designer/designer/images/designer_layout.png | Bin 0 -> 706 bytes .../designer/images/designer_lcdnumber.png | Bin 0 -> 558 bytes tools/designer/designer/images/designer_left.png | Bin 0 -> 678 bytes tools/designer/designer/images/designer_line.png | Bin 0 -> 287 bytes .../designer/designer/images/designer_lineedit.png | Bin 0 -> 405 bytes .../designer/designer/images/designer_listbox.png | Bin 0 -> 384 bytes .../designer/designer/images/designer_listview.png | Bin 0 -> 759 bytes .../designer/images/designer_multilineedit.png | Bin 0 -> 452 bytes .../designer/designer/images/designer_newform.png | Bin 0 -> 531 bytes tools/designer/designer/images/designer_no.png | Bin 0 -> 230 bytes tools/designer/designer/images/designer_object.png | Bin 0 -> 1065 bytes .../designer/images/designer_ordertool.png | Bin 0 -> 587 bytes .../designer/designer/images/designer_pixlabel.png | Bin 0 -> 1228 bytes .../designer/designer/images/designer_pointer.png | Bin 0 -> 586 bytes tools/designer/designer/images/designer_print.png | Bin 0 -> 742 bytes .../designer/designer/images/designer_progress.png | Bin 0 -> 559 bytes .../designer/designer/images/designer_project.png | Bin 0 -> 1275 bytes .../designer/images/designer_pushbutton.png | Bin 0 -> 408 bytes tools/designer/designer/images/designer_qtlogo.png | Bin 0 -> 12615 bytes .../designer/images/designer_radiobutton.png | Bin 0 -> 586 bytes tools/designer/designer/images/designer_redo.png | Bin 0 -> 592 bytes .../designer/images/designer_resetproperty.png | Bin 0 -> 184 bytes .../designer/images/designer_richtextedit.png | Bin 0 -> 834 bytes tools/designer/designer/images/designer_right.png | Bin 0 -> 656 bytes tools/designer/designer/images/designer_s_down.png | Bin 0 -> 574 bytes .../designer/images/designer_s_editcut.png | Bin 0 -> 444 bytes tools/designer/designer/images/designer_s_left.png | Bin 0 -> 564 bytes .../designer/designer/images/designer_s_right.png | Bin 0 -> 557 bytes tools/designer/designer/images/designer_s_up.png | Bin 0 -> 586 bytes .../designer/images/designer_scrollbar.png | Bin 0 -> 408 bytes .../designer/images/designer_searchfind.png | Bin 0 -> 843 bytes .../designer/designer/images/designer_setbuddy.png | Bin 0 -> 427 bytes .../designer/designer/images/designer_sizeall.png | Bin 0 -> 208 bytes tools/designer/designer/images/designer_sizeb.png | Bin 0 -> 203 bytes tools/designer/designer/images/designer_sizef.png | Bin 0 -> 203 bytes tools/designer/designer/images/designer_sizeh.png | Bin 0 -> 179 bytes tools/designer/designer/images/designer_sizev.png | Bin 0 -> 177 bytes tools/designer/designer/images/designer_slider.png | Bin 0 -> 729 bytes tools/designer/designer/images/designer_spacer.png | Bin 0 -> 715 bytes .../designer/designer/images/designer_spinbox.png | Bin 0 -> 455 bytes tools/designer/designer/images/designer_splash.png | Bin 0 -> 123917 bytes tools/designer/designer/images/designer_table.png | Bin 0 -> 483 bytes .../designer/images/designer_tabwidget.png | Bin 0 -> 572 bytes .../designer/designer/images/designer_textbold.png | Bin 0 -> 494 bytes .../designer/images/designer_textbrowser.png | Bin 0 -> 514 bytes .../designer/images/designer_textcenter.png | Bin 0 -> 429 bytes .../designer/designer/images/designer_textedit.png | Bin 0 -> 495 bytes .../designer/designer/images/designer_textfont.png | Bin 0 -> 494 bytes tools/designer/designer/images/designer_texth1.png | Bin 0 -> 462 bytes tools/designer/designer/images/designer_texth2.png | Bin 0 -> 511 bytes tools/designer/designer/images/designer_texth3.png | Bin 0 -> 485 bytes .../designer/images/designer_textitalic.png | Bin 0 -> 442 bytes .../designer/images/designer_textjustify.png | Bin 0 -> 408 bytes .../designer/images/designer_textlarger.png | Bin 0 -> 710 bytes .../designer/designer/images/designer_textleft.png | Bin 0 -> 409 bytes .../designer/images/designer_textlinebreak.png | Bin 0 -> 509 bytes .../designer/images/designer_textparagraph.png | Bin 0 -> 527 bytes .../designer/images/designer_textright.png | Bin 0 -> 408 bytes .../designer/images/designer_textsmaller.png | Bin 0 -> 654 bytes .../designer/images/designer_textteletext.png | Bin 0 -> 445 bytes .../designer/images/designer_textunderline.png | Bin 0 -> 471 bytes .../designer/designer/images/designer_textview.png | Bin 0 -> 498 bytes .../designer/designer/images/designer_timeedit.png | Bin 0 -> 1520 bytes .../designer/designer/images/designer_toolbox.png | Bin 0 -> 783 bytes .../designer/images/designer_toolbutton.png | Bin 0 -> 1261 bytes tools/designer/designer/images/designer_undo.png | Bin 0 -> 572 bytes tools/designer/designer/images/designer_up.png | Bin 0 -> 692 bytes .../designer/designer/images/designer_uparrow.png | Bin 0 -> 169 bytes tools/designer/designer/images/designer_vsplit.png | Bin 0 -> 192 bytes tools/designer/designer/images/designer_wait.png | Bin 0 -> 216 bytes .../designer/images/designer_widgetstack.png | Bin 0 -> 831 bytes .../designer/images/designer_wizarddata.png | Bin 0 -> 323 bytes .../designer/images/designer_wizarddialog.png | Bin 0 -> 632 bytes .../designer/designer/images/designer_wordwrap.png | Bin 0 -> 643 bytes tools/designer/designer/layout.cpp | 1024 ++++ tools/designer/designer/layout.h | 195 + tools/designer/designer/listboxdnd.cpp | 312 ++ tools/designer/designer/listboxdnd.h | 70 + tools/designer/designer/listboxeditor.ui | 461 ++ tools/designer/designer/listboxeditorimpl.cpp | 250 + tools/designer/designer/listboxeditorimpl.h | 68 + tools/designer/designer/listboxrename.cpp | 164 + tools/designer/designer/listboxrename.h | 64 + tools/designer/designer/listdnd.cpp | 149 + tools/designer/designer/listdnd.h | 70 + tools/designer/designer/listeditor.ui | 182 + tools/designer/designer/listeditor.ui.h | 72 + tools/designer/designer/listviewdnd.cpp | 439 ++ tools/designer/designer/listviewdnd.h | 73 + tools/designer/designer/listvieweditor.ui | 938 ++++ tools/designer/designer/listvieweditorimpl.cpp | 655 +++ tools/designer/designer/listvieweditorimpl.h | 109 + tools/designer/designer/mainwindow.cpp | 3784 +++++++++++++++ tools/designer/designer/mainwindow.h | 503 ++ tools/designer/designer/mainwindowactions.cpp | 2061 ++++++++ tools/designer/designer/menubareditor.cpp | 1134 +++++ tools/designer/designer/menubareditor.h | 205 + tools/designer/designer/metadatabase.cpp | 1693 +++++++ tools/designer/designer/metadatabase.h | 276 ++ tools/designer/designer/multilineeditor.ui | 188 + tools/designer/designer/multilineeditorimpl.cpp | 417 ++ tools/designer/designer/multilineeditorimpl.h | 116 + tools/designer/designer/newform.ui | 245 + tools/designer/designer/newformimpl.cpp | 418 ++ tools/designer/designer/newformimpl.h | 171 + tools/designer/designer/orderindicator.cpp | 119 + tools/designer/designer/orderindicator.h | 64 + tools/designer/designer/outputwindow.cpp | 214 + tools/designer/designer/outputwindow.h | 105 + tools/designer/designer/paletteeditor.ui | 503 ++ tools/designer/designer/paletteeditoradvanced.ui | 755 +++ .../designer/paletteeditoradvancedimpl.cpp | 650 +++ .../designer/designer/paletteeditoradvancedimpl.h | 103 + tools/designer/designer/paletteeditorimpl.cpp | 311 ++ tools/designer/designer/paletteeditorimpl.h | 83 + tools/designer/designer/pixmapchooser.cpp | 206 + tools/designer/designer/pixmapchooser.h | 79 + tools/designer/designer/pixmapcollection.cpp | 187 + tools/designer/designer/pixmapcollection.h | 87 + tools/designer/designer/pixmapcollectioneditor.ui | 225 + .../designer/designer/pixmapcollectioneditor.ui.h | 156 + tools/designer/designer/pixmapfunction.ui | 937 ++++ tools/designer/designer/popupmenueditor.cpp | 1469 ++++++ tools/designer/designer/popupmenueditor.h | 242 + tools/designer/designer/preferences.ui | 670 +++ tools/designer/designer/previewframe.cpp | 64 + tools/designer/designer/previewframe.h | 66 + tools/designer/designer/previewwidget.ui | 311 ++ tools/designer/designer/previewwidgetimpl.cpp | 72 + tools/designer/designer/previewwidgetimpl.h | 50 + tools/designer/designer/project.cpp | 1598 +++++++ tools/designer/designer/project.h | 280 ++ tools/designer/designer/projectsettings.ui | 308 ++ tools/designer/designer/projectsettingsimpl.cpp | 132 + tools/designer/designer/projectsettingsimpl.h | 63 + tools/designer/designer/propertyeditor.cpp | 4308 +++++++++++++++++ tools/designer/designer/propertyeditor.h | 874 ++++ tools/designer/designer/propertyobject.cpp | 165 + tools/designer/designer/propertyobject.h | 43 + tools/designer/designer/qcompletionedit.cpp | 217 + tools/designer/designer/qcompletionedit.h | 86 + tools/designer/designer/replacedialog.ui | 325 ++ tools/designer/designer/replacedialog.ui.h | 82 + tools/designer/designer/resource.cpp | 3359 +++++++++++++ tools/designer/designer/resource.h | 172 + tools/designer/designer/richtextfontdialog.ui | 354 ++ tools/designer/designer/richtextfontdialog.ui.h | 49 + tools/designer/designer/sizehandle.cpp | 394 ++ tools/designer/designer/sizehandle.h | 104 + tools/designer/designer/sourceeditor.cpp | 325 ++ tools/designer/designer/sourceeditor.h | 113 + tools/designer/designer/sourcefile.cpp | 302 ++ tools/designer/designer/sourcefile.h | 93 + tools/designer/designer/startdialog.ui | 331 ++ tools/designer/designer/startdialogimpl.cpp | 177 + tools/designer/designer/startdialogimpl.h | 87 + tools/designer/designer/styledbutton.cpp | 302 ++ tools/designer/designer/styledbutton.h | 110 + tools/designer/designer/syntaxhighlighter_html.cpp | 167 + tools/designer/designer/syntaxhighlighter_html.h | 64 + tools/designer/designer/tableeditor.ui | 831 ++++ tools/designer/designer/tableeditorimpl.cpp | 501 ++ tools/designer/designer/tableeditorimpl.h | 89 + tools/designer/designer/timestamp.cpp | 93 + tools/designer/designer/timestamp.h | 70 + tools/designer/designer/variabledialog.ui | 301 ++ tools/designer/designer/variabledialogimpl.cpp | 185 + tools/designer/designer/variabledialogimpl.h | 63 + tools/designer/designer/widgetaction.cpp | 65 + tools/designer/designer/widgetaction.h | 72 + tools/designer/designer/widgetfactory.cpp | 1821 +++++++ tools/designer/designer/widgetfactory.h | 509 ++ tools/designer/designer/wizardeditor.ui | 345 ++ tools/designer/designer/wizardeditorimpl.cpp | 258 + tools/designer/designer/wizardeditorimpl.h | 81 + tools/designer/designer/workspace.cpp | 713 +++ tools/designer/designer/workspace.h | 158 + tools/designer/editor/arghintwidget.cpp | 239 + tools/designer/editor/arghintwidget.h | 69 + tools/designer/editor/browser.cpp | 149 + tools/designer/editor/browser.h | 66 + tools/designer/editor/cindent.cpp | 163 + tools/designer/editor/cindent.h | 63 + tools/designer/editor/completion.cpp | 714 +++ tools/designer/editor/completion.h | 110 + tools/designer/editor/conf.cpp | 269 ++ tools/designer/editor/conf.h | 75 + tools/designer/editor/editor.cpp | 251 + tools/designer/editor/editor.h | 111 + tools/designer/editor/editor.pro | 40 + tools/designer/editor/markerwidget.cpp | 491 ++ tools/designer/editor/markerwidget.h | 75 + tools/designer/editor/paragdata.h | 65 + tools/designer/editor/parenmatcher.cpp | 215 + tools/designer/editor/parenmatcher.h | 78 + tools/designer/editor/preferences.ui | 510 ++ tools/designer/editor/preferences.ui.h | 181 + tools/designer/editor/viewmanager.cpp | 276 ++ tools/designer/editor/viewmanager.h | 100 + tools/designer/editor/yyindent.cpp | 1170 +++++ .../designer/examples/addressbook/addressbook.pro | 14 + tools/designer/examples/addressbook/addressbook.ui | 324 ++ .../designer/examples/addressbook/addressbook.ui.h | 137 + .../examples/addressbook/addressdetails.ui | 243 + .../examples/addressbook/addressdetails.ui.h | 24 + .../examples/addressbook/images/editcut.png | Bin 0 -> 163 bytes .../examples/addressbook/images/filenew.png | Bin 0 -> 150 bytes .../examples/addressbook/images/fileopen.png | Bin 0 -> 179 bytes .../examples/addressbook/images/filesave.png | Bin 0 -> 157 bytes .../examples/addressbook/images/searchfind.png | Bin 0 -> 587 bytes tools/designer/examples/addressbook/main.cpp | 11 + tools/designer/examples/addressbook/search.ui | 136 + tools/designer/examples/addressbook/search.ui.h | 13 + tools/designer/examples/book/book.sql | 42 + tools/designer/examples/book/book1/book.ui | 71 + tools/designer/examples/book/book1/book.ui.h | 5 + tools/designer/examples/book/book1/book1.pro | 8 + tools/designer/examples/book/book1/main.cpp | 27 + tools/designer/examples/book/book2/book.ui | 77 + tools/designer/examples/book/book2/book.ui.h | 10 + tools/designer/examples/book/book2/book2.pro | 8 + tools/designer/examples/book/book2/main.cpp | 27 + tools/designer/examples/book/book3/book.ui | 141 + tools/designer/examples/book/book3/book.ui.h | 16 + tools/designer/examples/book/book3/book3.pro | 8 + tools/designer/examples/book/book3/main.cpp | 27 + tools/designer/examples/book/book4/book.ui | 179 + tools/designer/examples/book/book4/book.ui.h | 16 + tools/designer/examples/book/book4/book4.pro | 8 + tools/designer/examples/book/book4/main.cpp | 29 + tools/designer/examples/book/book5/book.ui | 188 + tools/designer/examples/book/book5/book.ui.h | 23 + tools/designer/examples/book/book5/book5.pro | 8 + tools/designer/examples/book/book5/editbook.ui | 291 ++ tools/designer/examples/book/book5/editbook.ui.h | 10 + tools/designer/examples/book/book5/main.cpp | 27 + tools/designer/examples/book/book6/book.ui | 189 + tools/designer/examples/book/book6/book.ui.h | 33 + tools/designer/examples/book/book6/book6.pro | 8 + tools/designer/examples/book/book6/editbook.ui | 300 ++ tools/designer/examples/book/book6/editbook.ui.h | 10 + tools/designer/examples/book/book6/main.cpp | 27 + tools/designer/examples/book/book7/book.ui | 189 + tools/designer/examples/book/book7/book.ui.h | 33 + tools/designer/examples/book/book7/book7.pro | 7 + tools/designer/examples/book/book7/editbook.ui | 384 ++ tools/designer/examples/book/book7/editbook.ui.h | 42 + tools/designer/examples/book/book7/main.cpp | 27 + tools/designer/examples/book/book8/book.ui | 189 + tools/designer/examples/book/book8/book.ui.h | 33 + tools/designer/examples/book/book8/book8.pro | 7 + tools/designer/examples/book/book8/editbook.ui | 386 ++ tools/designer/examples/book/book8/editbook.ui.h | 47 + tools/designer/examples/book/book8/main.cpp | 27 + tools/designer/examples/book/connection.cpp | 52 + tools/designer/examples/book/connection.h | 18 + tools/designer/examples/colortool/colornameform.ui | 168 + .../designer/examples/colortool/colornameform.ui.h | 27 + tools/designer/examples/colortool/colortool.pro | 27 + tools/designer/examples/colortool/findform.ui | 141 + tools/designer/examples/colortool/findform.ui.h | 18 + .../examples/colortool/images/editcopy.png | Bin 0 -> 187 bytes .../designer/examples/colortool/images/editcut.png | Bin 0 -> 163 bytes .../examples/colortool/images/editraise.png | Bin 0 -> 489 bytes .../designer/examples/colortool/images/filenew.png | Bin 0 -> 127 bytes .../examples/colortool/images/fileopen.png | Bin 0 -> 178 bytes .../examples/colortool/images/filesave.png | Bin 0 -> 158 bytes .../examples/colortool/images/iconview.png | Bin 0 -> 898 bytes .../examples/colortool/images/richtextedit.png | Bin 0 -> 878 bytes .../examples/colortool/images/searchfind.png | Bin 0 -> 554 bytes tools/designer/examples/colortool/images/table.png | Bin 0 -> 371 bytes .../examples/colortool/images/tabwidget.png | Bin 0 -> 545 bytes .../examples/colortool/images/widgetstack.png | Bin 0 -> 662 bytes tools/designer/examples/colortool/main.cpp | 10 + tools/designer/examples/colortool/mainform.ui | 601 +++ tools/designer/examples/colortool/mainform.ui.h | 585 +++ tools/designer/examples/colortool/optionsform.ui | 153 + tools/designer/examples/colortool/optionsform.ui.h | 7 + tools/designer/examples/credit/credit.pro | 11 + tools/designer/examples/credit/creditform.cpp | 20 + tools/designer/examples/credit/creditform.h | 12 + tools/designer/examples/credit/creditformbase.cpp | 122 + tools/designer/examples/credit/creditformbase.h | 48 + tools/designer/examples/credit/creditformbase.ui | 212 + tools/designer/examples/credit/creditformbase.ui.h | 5 + tools/designer/examples/credit/main.cpp | 25 + .../examples/filechooser/plugin/plugin.cpp | 95 + .../designer/examples/filechooser/plugin/plugin.h | 16 + .../examples/filechooser/plugin/plugin.pro | 14 + .../examples/filechooser/widget/filechooser.cpp | 62 + .../examples/filechooser/widget/filechooser.h | 48 + .../examples/filechooser/widget/filechooser.pro | 9 + .../designer/examples/filechooser/widget/main.cpp | 10 + tools/designer/examples/metric/main.cpp | 12 + tools/designer/examples/metric/metric.pro | 12 + tools/designer/examples/metric/metric.ui | 366 ++ tools/designer/examples/metric/metric.ui.h | 72 + tools/designer/examples/multiclip/main.cpp | 25 + tools/designer/examples/multiclip/multiclip.pro | 9 + tools/designer/examples/multiclip/multiclip.ui | 206 + tools/designer/examples/multiclip/multiclip.ui.h | 70 + tools/designer/examples/opengl/glwidget.cpp | 170 + tools/designer/examples/opengl/glwidget.h | 75 + tools/designer/examples/opengl/main.cpp | 305 ++ tools/designer/examples/opengl/opengl.pro | 11 + tools/designer/examples/receiver1/main.cpp | 24 + tools/designer/examples/receiver1/mainform.ui | 87 + tools/designer/examples/receiver1/mainform.ui.h | 25 + tools/designer/examples/receiver1/receiver.pro | 11 + tools/designer/examples/receiver2/main.cpp | 25 + tools/designer/examples/receiver2/mainform.ui | 82 + tools/designer/examples/receiver2/mainform.ui.h | 20 + tools/designer/examples/receiver2/receiver.cpp | 29 + tools/designer/examples/receiver2/receiver.h | 13 + tools/designer/examples/receiver2/receiver.pro | 12 + .../designer/examples/richedit/images/editcopy.png | Bin 0 -> 187 bytes .../designer/examples/richedit/images/editcut.png | Bin 0 -> 163 bytes .../examples/richedit/images/editpaste.png | Bin 0 -> 209 bytes .../designer/examples/richedit/images/filenew.png | Bin 0 -> 127 bytes .../designer/examples/richedit/images/fileopen.png | Bin 0 -> 178 bytes .../designer/examples/richedit/images/filesave.png | Bin 0 -> 158 bytes tools/designer/examples/richedit/images/redo.png | Bin 0 -> 149 bytes .../designer/examples/richedit/images/textbold.png | Bin 0 -> 119 bytes .../examples/richedit/images/textcenter.png | Bin 0 -> 92 bytes .../examples/richedit/images/textitalic.png | Bin 0 -> 102 bytes .../designer/examples/richedit/images/textleft.png | Bin 0 -> 90 bytes .../examples/richedit/images/textright.png | Bin 0 -> 93 bytes .../examples/richedit/images/textunder.png | Bin 0 -> 115 bytes tools/designer/examples/richedit/images/undo.png | Bin 0 -> 150 bytes tools/designer/examples/richedit/main.cpp | 25 + tools/designer/examples/richedit/richedit.pro | 10 + tools/designer/examples/richedit/richedit.ui | 612 +++ tools/designer/examples/richedit/richedit.ui.h | 120 + tools/designer/examples/sizeaware/main.cpp | 11 + tools/designer/examples/sizeaware/sizeaware.cpp | 38 + tools/designer/examples/sizeaware/sizeaware.h | 23 + tools/designer/examples/sizeaware/sizeaware.pro | 6 + tools/designer/examples/vcr/main.cpp | 10 + tools/designer/examples/vcr/play.xpm | 23 + tools/designer/examples/vcr/vcr.cpp | 117 + tools/designer/examples/vcr/vcr.h | 17 + tools/designer/examples/vcr/vcr.pro | 8 + tools/designer/integration/designer.el | 19 + tools/designer/interfaces/actioninterface.h | 85 + tools/designer/interfaces/classbrowserinterface.h | 70 + tools/designer/interfaces/designerinterface.h | 268 ++ tools/designer/interfaces/editorinterface.h | 109 + tools/designer/interfaces/filterinterface.h | 75 + tools/designer/interfaces/interpreterinterface.h | 66 + tools/designer/interfaces/languageinterface.h | 138 + tools/designer/interfaces/preferenceinterface.h | 75 + tools/designer/interfaces/projectsettingsiface.h | 76 + tools/designer/interfaces/sourcetemplateiface.h | 72 + tools/designer/interfaces/templatewizardiface.h | 67 + tools/designer/interfaces/widgetinterface.h | 42 + tools/designer/plugins/cppeditor/common.cpp | 111 + tools/designer/plugins/cppeditor/cppbrowser.cpp | 78 + tools/designer/plugins/cppeditor/cppbrowser.h | 50 + tools/designer/plugins/cppeditor/cppcompletion.cpp | 220 + tools/designer/plugins/cppeditor/cppcompletion.h | 60 + tools/designer/plugins/cppeditor/cppeditor.cpp | 168 + tools/designer/plugins/cppeditor/cppeditor.h | 78 + tools/designer/plugins/cppeditor/cppeditor.pro | 21 + .../plugins/cppeditor/editorinterfaceimpl.cpp | 338 ++ .../plugins/cppeditor/editorinterfaceimpl.h | 107 + .../plugins/cppeditor/languageinterfaceimpl.cpp | 249 + .../plugins/cppeditor/languageinterfaceimpl.h | 90 + .../designer/plugins/cppeditor/mainfilesettings.ui | 211 + .../plugins/cppeditor/mainfilesettings.ui.h | 36 + .../plugins/cppeditor/preferenceinterfaceimpl.cpp | 102 + .../plugins/cppeditor/preferenceinterfaceimpl.h | 64 + .../designer/plugins/cppeditor/projectsettings.ui | 347 ++ .../plugins/cppeditor/projectsettings.ui.h | 106 + .../cppeditor/projectsettingsinterfaceimpl.cpp | 106 + .../cppeditor/projectsettingsinterfaceimpl.h | 62 + .../cppeditor/sourcetemplateinterfaceimpl.cpp | 117 + .../cppeditor/sourcetemplateinterfaceimpl.h | 54 + .../plugins/cppeditor/syntaxhighliter_cpp.cpp | 550 +++ .../plugins/cppeditor/syntaxhighliter_cpp.h | 73 + tools/designer/plugins/cppeditor/yyreg.cpp | 800 ++++ tools/designer/plugins/cppeditor/yyreg.h | 88 + tools/designer/plugins/dlg/dlg.pro | 13 + tools/designer/plugins/dlg/dlg2ui.cpp | 1632 +++++++ tools/designer/plugins/dlg/dlg2ui.h | 144 + tools/designer/plugins/dlg/main.cpp | 108 + tools/designer/plugins/glade/glade.pro | 13 + tools/designer/plugins/glade/glade2ui.cpp | 2203 +++++++++ tools/designer/plugins/glade/glade2ui.h | 169 + tools/designer/plugins/glade/main.cpp | 109 + tools/designer/plugins/kdevdlg/kdevdlg.pro | 11 + tools/designer/plugins/kdevdlg/kdevdlg2ui.cpp | 524 +++ tools/designer/plugins/kdevdlg/kdevdlg2ui.h | 90 + tools/designer/plugins/kdevdlg/main.cpp | 120 + tools/designer/plugins/plugins.pro | 9 + tools/designer/plugins/rc/main.cpp | 117 + tools/designer/plugins/rc/rc.pro | 11 + tools/designer/plugins/rc/rc2ui.cpp | 888 ++++ tools/designer/plugins/rc/rc2ui.h | 103 + .../plugins/wizards/images/qtwizards_menu_1.png | Bin 0 -> 10172 bytes .../plugins/wizards/images/qtwizards_menu_2.png | Bin 0 -> 12582 bytes .../plugins/wizards/images/qtwizards_menu_3.png | Bin 0 -> 11653 bytes .../plugins/wizards/images/qtwizards_table_1.png | Bin 0 -> 13382 bytes .../plugins/wizards/images/qtwizards_table_2.png | Bin 0 -> 15245 bytes .../plugins/wizards/images/qtwizards_table_3.png | Bin 0 -> 16105 bytes .../plugins/wizards/images/qtwizards_table_4.png | Bin 0 -> 7894 bytes tools/designer/plugins/wizards/images/re-sort.png | Bin 0 -> 254 bytes .../plugins/wizards/images/small/editcopy.png | Bin 0 -> 172 bytes .../plugins/wizards/images/small/editcut.png | Bin 0 -> 157 bytes .../plugins/wizards/images/small/editpaste.png | Bin 0 -> 199 bytes .../plugins/wizards/images/small/filenew.png | Bin 0 -> 119 bytes .../plugins/wizards/images/small/fileopen.png | Bin 0 -> 165 bytes .../plugins/wizards/images/small/filesave.png | Bin 0 -> 150 bytes .../plugins/wizards/images/small/print.png | Bin 0 -> 586 bytes .../designer/plugins/wizards/images/small/redo.png | Bin 0 -> 137 bytes .../plugins/wizards/images/small/searchfind.png | Bin 0 -> 534 bytes .../designer/plugins/wizards/images/small/undo.png | Bin 0 -> 137 bytes tools/designer/plugins/wizards/main.cpp | 142 + tools/designer/plugins/wizards/mainwindowwizard.ui | 757 +++ .../designer/plugins/wizards/mainwindowwizard.ui.h | 321 ++ tools/designer/plugins/wizards/sqlformwizard.ui | 1776 +++++++ .../designer/plugins/wizards/sqlformwizardimpl.cpp | 624 +++ tools/designer/plugins/wizards/sqlformwizardimpl.h | 87 + tools/designer/plugins/wizards/wizards.pro | 21 + tools/designer/shared/domtool.cpp | 460 ++ tools/designer/shared/domtool.h | 60 + tools/designer/shared/globaldefs.h | 69 + tools/designer/shared/parser.cpp | 79 + tools/designer/shared/parser.h | 46 + tools/designer/shared/ui2uib.cpp | 900 ++++ tools/designer/shared/ui2uib.h | 42 + tools/designer/shared/uib.cpp | 49 + tools/designer/shared/uib.h | 159 + tools/designer/shared/widgetdatabase.cpp | 960 ++++ tools/designer/shared/widgetdatabase.h | 103 + tools/designer/templates/Configuration_Dialog.ui | 162 + .../templates/Dialog_with_Buttons_(Bottom).ui | 122 + .../templates/Dialog_with_Buttons_(Right).ui | 122 + tools/designer/templates/Tab_Dialog.ui | 146 + tools/designer/tools/conv2ui/conv2ui.pro | 10 + tools/designer/tools/conv2ui/main.cpp | 220 + tools/designer/tools/createcw/README | 18 + tools/designer/tools/createcw/createcw.pro | 8 + tools/designer/tools/createcw/main.cpp | 190 + tools/designer/uic/embed.cpp | 316 ++ tools/designer/uic/form.cpp | 1452 ++++++ tools/designer/uic/main.cpp | 358 ++ tools/designer/uic/object.cpp | 745 +++ tools/designer/uic/subclassing.cpp | 352 ++ tools/designer/uic/uic.cpp | 1129 +++++ tools/designer/uic/uic.h | 176 + tools/designer/uic/uic.pro | 42 + tools/designer/uilib/qwidgetfactory.cpp | 2623 +++++++++++ tools/designer/uilib/qwidgetfactory.h | 187 + tools/designer/uilib/test/main.cpp | 50 + tools/designer/uilib/test/test.pro | 7 + tools/designer/uilib/uilib.pro | 30 + tools/linguist/LICENSE.GPL | 280 ++ tools/linguist/book/images/doneandnext.png | Bin 0 -> 445 bytes tools/linguist/book/images/editcopy.png | Bin 0 -> 587 bytes tools/linguist/book/images/editcut.png | Bin 0 -> 480 bytes tools/linguist/book/images/editfind.png | Bin 0 -> 776 bytes tools/linguist/book/images/editpaste.png | Bin 0 -> 664 bytes tools/linguist/book/images/editredo.png | Bin 0 -> 362 bytes tools/linguist/book/images/editundo.png | Bin 0 -> 353 bytes tools/linguist/book/images/fileopen.png | Bin 0 -> 523 bytes tools/linguist/book/images/fileprint.png | Bin 0 -> 767 bytes tools/linguist/book/images/filesave.png | Bin 0 -> 510 bytes tools/linguist/book/images/finddialog.png | Bin 0 -> 3165 bytes tools/linguist/book/images/linguist.png | Bin 0 -> 22819 bytes tools/linguist/book/images/menubar.png | Bin 0 -> 511 bytes tools/linguist/book/images/next.png | Bin 0 -> 418 bytes tools/linguist/book/images/nextunfinished.png | Bin 0 -> 456 bytes tools/linguist/book/images/phrasebookdialog.png | Bin 0 -> 4857 bytes tools/linguist/book/images/phrasebookopen.png | Bin 0 -> 883 bytes tools/linguist/book/images/prev.png | Bin 0 -> 412 bytes tools/linguist/book/images/prevunfinished.png | Bin 0 -> 449 bytes tools/linguist/book/images/toolbar.png | Bin 0 -> 5397 bytes tools/linguist/book/images/tt1_en.png | Bin 0 -> 872 bytes tools/linguist/book/images/tt1_la.png | Bin 0 -> 894 bytes tools/linguist/book/images/tt2_en.png | Bin 0 -> 1615 bytes tools/linguist/book/images/tt2_fr.png | Bin 0 -> 1854 bytes tools/linguist/book/images/tt2_nl.png | Bin 0 -> 1881 bytes tools/linguist/book/images/tt3_10_en.png | Bin 0 -> 2286 bytes tools/linguist/book/images/tt3_10_pt_bad.png | Bin 0 -> 2411 bytes tools/linguist/book/images/tt3_10_pt_good.png | Bin 0 -> 2485 bytes tools/linguist/book/images/tt3_11_about_pt.png | Bin 0 -> 2720 bytes tools/linguist/book/images/tt3_11_en.png | Bin 0 -> 2368 bytes tools/linguist/book/images/tt3_11_pt.png | Bin 0 -> 2537 bytes .../linguist/book/images/validateaccelerators.png | Bin 0 -> 387 bytes tools/linguist/book/images/validatephrases.png | Bin 0 -> 293 bytes tools/linguist/book/images/validatepunctuation.png | Bin 0 -> 373 bytes tools/linguist/book/linguist-manager.leaf | 138 + tools/linguist/book/linguist-manual.book | 90 + tools/linguist/book/linguist-programmer.leaf | 1145 +++++ tools/linguist/book/linguist-translator.leaf | 582 +++ tools/linguist/linguist.pro | 11 + tools/linguist/linguist/about.ui | 223 + tools/linguist/linguist/finddialog.cpp | 183 + tools/linguist/linguist/finddialog.h | 68 + tools/linguist/linguist/images/accelerator.png | Bin 0 -> 782 bytes tools/linguist/linguist/images/appicon.png | Bin 0 -> 1936 bytes tools/linguist/linguist/images/book.png | Bin 0 -> 825 bytes tools/linguist/linguist/images/d_accelerator.png | Bin 0 -> 487 bytes tools/linguist/linguist/images/d_book.png | Bin 0 -> 557 bytes tools/linguist/linguist/images/d_doneandnext.png | Bin 0 -> 457 bytes tools/linguist/linguist/images/d_editcopy.png | Bin 0 -> 526 bytes tools/linguist/linguist/images/d_editcut.png | Bin 0 -> 800 bytes tools/linguist/linguist/images/d_editpaste.png | Bin 0 -> 610 bytes tools/linguist/linguist/images/d_fileopen.png | Bin 0 -> 406 bytes tools/linguist/linguist/images/d_filesave.png | Bin 0 -> 267 bytes tools/linguist/linguist/images/d_next.png | Bin 0 -> 446 bytes .../linguist/linguist/images/d_nextunfinished.png | Bin 0 -> 522 bytes tools/linguist/linguist/images/d_phrase.png | Bin 0 -> 290 bytes tools/linguist/linguist/images/d_prev.png | Bin 0 -> 425 bytes .../linguist/linguist/images/d_prevunfinished.png | Bin 0 -> 542 bytes tools/linguist/linguist/images/d_print.png | Bin 0 -> 595 bytes tools/linguist/linguist/images/d_punctuation.png | Bin 0 -> 356 bytes tools/linguist/linguist/images/d_redo.png | Bin 0 -> 465 bytes .../linguist/linguist/images/d_s_check_danger.png | Bin 0 -> 270 bytes tools/linguist/linguist/images/d_s_check_obs.png | Bin 0 -> 220 bytes tools/linguist/linguist/images/d_s_check_off.png | Bin 0 -> 348 bytes tools/linguist/linguist/images/d_s_check_on.png | Bin 0 -> 220 bytes tools/linguist/linguist/images/d_searchfind.png | Bin 0 -> 501 bytes tools/linguist/linguist/images/d_undo.png | Bin 0 -> 471 bytes tools/linguist/linguist/images/doneandnext.png | Bin 0 -> 532 bytes tools/linguist/linguist/images/editcopy.png | Bin 0 -> 491 bytes tools/linguist/linguist/images/editcut.png | Bin 0 -> 649 bytes tools/linguist/linguist/images/editpaste.png | Bin 0 -> 864 bytes tools/linguist/linguist/images/fileopen.png | Bin 0 -> 681 bytes tools/linguist/linguist/images/filesave.png | Bin 0 -> 328 bytes tools/linguist/linguist/images/next.png | Bin 0 -> 541 bytes tools/linguist/linguist/images/nextunfinished.png | Bin 0 -> 649 bytes tools/linguist/linguist/images/pagecurl.png | Bin 0 -> 1247 bytes tools/linguist/linguist/images/phrase.png | Bin 0 -> 366 bytes tools/linguist/linguist/images/prev.png | Bin 0 -> 542 bytes tools/linguist/linguist/images/prevunfinished.png | Bin 0 -> 725 bytes tools/linguist/linguist/images/print.png | Bin 0 -> 766 bytes tools/linguist/linguist/images/punctuation.png | Bin 0 -> 502 bytes tools/linguist/linguist/images/redo.png | Bin 0 -> 592 bytes tools/linguist/linguist/images/s_check_danger.png | Bin 0 -> 326 bytes tools/linguist/linguist/images/s_check_obs.png | Bin 0 -> 245 bytes tools/linguist/linguist/images/s_check_off.png | Bin 0 -> 439 bytes tools/linguist/linguist/images/s_check_on.png | Bin 0 -> 235 bytes tools/linguist/linguist/images/searchfind.png | Bin 0 -> 843 bytes tools/linguist/linguist/images/splash.png | Bin 0 -> 31939 bytes tools/linguist/linguist/images/undo.png | Bin 0 -> 572 bytes tools/linguist/linguist/images/whatsthis.xpm | 24 + tools/linguist/linguist/linguist.icns | Bin 0 -> 47620 bytes tools/linguist/linguist/linguist.ico | Bin 0 -> 10134 bytes tools/linguist/linguist/linguist.pro | 109 + tools/linguist/linguist/linguist.rc | 1 + tools/linguist/linguist/linguist_de.ts | 993 ++++ tools/linguist/linguist/linguist_fr.ts | 993 ++++ tools/linguist/linguist/listviews.cpp | 350 ++ tools/linguist/linguist/listviews.h | 135 + tools/linguist/linguist/main.cpp | 89 + tools/linguist/linguist/msgedit.cpp | 834 ++++ tools/linguist/linguist/msgedit.h | 244 + tools/linguist/linguist/phrase.cpp | 189 + tools/linguist/linguist/phrase.h | 74 + tools/linguist/linguist/phrasebookbox.cpp | 244 + tools/linguist/linguist/phrasebookbox.h | 84 + tools/linguist/linguist/phraselv.cpp | 171 + tools/linguist/linguist/phraselv.h | 83 + tools/linguist/linguist/printout.cpp | 182 + tools/linguist/linguist/printout.h | 126 + tools/linguist/linguist/simtexth.cpp | 239 + tools/linguist/linguist/simtexth.h | 64 + tools/linguist/linguist/statistics.ui | 259 + tools/linguist/linguist/statistics.ui.h | 53 + tools/linguist/linguist/trwindow.cpp | 2071 ++++++++ tools/linguist/linguist/trwindow.h | 237 + tools/linguist/lrelease/lrelease.pro | 17 + tools/linguist/lrelease/main.cpp | 203 + tools/linguist/lupdate/fetchtr.cpp | 824 ++++ tools/linguist/lupdate/lupdate.pro | 21 + tools/linguist/lupdate/main.cpp | 241 + tools/linguist/lupdate/merge.cpp | 129 + tools/linguist/lupdate/numberh.cpp | 248 + tools/linguist/lupdate/sametexth.cpp | 97 + tools/linguist/phrasebooks/danish.qph | 1018 ++++ tools/linguist/phrasebooks/dutch.qph | 1044 ++++ tools/linguist/phrasebooks/finnish.qph | 1033 ++++ tools/linguist/phrasebooks/french.qph | 1104 +++++ tools/linguist/phrasebooks/german.qph | 1075 +++++ tools/linguist/phrasebooks/italian.qph | 1105 +++++ tools/linguist/phrasebooks/norwegian.qph | 1004 ++++ tools/linguist/phrasebooks/russian.qph | 982 ++++ tools/linguist/phrasebooks/spanish.qph | 1086 +++++ tools/linguist/phrasebooks/swedish.qph | 1010 ++++ tools/linguist/qdoc.conf | 15 + tools/linguist/qm2ts/main.cpp | 128 + tools/linguist/qm2ts/qm2ts.1 | 55 + tools/linguist/qm2ts/qm2ts.pro | 15 + tools/linguist/shared/metatranslator.cpp | 601 +++ tools/linguist/shared/metatranslator.h | 120 + tools/linguist/shared/proparser.cpp | 217 + tools/linguist/shared/proparser.h | 42 + tools/linguist/tutorial/tt1/main.cpp | 25 + tools/linguist/tutorial/tt1/tt1.pro | 4 + tools/linguist/tutorial/tt2/arrowpad.cpp | 31 + tools/linguist/tutorial/tt2/arrowpad.h | 22 + tools/linguist/tutorial/tt2/main.cpp | 26 + tools/linguist/tutorial/tt2/mainwindow.cpp | 26 + tools/linguist/tutorial/tt2/mainwindow.h | 19 + tools/linguist/tutorial/tt2/tt2.pro | 9 + tools/linguist/tutorial/tt3/main.cpp | 26 + tools/linguist/tutorial/tt3/mainwindow.cpp | 47 + tools/linguist/tutorial/tt3/mainwindow.h | 23 + tools/linguist/tutorial/tt3/printpanel.cpp | 37 + tools/linguist/tutorial/tt3/printpanel.h | 19 + tools/linguist/tutorial/tt3/tt3.pro | 8 + tools/linguist/tutorial/tt3/tt3_pt.ts | 65 + tools/makeqpf/main.cpp | 320 ++ tools/makeqpf/makeall | 4 + tools/makeqpf/makeqpf.pro | 10 + tools/mergetr/mergetr.cpp | 347 ++ tools/mergetr/mergetr.pro | 9 + tools/msg2qm/msg2qm.cpp | 236 + tools/msg2qm/msg2qm.pro | 10 + tools/qconfig/LICENSE.GPL | 280 ++ tools/qconfig/main.cpp | 733 +++ tools/qconfig/main.h | 86 + tools/qconfig/qconfig.pro | 7 + tools/qembed/qembed.cpp | 338 ++ tools/qembed/qembed.pro | 7 + tools/qtconfig/LICENSE.GPL | 280 ++ tools/qtconfig/colorbutton.cpp | 177 + tools/qtconfig/colorbutton.h | 82 + tools/qtconfig/images/appicon.png | Bin 0 -> 714 bytes tools/qtconfig/main.cpp | 45 + tools/qtconfig/mainwindow.cpp | 1142 +++++ tools/qtconfig/mainwindow.h | 104 + tools/qtconfig/mainwindowbase.ui | 1846 ++++++++ tools/qtconfig/paletteeditoradvanced.cpp | 615 +++ tools/qtconfig/paletteeditoradvanced.h | 98 + tools/qtconfig/paletteeditoradvancedbase.ui | 682 +++ tools/qtconfig/previewframe.cpp | 63 + tools/qtconfig/previewframe.h | 67 + tools/qtconfig/previewwidget.cpp | 75 + tools/qtconfig/previewwidget.h | 50 + tools/qtconfig/previewwidgetbase.ui | 311 ++ tools/qtconfig/qtconfig.pro | 18 + tools/qvfb/LICENSE.GPL | 280 ++ tools/qvfb/README | 55 + tools/qvfb/config.ui | 1684 +++++++ tools/qvfb/gammaview.h | 49 + tools/qvfb/images/logo.png | Bin 0 -> 714 bytes tools/qvfb/main.cpp | 97 + tools/qvfb/pda.skin | 15 + tools/qvfb/pda_down.png | Bin 0 -> 94345 bytes tools/qvfb/pda_up.png | Bin 0 -> 92698 bytes tools/qvfb/qanimationwriter.cpp | 414 ++ tools/qvfb/qanimationwriter.h | 59 + tools/qvfb/qvfb.cpp | 389 ++ tools/qvfb/qvfb.h | 91 + tools/qvfb/qvfb.pro | 11 + tools/qvfb/qvfbratedlg.cpp | 80 + tools/qvfb/qvfbratedlg.h | 59 + tools/qvfb/qvfbview.cpp | 615 +++ tools/qvfb/qvfbview.h | 126 + tools/qvfb/skin.cpp | 174 + tools/qvfb/skin.h | 78 + tools/tools.pro | 18 + 941 files changed, 168282 insertions(+) create mode 100644 tools/assistant/LICENSE.GPL create mode 100644 tools/assistant/assistant.icns create mode 100644 tools/assistant/assistant.ico create mode 100644 tools/assistant/assistant.pro create mode 100644 tools/assistant/assistant.rc create mode 100644 tools/assistant/assistant_de.qm create mode 100644 tools/assistant/assistant_de.ts create mode 100644 tools/assistant/assistant_fr.ts create mode 100644 tools/assistant/book/assistant.book create mode 100644 tools/assistant/book/assistant.leaf create mode 100644 tools/assistant/book/images/assistant.png create mode 100644 tools/assistant/book/images/docwindow.png create mode 100644 tools/assistant/book/images/general.png create mode 100644 tools/assistant/book/images/pdf1.png create mode 100644 tools/assistant/book/images/search.png create mode 100644 tools/assistant/book/images/sidebar.png create mode 100644 tools/assistant/book/images/toolbar1.png create mode 100644 tools/assistant/book/images/web.png create mode 100644 tools/assistant/config.cpp create mode 100644 tools/assistant/config.h create mode 100644 tools/assistant/docuparser.cpp create mode 100644 tools/assistant/docuparser.h create mode 100644 tools/assistant/finddialog.ui create mode 100644 tools/assistant/finddialog.ui.h create mode 100644 tools/assistant/helpdialog.ui create mode 100644 tools/assistant/helpdialogimpl.cpp create mode 100644 tools/assistant/helpdialogimpl.h create mode 100644 tools/assistant/helpwindow.cpp create mode 100644 tools/assistant/helpwindow.h create mode 100644 tools/assistant/images/addtab.png create mode 100644 tools/assistant/images/appicon.png create mode 100644 tools/assistant/images/assistant.png create mode 100644 tools/assistant/images/book.png create mode 100644 tools/assistant/images/closetab.png create mode 100644 tools/assistant/images/d_closetab.png create mode 100644 tools/assistant/images/designer.png create mode 100644 tools/assistant/images/editcopy.png create mode 100644 tools/assistant/images/find.png create mode 100644 tools/assistant/images/home.png create mode 100644 tools/assistant/images/linguist.png create mode 100644 tools/assistant/images/next.png create mode 100644 tools/assistant/images/previous.png create mode 100644 tools/assistant/images/print.png create mode 100644 tools/assistant/images/qt.png create mode 100644 tools/assistant/images/splash.png create mode 100644 tools/assistant/images/whatsthis.xpm create mode 100644 tools/assistant/images/zoomin.png create mode 100644 tools/assistant/images/zoomout.png create mode 100644 tools/assistant/index.cpp create mode 100644 tools/assistant/index.h create mode 100644 tools/assistant/lib/lib.pro create mode 100644 tools/assistant/lib/qassistantclient.cpp create mode 100644 tools/assistant/lib/qassistantclient.h create mode 100644 tools/assistant/main.cpp create mode 100644 tools/assistant/mainwindow.ui create mode 100644 tools/assistant/mainwindow.ui.h create mode 100644 tools/assistant/profile.cpp create mode 100644 tools/assistant/profile.h create mode 100644 tools/assistant/settingsdialog.ui create mode 100644 tools/assistant/settingsdialogimpl.cpp create mode 100644 tools/assistant/settingsdialogimpl.h create mode 100644 tools/assistant/tabbedbrowser.ui create mode 100644 tools/assistant/tabbedbrowser.ui.h create mode 100644 tools/assistant/topicchooser.ui create mode 100644 tools/assistant/topicchooserimpl.cpp create mode 100644 tools/assistant/topicchooserimpl.h create mode 100644 tools/designer/LICENSE.GPL create mode 100644 tools/designer/app/app.pro create mode 100644 tools/designer/app/designer.icns create mode 100644 tools/designer/app/designer.ico create mode 100644 tools/designer/app/designer.rc create mode 100644 tools/designer/app/main.cpp create mode 100644 tools/designer/designer.pro create mode 100644 tools/designer/designer/about.ui create mode 100644 tools/designer/designer/actiondnd.cpp create mode 100644 tools/designer/designer/actiondnd.h create mode 100644 tools/designer/designer/actioneditor.ui create mode 100644 tools/designer/designer/actioneditorimpl.cpp create mode 100644 tools/designer/designer/actioneditorimpl.h create mode 100644 tools/designer/designer/actionlistview.cpp create mode 100644 tools/designer/designer/actionlistview.h create mode 100644 tools/designer/designer/asciivalidator.cpp create mode 100644 tools/designer/designer/asciivalidator.h create mode 100644 tools/designer/designer/command.cpp create mode 100644 tools/designer/designer/command.h create mode 100644 tools/designer/designer/configtoolboxdialog.ui create mode 100644 tools/designer/designer/configtoolboxdialog.ui.h create mode 100644 tools/designer/designer/connectiondialog.ui create mode 100644 tools/designer/designer/connectiondialog.ui.h create mode 100644 tools/designer/designer/connectionitems.cpp create mode 100644 tools/designer/designer/connectionitems.h create mode 100644 tools/designer/designer/connectiontable.cpp create mode 100644 tools/designer/designer/connectiontable.h create mode 100644 tools/designer/designer/createtemplate.ui create mode 100644 tools/designer/designer/customwidgeteditor.ui create mode 100644 tools/designer/designer/customwidgeteditorimpl.cpp create mode 100644 tools/designer/designer/customwidgeteditorimpl.h create mode 100644 tools/designer/designer/database.cpp create mode 100644 tools/designer/designer/database.h create mode 100644 tools/designer/designer/database2.h create mode 100644 tools/designer/designer/dbconnection.ui create mode 100644 tools/designer/designer/dbconnectioneditor.ui create mode 100644 tools/designer/designer/dbconnectionimpl.cpp create mode 100644 tools/designer/designer/dbconnectionimpl.h create mode 100644 tools/designer/designer/dbconnections.ui create mode 100644 tools/designer/designer/dbconnectionsimpl.cpp create mode 100644 tools/designer/designer/dbconnectionsimpl.h create mode 100644 tools/designer/designer/defs.cpp create mode 100644 tools/designer/designer/defs.h create mode 100644 tools/designer/designer/designer.pro create mode 100644 tools/designer/designer/designer_de.ts create mode 100644 tools/designer/designer/designer_fr.ts create mode 100644 tools/designer/designer/designer_pch.h create mode 100644 tools/designer/designer/designerapp.cpp create mode 100644 tools/designer/designer/designerapp.h create mode 100644 tools/designer/designer/designerappiface.cpp create mode 100644 tools/designer/designer/designerappiface.h create mode 100644 tools/designer/designer/editfunctions.ui create mode 100644 tools/designer/designer/editfunctionsimpl.cpp create mode 100644 tools/designer/designer/editfunctionsimpl.h create mode 100644 tools/designer/designer/finddialog.ui create mode 100644 tools/designer/designer/finddialog.ui.h create mode 100644 tools/designer/designer/formfile.cpp create mode 100644 tools/designer/designer/formfile.h create mode 100644 tools/designer/designer/formsettings.ui create mode 100644 tools/designer/designer/formsettingsimpl.cpp create mode 100644 tools/designer/designer/formsettingsimpl.h create mode 100644 tools/designer/designer/formwindow.cpp create mode 100644 tools/designer/designer/formwindow.h create mode 100644 tools/designer/designer/gotolinedialog.ui create mode 100644 tools/designer/designer/gotolinedialog.ui.h create mode 100644 tools/designer/designer/hierarchyview.cpp create mode 100644 tools/designer/designer/hierarchyview.h create mode 100644 tools/designer/designer/iconvieweditor.ui create mode 100644 tools/designer/designer/iconvieweditorimpl.cpp create mode 100644 tools/designer/designer/iconvieweditorimpl.h create mode 100644 tools/designer/designer/images/designer_adjustsize.png create mode 100644 tools/designer/designer/images/designer_appicon.png create mode 100644 tools/designer/designer/images/designer_arrow.png create mode 100644 tools/designer/designer/images/designer_background.png create mode 100644 tools/designer/designer/images/designer_book.png create mode 100644 tools/designer/designer/images/designer_buttongroup.png create mode 100644 tools/designer/designer/images/designer_checkbox.png create mode 100644 tools/designer/designer/images/designer_combobox.png create mode 100644 tools/designer/designer/images/designer_connecttool.png create mode 100644 tools/designer/designer/images/designer_cross.png create mode 100644 tools/designer/designer/images/designer_customwidget.png create mode 100644 tools/designer/designer/images/designer_d_adjustsize.png create mode 100644 tools/designer/designer/images/designer_d_book.png create mode 100644 tools/designer/designer/images/designer_d_buttongroup.png create mode 100644 tools/designer/designer/images/designer_d_checkbox.png create mode 100644 tools/designer/designer/images/designer_d_combobox.png create mode 100644 tools/designer/designer/images/designer_d_connecttool.png create mode 100644 tools/designer/designer/images/designer_d_customwidget.png create mode 100644 tools/designer/designer/images/designer_d_databrowser.png create mode 100644 tools/designer/designer/images/designer_d_datatable.png create mode 100644 tools/designer/designer/images/designer_d_dataview.png create mode 100644 tools/designer/designer/images/designer_d_dateedit.png create mode 100644 tools/designer/designer/images/designer_d_datetimeedit.png create mode 100644 tools/designer/designer/images/designer_d_dial.png create mode 100644 tools/designer/designer/images/designer_d_down.png create mode 100644 tools/designer/designer/images/designer_d_editbreaklayout.png create mode 100644 tools/designer/designer/images/designer_d_editcopy.png create mode 100644 tools/designer/designer/images/designer_d_editcut.png create mode 100644 tools/designer/designer/images/designer_d_editdelete.png create mode 100644 tools/designer/designer/images/designer_d_editgrid.png create mode 100644 tools/designer/designer/images/designer_d_edithlayout.png create mode 100644 tools/designer/designer/images/designer_d_edithlayoutsplit.png create mode 100644 tools/designer/designer/images/designer_d_editlower.png create mode 100644 tools/designer/designer/images/designer_d_editpaste.png create mode 100644 tools/designer/designer/images/designer_d_editraise.png create mode 100644 tools/designer/designer/images/designer_d_editslots.png create mode 100644 tools/designer/designer/images/designer_d_editvlayout.png create mode 100644 tools/designer/designer/images/designer_d_editvlayoutsplit.png create mode 100644 tools/designer/designer/images/designer_d_filenew.png create mode 100644 tools/designer/designer/images/designer_d_fileopen.png create mode 100644 tools/designer/designer/images/designer_d_filesave.png create mode 100644 tools/designer/designer/images/designer_d_folder.png create mode 100644 tools/designer/designer/images/designer_d_form.png create mode 100644 tools/designer/designer/images/designer_d_frame.png create mode 100644 tools/designer/designer/images/designer_d_groupbox.png create mode 100644 tools/designer/designer/images/designer_d_help.png create mode 100644 tools/designer/designer/images/designer_d_home.png create mode 100644 tools/designer/designer/images/designer_d_iconview.png create mode 100644 tools/designer/designer/images/designer_d_image.png create mode 100644 tools/designer/designer/images/designer_d_label.png create mode 100644 tools/designer/designer/images/designer_d_layout.png create mode 100644 tools/designer/designer/images/designer_d_lcdnumber.png create mode 100644 tools/designer/designer/images/designer_d_left.png create mode 100644 tools/designer/designer/images/designer_d_line.png create mode 100644 tools/designer/designer/images/designer_d_lineedit.png create mode 100644 tools/designer/designer/images/designer_d_listbox.png create mode 100644 tools/designer/designer/images/designer_d_listview.png create mode 100644 tools/designer/designer/images/designer_d_multilineedit.png create mode 100644 tools/designer/designer/images/designer_d_newform.png create mode 100644 tools/designer/designer/images/designer_d_ordertool.png create mode 100644 tools/designer/designer/images/designer_d_pixlabel.png create mode 100644 tools/designer/designer/images/designer_d_pointer.png create mode 100644 tools/designer/designer/images/designer_d_print.png create mode 100644 tools/designer/designer/images/designer_d_progress.png create mode 100644 tools/designer/designer/images/designer_d_project.png create mode 100644 tools/designer/designer/images/designer_d_pushbutton.png create mode 100644 tools/designer/designer/images/designer_d_radiobutton.png create mode 100644 tools/designer/designer/images/designer_d_redo.png create mode 100644 tools/designer/designer/images/designer_d_richtextedit.png create mode 100644 tools/designer/designer/images/designer_d_right.png create mode 100644 tools/designer/designer/images/designer_d_scrollbar.png create mode 100644 tools/designer/designer/images/designer_d_searchfind.png create mode 100644 tools/designer/designer/images/designer_d_setbuddy.png create mode 100644 tools/designer/designer/images/designer_d_slider.png create mode 100644 tools/designer/designer/images/designer_d_spacer.png create mode 100644 tools/designer/designer/images/designer_d_spinbox.png create mode 100644 tools/designer/designer/images/designer_d_table.png create mode 100644 tools/designer/designer/images/designer_d_tabwidget.png create mode 100644 tools/designer/designer/images/designer_d_textbold.png create mode 100644 tools/designer/designer/images/designer_d_textbrowser.png create mode 100644 tools/designer/designer/images/designer_d_textcenter.png create mode 100644 tools/designer/designer/images/designer_d_textedit.png create mode 100644 tools/designer/designer/images/designer_d_textfont.png create mode 100644 tools/designer/designer/images/designer_d_texth1.png create mode 100644 tools/designer/designer/images/designer_d_texth2.png create mode 100644 tools/designer/designer/images/designer_d_texth3.png create mode 100644 tools/designer/designer/images/designer_d_textitalic.png create mode 100644 tools/designer/designer/images/designer_d_textjustify.png create mode 100644 tools/designer/designer/images/designer_d_textlarger.png create mode 100644 tools/designer/designer/images/designer_d_textleft.png create mode 100644 tools/designer/designer/images/designer_d_textlinebreak.png create mode 100644 tools/designer/designer/images/designer_d_textparagraph.png create mode 100644 tools/designer/designer/images/designer_d_textright.png create mode 100644 tools/designer/designer/images/designer_d_textsmaller.png create mode 100644 tools/designer/designer/images/designer_d_textteletext.png create mode 100644 tools/designer/designer/images/designer_d_textunderline.png create mode 100644 tools/designer/designer/images/designer_d_textview.png create mode 100644 tools/designer/designer/images/designer_d_timeedit.png create mode 100644 tools/designer/designer/images/designer_d_toolbox.png create mode 100644 tools/designer/designer/images/designer_d_toolbutton.png create mode 100644 tools/designer/designer/images/designer_d_undo.png create mode 100644 tools/designer/designer/images/designer_d_up.png create mode 100644 tools/designer/designer/images/designer_d_widgetstack.png create mode 100644 tools/designer/designer/images/designer_d_wizarddata.png create mode 100644 tools/designer/designer/images/designer_d_wizarddialog.png create mode 100644 tools/designer/designer/images/designer_d_wordwrap.png create mode 100644 tools/designer/designer/images/designer_databrowser.png create mode 100644 tools/designer/designer/images/designer_datatable.png create mode 100644 tools/designer/designer/images/designer_dataview.png create mode 100644 tools/designer/designer/images/designer_dateedit.png create mode 100644 tools/designer/designer/images/designer_datetimeedit.png create mode 100644 tools/designer/designer/images/designer_dial.png create mode 100644 tools/designer/designer/images/designer_down.png create mode 100644 tools/designer/designer/images/designer_editbreaklayout.png create mode 100644 tools/designer/designer/images/designer_editcopy.png create mode 100644 tools/designer/designer/images/designer_editcut.png create mode 100644 tools/designer/designer/images/designer_editdelete.png create mode 100644 tools/designer/designer/images/designer_editgrid.png create mode 100644 tools/designer/designer/images/designer_edithlayout.png create mode 100644 tools/designer/designer/images/designer_edithlayoutsplit.png create mode 100644 tools/designer/designer/images/designer_editlower.png create mode 100644 tools/designer/designer/images/designer_editpaste.png create mode 100644 tools/designer/designer/images/designer_editraise.png create mode 100644 tools/designer/designer/images/designer_editslots.png create mode 100644 tools/designer/designer/images/designer_editvlayout.png create mode 100644 tools/designer/designer/images/designer_editvlayoutsplit.png create mode 100644 tools/designer/designer/images/designer_filenew.png create mode 100644 tools/designer/designer/images/designer_fileopen.png create mode 100644 tools/designer/designer/images/designer_filesave.png create mode 100644 tools/designer/designer/images/designer_folder.png create mode 100644 tools/designer/designer/images/designer_form.png create mode 100644 tools/designer/designer/images/designer_frame.png create mode 100644 tools/designer/designer/images/designer_groupbox.png create mode 100644 tools/designer/designer/images/designer_hand.png create mode 100644 tools/designer/designer/images/designer_help.png create mode 100644 tools/designer/designer/images/designer_home.png create mode 100644 tools/designer/designer/images/designer_hsplit.png create mode 100644 tools/designer/designer/images/designer_ibeam.png create mode 100644 tools/designer/designer/images/designer_iconview.png create mode 100644 tools/designer/designer/images/designer_image.png create mode 100644 tools/designer/designer/images/designer_label.png create mode 100644 tools/designer/designer/images/designer_layout.png create mode 100644 tools/designer/designer/images/designer_lcdnumber.png create mode 100644 tools/designer/designer/images/designer_left.png create mode 100644 tools/designer/designer/images/designer_line.png create mode 100644 tools/designer/designer/images/designer_lineedit.png create mode 100644 tools/designer/designer/images/designer_listbox.png create mode 100644 tools/designer/designer/images/designer_listview.png create mode 100644 tools/designer/designer/images/designer_multilineedit.png create mode 100644 tools/designer/designer/images/designer_newform.png create mode 100644 tools/designer/designer/images/designer_no.png create mode 100644 tools/designer/designer/images/designer_object.png create mode 100644 tools/designer/designer/images/designer_ordertool.png create mode 100644 tools/designer/designer/images/designer_pixlabel.png create mode 100644 tools/designer/designer/images/designer_pointer.png create mode 100644 tools/designer/designer/images/designer_print.png create mode 100644 tools/designer/designer/images/designer_progress.png create mode 100644 tools/designer/designer/images/designer_project.png create mode 100644 tools/designer/designer/images/designer_pushbutton.png create mode 100644 tools/designer/designer/images/designer_qtlogo.png create mode 100644 tools/designer/designer/images/designer_radiobutton.png create mode 100644 tools/designer/designer/images/designer_redo.png create mode 100644 tools/designer/designer/images/designer_resetproperty.png create mode 100644 tools/designer/designer/images/designer_richtextedit.png create mode 100644 tools/designer/designer/images/designer_right.png create mode 100644 tools/designer/designer/images/designer_s_down.png create mode 100644 tools/designer/designer/images/designer_s_editcut.png create mode 100644 tools/designer/designer/images/designer_s_left.png create mode 100644 tools/designer/designer/images/designer_s_right.png create mode 100644 tools/designer/designer/images/designer_s_up.png create mode 100644 tools/designer/designer/images/designer_scrollbar.png create mode 100644 tools/designer/designer/images/designer_searchfind.png create mode 100644 tools/designer/designer/images/designer_setbuddy.png create mode 100644 tools/designer/designer/images/designer_sizeall.png create mode 100644 tools/designer/designer/images/designer_sizeb.png create mode 100644 tools/designer/designer/images/designer_sizef.png create mode 100644 tools/designer/designer/images/designer_sizeh.png create mode 100644 tools/designer/designer/images/designer_sizev.png create mode 100644 tools/designer/designer/images/designer_slider.png create mode 100644 tools/designer/designer/images/designer_spacer.png create mode 100644 tools/designer/designer/images/designer_spinbox.png create mode 100644 tools/designer/designer/images/designer_splash.png create mode 100644 tools/designer/designer/images/designer_table.png create mode 100644 tools/designer/designer/images/designer_tabwidget.png create mode 100644 tools/designer/designer/images/designer_textbold.png create mode 100644 tools/designer/designer/images/designer_textbrowser.png create mode 100644 tools/designer/designer/images/designer_textcenter.png create mode 100644 tools/designer/designer/images/designer_textedit.png create mode 100644 tools/designer/designer/images/designer_textfont.png create mode 100644 tools/designer/designer/images/designer_texth1.png create mode 100644 tools/designer/designer/images/designer_texth2.png create mode 100644 tools/designer/designer/images/designer_texth3.png create mode 100644 tools/designer/designer/images/designer_textitalic.png create mode 100644 tools/designer/designer/images/designer_textjustify.png create mode 100644 tools/designer/designer/images/designer_textlarger.png create mode 100644 tools/designer/designer/images/designer_textleft.png create mode 100644 tools/designer/designer/images/designer_textlinebreak.png create mode 100644 tools/designer/designer/images/designer_textparagraph.png create mode 100644 tools/designer/designer/images/designer_textright.png create mode 100644 tools/designer/designer/images/designer_textsmaller.png create mode 100644 tools/designer/designer/images/designer_textteletext.png create mode 100644 tools/designer/designer/images/designer_textunderline.png create mode 100644 tools/designer/designer/images/designer_textview.png create mode 100644 tools/designer/designer/images/designer_timeedit.png create mode 100644 tools/designer/designer/images/designer_toolbox.png create mode 100644 tools/designer/designer/images/designer_toolbutton.png create mode 100644 tools/designer/designer/images/designer_undo.png create mode 100644 tools/designer/designer/images/designer_up.png create mode 100644 tools/designer/designer/images/designer_uparrow.png create mode 100644 tools/designer/designer/images/designer_vsplit.png create mode 100644 tools/designer/designer/images/designer_wait.png create mode 100644 tools/designer/designer/images/designer_widgetstack.png create mode 100644 tools/designer/designer/images/designer_wizarddata.png create mode 100644 tools/designer/designer/images/designer_wizarddialog.png create mode 100644 tools/designer/designer/images/designer_wordwrap.png create mode 100644 tools/designer/designer/layout.cpp create mode 100644 tools/designer/designer/layout.h create mode 100644 tools/designer/designer/listboxdnd.cpp create mode 100644 tools/designer/designer/listboxdnd.h create mode 100644 tools/designer/designer/listboxeditor.ui create mode 100644 tools/designer/designer/listboxeditorimpl.cpp create mode 100644 tools/designer/designer/listboxeditorimpl.h create mode 100644 tools/designer/designer/listboxrename.cpp create mode 100644 tools/designer/designer/listboxrename.h create mode 100644 tools/designer/designer/listdnd.cpp create mode 100644 tools/designer/designer/listdnd.h create mode 100644 tools/designer/designer/listeditor.ui create mode 100644 tools/designer/designer/listeditor.ui.h create mode 100644 tools/designer/designer/listviewdnd.cpp create mode 100644 tools/designer/designer/listviewdnd.h create mode 100644 tools/designer/designer/listvieweditor.ui create mode 100644 tools/designer/designer/listvieweditorimpl.cpp create mode 100644 tools/designer/designer/listvieweditorimpl.h create mode 100644 tools/designer/designer/mainwindow.cpp create mode 100644 tools/designer/designer/mainwindow.h create mode 100644 tools/designer/designer/mainwindowactions.cpp create mode 100644 tools/designer/designer/menubareditor.cpp create mode 100644 tools/designer/designer/menubareditor.h create mode 100644 tools/designer/designer/metadatabase.cpp create mode 100644 tools/designer/designer/metadatabase.h create mode 100644 tools/designer/designer/multilineeditor.ui create mode 100644 tools/designer/designer/multilineeditorimpl.cpp create mode 100644 tools/designer/designer/multilineeditorimpl.h create mode 100644 tools/designer/designer/newform.ui create mode 100644 tools/designer/designer/newformimpl.cpp create mode 100644 tools/designer/designer/newformimpl.h create mode 100644 tools/designer/designer/orderindicator.cpp create mode 100644 tools/designer/designer/orderindicator.h create mode 100644 tools/designer/designer/outputwindow.cpp create mode 100644 tools/designer/designer/outputwindow.h create mode 100644 tools/designer/designer/paletteeditor.ui create mode 100644 tools/designer/designer/paletteeditoradvanced.ui create mode 100644 tools/designer/designer/paletteeditoradvancedimpl.cpp create mode 100644 tools/designer/designer/paletteeditoradvancedimpl.h create mode 100644 tools/designer/designer/paletteeditorimpl.cpp create mode 100644 tools/designer/designer/paletteeditorimpl.h create mode 100644 tools/designer/designer/pixmapchooser.cpp create mode 100644 tools/designer/designer/pixmapchooser.h create mode 100644 tools/designer/designer/pixmapcollection.cpp create mode 100644 tools/designer/designer/pixmapcollection.h create mode 100644 tools/designer/designer/pixmapcollectioneditor.ui create mode 100644 tools/designer/designer/pixmapcollectioneditor.ui.h create mode 100644 tools/designer/designer/pixmapfunction.ui create mode 100644 tools/designer/designer/popupmenueditor.cpp create mode 100644 tools/designer/designer/popupmenueditor.h create mode 100644 tools/designer/designer/preferences.ui create mode 100644 tools/designer/designer/previewframe.cpp create mode 100644 tools/designer/designer/previewframe.h create mode 100644 tools/designer/designer/previewwidget.ui create mode 100644 tools/designer/designer/previewwidgetimpl.cpp create mode 100644 tools/designer/designer/previewwidgetimpl.h create mode 100644 tools/designer/designer/project.cpp create mode 100644 tools/designer/designer/project.h create mode 100644 tools/designer/designer/projectsettings.ui create mode 100644 tools/designer/designer/projectsettingsimpl.cpp create mode 100644 tools/designer/designer/projectsettingsimpl.h create mode 100644 tools/designer/designer/propertyeditor.cpp create mode 100644 tools/designer/designer/propertyeditor.h create mode 100644 tools/designer/designer/propertyobject.cpp create mode 100644 tools/designer/designer/propertyobject.h create mode 100644 tools/designer/designer/qcompletionedit.cpp create mode 100644 tools/designer/designer/qcompletionedit.h create mode 100644 tools/designer/designer/replacedialog.ui create mode 100644 tools/designer/designer/replacedialog.ui.h create mode 100644 tools/designer/designer/resource.cpp create mode 100644 tools/designer/designer/resource.h create mode 100644 tools/designer/designer/richtextfontdialog.ui create mode 100644 tools/designer/designer/richtextfontdialog.ui.h create mode 100644 tools/designer/designer/sizehandle.cpp create mode 100644 tools/designer/designer/sizehandle.h create mode 100644 tools/designer/designer/sourceeditor.cpp create mode 100644 tools/designer/designer/sourceeditor.h create mode 100644 tools/designer/designer/sourcefile.cpp create mode 100644 tools/designer/designer/sourcefile.h create mode 100644 tools/designer/designer/startdialog.ui create mode 100644 tools/designer/designer/startdialogimpl.cpp create mode 100644 tools/designer/designer/startdialogimpl.h create mode 100644 tools/designer/designer/styledbutton.cpp create mode 100644 tools/designer/designer/styledbutton.h create mode 100644 tools/designer/designer/syntaxhighlighter_html.cpp create mode 100644 tools/designer/designer/syntaxhighlighter_html.h create mode 100644 tools/designer/designer/tableeditor.ui create mode 100644 tools/designer/designer/tableeditorimpl.cpp create mode 100644 tools/designer/designer/tableeditorimpl.h create mode 100644 tools/designer/designer/timestamp.cpp create mode 100644 tools/designer/designer/timestamp.h create mode 100644 tools/designer/designer/variabledialog.ui create mode 100644 tools/designer/designer/variabledialogimpl.cpp create mode 100644 tools/designer/designer/variabledialogimpl.h create mode 100644 tools/designer/designer/widgetaction.cpp create mode 100644 tools/designer/designer/widgetaction.h create mode 100644 tools/designer/designer/widgetfactory.cpp create mode 100644 tools/designer/designer/widgetfactory.h create mode 100644 tools/designer/designer/wizardeditor.ui create mode 100644 tools/designer/designer/wizardeditorimpl.cpp create mode 100644 tools/designer/designer/wizardeditorimpl.h create mode 100644 tools/designer/designer/workspace.cpp create mode 100644 tools/designer/designer/workspace.h create mode 100644 tools/designer/editor/arghintwidget.cpp create mode 100644 tools/designer/editor/arghintwidget.h create mode 100644 tools/designer/editor/browser.cpp create mode 100644 tools/designer/editor/browser.h create mode 100644 tools/designer/editor/cindent.cpp create mode 100644 tools/designer/editor/cindent.h create mode 100644 tools/designer/editor/completion.cpp create mode 100644 tools/designer/editor/completion.h create mode 100644 tools/designer/editor/conf.cpp create mode 100644 tools/designer/editor/conf.h create mode 100644 tools/designer/editor/editor.cpp create mode 100644 tools/designer/editor/editor.h create mode 100644 tools/designer/editor/editor.pro create mode 100644 tools/designer/editor/markerwidget.cpp create mode 100644 tools/designer/editor/markerwidget.h create mode 100644 tools/designer/editor/paragdata.h create mode 100644 tools/designer/editor/parenmatcher.cpp create mode 100644 tools/designer/editor/parenmatcher.h create mode 100644 tools/designer/editor/preferences.ui create mode 100644 tools/designer/editor/preferences.ui.h create mode 100644 tools/designer/editor/viewmanager.cpp create mode 100644 tools/designer/editor/viewmanager.h create mode 100644 tools/designer/editor/yyindent.cpp create mode 100644 tools/designer/examples/addressbook/addressbook.pro create mode 100644 tools/designer/examples/addressbook/addressbook.ui create mode 100644 tools/designer/examples/addressbook/addressbook.ui.h create mode 100644 tools/designer/examples/addressbook/addressdetails.ui create mode 100644 tools/designer/examples/addressbook/addressdetails.ui.h create mode 100644 tools/designer/examples/addressbook/images/editcut.png create mode 100644 tools/designer/examples/addressbook/images/filenew.png create mode 100644 tools/designer/examples/addressbook/images/fileopen.png create mode 100644 tools/designer/examples/addressbook/images/filesave.png create mode 100644 tools/designer/examples/addressbook/images/searchfind.png create mode 100644 tools/designer/examples/addressbook/main.cpp create mode 100644 tools/designer/examples/addressbook/search.ui create mode 100644 tools/designer/examples/addressbook/search.ui.h create mode 100644 tools/designer/examples/book/book.sql create mode 100644 tools/designer/examples/book/book1/book.ui create mode 100644 tools/designer/examples/book/book1/book.ui.h create mode 100644 tools/designer/examples/book/book1/book1.pro create mode 100644 tools/designer/examples/book/book1/main.cpp create mode 100644 tools/designer/examples/book/book2/book.ui create mode 100644 tools/designer/examples/book/book2/book.ui.h create mode 100644 tools/designer/examples/book/book2/book2.pro create mode 100644 tools/designer/examples/book/book2/main.cpp create mode 100644 tools/designer/examples/book/book3/book.ui create mode 100644 tools/designer/examples/book/book3/book.ui.h create mode 100644 tools/designer/examples/book/book3/book3.pro create mode 100644 tools/designer/examples/book/book3/main.cpp create mode 100644 tools/designer/examples/book/book4/book.ui create mode 100644 tools/designer/examples/book/book4/book.ui.h create mode 100644 tools/designer/examples/book/book4/book4.pro create mode 100644 tools/designer/examples/book/book4/main.cpp create mode 100644 tools/designer/examples/book/book5/book.ui create mode 100644 tools/designer/examples/book/book5/book.ui.h create mode 100644 tools/designer/examples/book/book5/book5.pro create mode 100644 tools/designer/examples/book/book5/editbook.ui create mode 100644 tools/designer/examples/book/book5/editbook.ui.h create mode 100644 tools/designer/examples/book/book5/main.cpp create mode 100644 tools/designer/examples/book/book6/book.ui create mode 100644 tools/designer/examples/book/book6/book.ui.h create mode 100644 tools/designer/examples/book/book6/book6.pro create mode 100644 tools/designer/examples/book/book6/editbook.ui create mode 100644 tools/designer/examples/book/book6/editbook.ui.h create mode 100644 tools/designer/examples/book/book6/main.cpp create mode 100644 tools/designer/examples/book/book7/book.ui create mode 100644 tools/designer/examples/book/book7/book.ui.h create mode 100644 tools/designer/examples/book/book7/book7.pro create mode 100644 tools/designer/examples/book/book7/editbook.ui create mode 100644 tools/designer/examples/book/book7/editbook.ui.h create mode 100644 tools/designer/examples/book/book7/main.cpp create mode 100644 tools/designer/examples/book/book8/book.ui create mode 100644 tools/designer/examples/book/book8/book.ui.h create mode 100644 tools/designer/examples/book/book8/book8.pro create mode 100644 tools/designer/examples/book/book8/editbook.ui create mode 100644 tools/designer/examples/book/book8/editbook.ui.h create mode 100644 tools/designer/examples/book/book8/main.cpp create mode 100644 tools/designer/examples/book/connection.cpp create mode 100644 tools/designer/examples/book/connection.h create mode 100644 tools/designer/examples/colortool/colornameform.ui create mode 100644 tools/designer/examples/colortool/colornameform.ui.h create mode 100644 tools/designer/examples/colortool/colortool.pro create mode 100644 tools/designer/examples/colortool/findform.ui create mode 100644 tools/designer/examples/colortool/findform.ui.h create mode 100644 tools/designer/examples/colortool/images/editcopy.png create mode 100644 tools/designer/examples/colortool/images/editcut.png create mode 100644 tools/designer/examples/colortool/images/editraise.png create mode 100644 tools/designer/examples/colortool/images/filenew.png create mode 100644 tools/designer/examples/colortool/images/fileopen.png create mode 100644 tools/designer/examples/colortool/images/filesave.png create mode 100644 tools/designer/examples/colortool/images/iconview.png create mode 100644 tools/designer/examples/colortool/images/richtextedit.png create mode 100644 tools/designer/examples/colortool/images/searchfind.png create mode 100644 tools/designer/examples/colortool/images/table.png create mode 100644 tools/designer/examples/colortool/images/tabwidget.png create mode 100644 tools/designer/examples/colortool/images/widgetstack.png create mode 100644 tools/designer/examples/colortool/main.cpp create mode 100644 tools/designer/examples/colortool/mainform.ui create mode 100644 tools/designer/examples/colortool/mainform.ui.h create mode 100644 tools/designer/examples/colortool/optionsform.ui create mode 100644 tools/designer/examples/colortool/optionsform.ui.h create mode 100644 tools/designer/examples/credit/credit.pro create mode 100644 tools/designer/examples/credit/creditform.cpp create mode 100644 tools/designer/examples/credit/creditform.h create mode 100644 tools/designer/examples/credit/creditformbase.cpp create mode 100644 tools/designer/examples/credit/creditformbase.h create mode 100644 tools/designer/examples/credit/creditformbase.ui create mode 100644 tools/designer/examples/credit/creditformbase.ui.h create mode 100644 tools/designer/examples/credit/main.cpp create mode 100644 tools/designer/examples/filechooser/plugin/plugin.cpp create mode 100644 tools/designer/examples/filechooser/plugin/plugin.h create mode 100644 tools/designer/examples/filechooser/plugin/plugin.pro create mode 100644 tools/designer/examples/filechooser/widget/filechooser.cpp create mode 100644 tools/designer/examples/filechooser/widget/filechooser.h create mode 100644 tools/designer/examples/filechooser/widget/filechooser.pro create mode 100644 tools/designer/examples/filechooser/widget/main.cpp create mode 100644 tools/designer/examples/metric/main.cpp create mode 100644 tools/designer/examples/metric/metric.pro create mode 100644 tools/designer/examples/metric/metric.ui create mode 100644 tools/designer/examples/metric/metric.ui.h create mode 100644 tools/designer/examples/multiclip/main.cpp create mode 100644 tools/designer/examples/multiclip/multiclip.pro create mode 100644 tools/designer/examples/multiclip/multiclip.ui create mode 100644 tools/designer/examples/multiclip/multiclip.ui.h create mode 100644 tools/designer/examples/opengl/glwidget.cpp create mode 100644 tools/designer/examples/opengl/glwidget.h create mode 100644 tools/designer/examples/opengl/main.cpp create mode 100644 tools/designer/examples/opengl/opengl.pro create mode 100644 tools/designer/examples/receiver1/main.cpp create mode 100644 tools/designer/examples/receiver1/mainform.ui create mode 100644 tools/designer/examples/receiver1/mainform.ui.h create mode 100644 tools/designer/examples/receiver1/receiver.pro create mode 100644 tools/designer/examples/receiver2/main.cpp create mode 100644 tools/designer/examples/receiver2/mainform.ui create mode 100644 tools/designer/examples/receiver2/mainform.ui.h create mode 100644 tools/designer/examples/receiver2/receiver.cpp create mode 100644 tools/designer/examples/receiver2/receiver.h create mode 100644 tools/designer/examples/receiver2/receiver.pro create mode 100644 tools/designer/examples/richedit/images/editcopy.png create mode 100644 tools/designer/examples/richedit/images/editcut.png create mode 100644 tools/designer/examples/richedit/images/editpaste.png create mode 100644 tools/designer/examples/richedit/images/filenew.png create mode 100644 tools/designer/examples/richedit/images/fileopen.png create mode 100644 tools/designer/examples/richedit/images/filesave.png create mode 100644 tools/designer/examples/richedit/images/redo.png create mode 100644 tools/designer/examples/richedit/images/textbold.png create mode 100644 tools/designer/examples/richedit/images/textcenter.png create mode 100644 tools/designer/examples/richedit/images/textitalic.png create mode 100644 tools/designer/examples/richedit/images/textleft.png create mode 100644 tools/designer/examples/richedit/images/textright.png create mode 100644 tools/designer/examples/richedit/images/textunder.png create mode 100644 tools/designer/examples/richedit/images/undo.png create mode 100644 tools/designer/examples/richedit/main.cpp create mode 100644 tools/designer/examples/richedit/richedit.pro create mode 100644 tools/designer/examples/richedit/richedit.ui create mode 100644 tools/designer/examples/richedit/richedit.ui.h create mode 100644 tools/designer/examples/sizeaware/main.cpp create mode 100644 tools/designer/examples/sizeaware/sizeaware.cpp create mode 100644 tools/designer/examples/sizeaware/sizeaware.h create mode 100644 tools/designer/examples/sizeaware/sizeaware.pro create mode 100644 tools/designer/examples/vcr/main.cpp create mode 100644 tools/designer/examples/vcr/play.xpm create mode 100644 tools/designer/examples/vcr/vcr.cpp create mode 100644 tools/designer/examples/vcr/vcr.h create mode 100644 tools/designer/examples/vcr/vcr.pro create mode 100644 tools/designer/integration/designer.el create mode 100644 tools/designer/interfaces/actioninterface.h create mode 100644 tools/designer/interfaces/classbrowserinterface.h create mode 100644 tools/designer/interfaces/designerinterface.h create mode 100644 tools/designer/interfaces/editorinterface.h create mode 100644 tools/designer/interfaces/filterinterface.h create mode 100644 tools/designer/interfaces/interpreterinterface.h create mode 100644 tools/designer/interfaces/languageinterface.h create mode 100644 tools/designer/interfaces/preferenceinterface.h create mode 100644 tools/designer/interfaces/projectsettingsiface.h create mode 100644 tools/designer/interfaces/sourcetemplateiface.h create mode 100644 tools/designer/interfaces/templatewizardiface.h create mode 100644 tools/designer/interfaces/widgetinterface.h create mode 100644 tools/designer/plugins/cppeditor/common.cpp create mode 100644 tools/designer/plugins/cppeditor/cppbrowser.cpp create mode 100644 tools/designer/plugins/cppeditor/cppbrowser.h create mode 100644 tools/designer/plugins/cppeditor/cppcompletion.cpp create mode 100644 tools/designer/plugins/cppeditor/cppcompletion.h create mode 100644 tools/designer/plugins/cppeditor/cppeditor.cpp create mode 100644 tools/designer/plugins/cppeditor/cppeditor.h create mode 100644 tools/designer/plugins/cppeditor/cppeditor.pro create mode 100644 tools/designer/plugins/cppeditor/editorinterfaceimpl.cpp create mode 100644 tools/designer/plugins/cppeditor/editorinterfaceimpl.h create mode 100644 tools/designer/plugins/cppeditor/languageinterfaceimpl.cpp create mode 100644 tools/designer/plugins/cppeditor/languageinterfaceimpl.h create mode 100644 tools/designer/plugins/cppeditor/mainfilesettings.ui create mode 100644 tools/designer/plugins/cppeditor/mainfilesettings.ui.h create mode 100644 tools/designer/plugins/cppeditor/preferenceinterfaceimpl.cpp create mode 100644 tools/designer/plugins/cppeditor/preferenceinterfaceimpl.h create mode 100644 tools/designer/plugins/cppeditor/projectsettings.ui create mode 100644 tools/designer/plugins/cppeditor/projectsettings.ui.h create mode 100644 tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.cpp create mode 100644 tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.h create mode 100644 tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.cpp create mode 100644 tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.h create mode 100644 tools/designer/plugins/cppeditor/syntaxhighliter_cpp.cpp create mode 100644 tools/designer/plugins/cppeditor/syntaxhighliter_cpp.h create mode 100644 tools/designer/plugins/cppeditor/yyreg.cpp create mode 100644 tools/designer/plugins/cppeditor/yyreg.h create mode 100644 tools/designer/plugins/dlg/dlg.pro create mode 100644 tools/designer/plugins/dlg/dlg2ui.cpp create mode 100644 tools/designer/plugins/dlg/dlg2ui.h create mode 100644 tools/designer/plugins/dlg/main.cpp create mode 100644 tools/designer/plugins/glade/glade.pro create mode 100644 tools/designer/plugins/glade/glade2ui.cpp create mode 100644 tools/designer/plugins/glade/glade2ui.h create mode 100644 tools/designer/plugins/glade/main.cpp create mode 100644 tools/designer/plugins/kdevdlg/kdevdlg.pro create mode 100644 tools/designer/plugins/kdevdlg/kdevdlg2ui.cpp create mode 100644 tools/designer/plugins/kdevdlg/kdevdlg2ui.h create mode 100644 tools/designer/plugins/kdevdlg/main.cpp create mode 100644 tools/designer/plugins/plugins.pro create mode 100644 tools/designer/plugins/rc/main.cpp create mode 100644 tools/designer/plugins/rc/rc.pro create mode 100644 tools/designer/plugins/rc/rc2ui.cpp create mode 100644 tools/designer/plugins/rc/rc2ui.h create mode 100644 tools/designer/plugins/wizards/images/qtwizards_menu_1.png create mode 100644 tools/designer/plugins/wizards/images/qtwizards_menu_2.png create mode 100644 tools/designer/plugins/wizards/images/qtwizards_menu_3.png create mode 100644 tools/designer/plugins/wizards/images/qtwizards_table_1.png create mode 100644 tools/designer/plugins/wizards/images/qtwizards_table_2.png create mode 100644 tools/designer/plugins/wizards/images/qtwizards_table_3.png create mode 100644 tools/designer/plugins/wizards/images/qtwizards_table_4.png create mode 100644 tools/designer/plugins/wizards/images/re-sort.png create mode 100644 tools/designer/plugins/wizards/images/small/editcopy.png create mode 100644 tools/designer/plugins/wizards/images/small/editcut.png create mode 100644 tools/designer/plugins/wizards/images/small/editpaste.png create mode 100644 tools/designer/plugins/wizards/images/small/filenew.png create mode 100644 tools/designer/plugins/wizards/images/small/fileopen.png create mode 100644 tools/designer/plugins/wizards/images/small/filesave.png create mode 100644 tools/designer/plugins/wizards/images/small/print.png create mode 100644 tools/designer/plugins/wizards/images/small/redo.png create mode 100644 tools/designer/plugins/wizards/images/small/searchfind.png create mode 100644 tools/designer/plugins/wizards/images/small/undo.png create mode 100644 tools/designer/plugins/wizards/main.cpp create mode 100644 tools/designer/plugins/wizards/mainwindowwizard.ui create mode 100644 tools/designer/plugins/wizards/mainwindowwizard.ui.h create mode 100644 tools/designer/plugins/wizards/sqlformwizard.ui create mode 100644 tools/designer/plugins/wizards/sqlformwizardimpl.cpp create mode 100644 tools/designer/plugins/wizards/sqlformwizardimpl.h create mode 100644 tools/designer/plugins/wizards/wizards.pro create mode 100644 tools/designer/shared/domtool.cpp create mode 100644 tools/designer/shared/domtool.h create mode 100644 tools/designer/shared/globaldefs.h create mode 100644 tools/designer/shared/parser.cpp create mode 100644 tools/designer/shared/parser.h create mode 100644 tools/designer/shared/ui2uib.cpp create mode 100644 tools/designer/shared/ui2uib.h create mode 100644 tools/designer/shared/uib.cpp create mode 100644 tools/designer/shared/uib.h create mode 100644 tools/designer/shared/widgetdatabase.cpp create mode 100644 tools/designer/shared/widgetdatabase.h create mode 100644 tools/designer/templates/Configuration_Dialog.ui create mode 100644 tools/designer/templates/Dialog_with_Buttons_(Bottom).ui create mode 100644 tools/designer/templates/Dialog_with_Buttons_(Right).ui create mode 100644 tools/designer/templates/Tab_Dialog.ui create mode 100644 tools/designer/tools/conv2ui/conv2ui.pro create mode 100644 tools/designer/tools/conv2ui/main.cpp create mode 100644 tools/designer/tools/createcw/README create mode 100644 tools/designer/tools/createcw/createcw.pro create mode 100644 tools/designer/tools/createcw/main.cpp create mode 100644 tools/designer/uic/embed.cpp create mode 100644 tools/designer/uic/form.cpp create mode 100644 tools/designer/uic/main.cpp create mode 100644 tools/designer/uic/object.cpp create mode 100644 tools/designer/uic/subclassing.cpp create mode 100644 tools/designer/uic/uic.cpp create mode 100644 tools/designer/uic/uic.h create mode 100644 tools/designer/uic/uic.pro create mode 100644 tools/designer/uilib/qwidgetfactory.cpp create mode 100644 tools/designer/uilib/qwidgetfactory.h create mode 100644 tools/designer/uilib/test/main.cpp create mode 100644 tools/designer/uilib/test/test.pro create mode 100644 tools/designer/uilib/uilib.pro create mode 100644 tools/linguist/LICENSE.GPL create mode 100644 tools/linguist/book/images/doneandnext.png create mode 100644 tools/linguist/book/images/editcopy.png create mode 100644 tools/linguist/book/images/editcut.png create mode 100644 tools/linguist/book/images/editfind.png create mode 100644 tools/linguist/book/images/editpaste.png create mode 100644 tools/linguist/book/images/editredo.png create mode 100644 tools/linguist/book/images/editundo.png create mode 100644 tools/linguist/book/images/fileopen.png create mode 100644 tools/linguist/book/images/fileprint.png create mode 100644 tools/linguist/book/images/filesave.png create mode 100644 tools/linguist/book/images/finddialog.png create mode 100644 tools/linguist/book/images/linguist.png create mode 100644 tools/linguist/book/images/menubar.png create mode 100644 tools/linguist/book/images/next.png create mode 100644 tools/linguist/book/images/nextunfinished.png create mode 100644 tools/linguist/book/images/phrasebookdialog.png create mode 100644 tools/linguist/book/images/phrasebookopen.png create mode 100644 tools/linguist/book/images/prev.png create mode 100644 tools/linguist/book/images/prevunfinished.png create mode 100644 tools/linguist/book/images/toolbar.png create mode 100644 tools/linguist/book/images/tt1_en.png create mode 100644 tools/linguist/book/images/tt1_la.png create mode 100644 tools/linguist/book/images/tt2_en.png create mode 100644 tools/linguist/book/images/tt2_fr.png create mode 100644 tools/linguist/book/images/tt2_nl.png create mode 100644 tools/linguist/book/images/tt3_10_en.png create mode 100644 tools/linguist/book/images/tt3_10_pt_bad.png create mode 100644 tools/linguist/book/images/tt3_10_pt_good.png create mode 100644 tools/linguist/book/images/tt3_11_about_pt.png create mode 100644 tools/linguist/book/images/tt3_11_en.png create mode 100644 tools/linguist/book/images/tt3_11_pt.png create mode 100644 tools/linguist/book/images/validateaccelerators.png create mode 100644 tools/linguist/book/images/validatephrases.png create mode 100644 tools/linguist/book/images/validatepunctuation.png create mode 100644 tools/linguist/book/linguist-manager.leaf create mode 100644 tools/linguist/book/linguist-manual.book create mode 100644 tools/linguist/book/linguist-programmer.leaf create mode 100644 tools/linguist/book/linguist-translator.leaf create mode 100644 tools/linguist/linguist.pro create mode 100644 tools/linguist/linguist/about.ui create mode 100644 tools/linguist/linguist/finddialog.cpp create mode 100644 tools/linguist/linguist/finddialog.h create mode 100644 tools/linguist/linguist/images/accelerator.png create mode 100644 tools/linguist/linguist/images/appicon.png create mode 100644 tools/linguist/linguist/images/book.png create mode 100644 tools/linguist/linguist/images/d_accelerator.png create mode 100644 tools/linguist/linguist/images/d_book.png create mode 100644 tools/linguist/linguist/images/d_doneandnext.png create mode 100644 tools/linguist/linguist/images/d_editcopy.png create mode 100644 tools/linguist/linguist/images/d_editcut.png create mode 100644 tools/linguist/linguist/images/d_editpaste.png create mode 100644 tools/linguist/linguist/images/d_fileopen.png create mode 100644 tools/linguist/linguist/images/d_filesave.png create mode 100644 tools/linguist/linguist/images/d_next.png create mode 100644 tools/linguist/linguist/images/d_nextunfinished.png create mode 100644 tools/linguist/linguist/images/d_phrase.png create mode 100644 tools/linguist/linguist/images/d_prev.png create mode 100644 tools/linguist/linguist/images/d_prevunfinished.png create mode 100644 tools/linguist/linguist/images/d_print.png create mode 100644 tools/linguist/linguist/images/d_punctuation.png create mode 100644 tools/linguist/linguist/images/d_redo.png create mode 100644 tools/linguist/linguist/images/d_s_check_danger.png create mode 100644 tools/linguist/linguist/images/d_s_check_obs.png create mode 100644 tools/linguist/linguist/images/d_s_check_off.png create mode 100644 tools/linguist/linguist/images/d_s_check_on.png create mode 100644 tools/linguist/linguist/images/d_searchfind.png create mode 100644 tools/linguist/linguist/images/d_undo.png create mode 100644 tools/linguist/linguist/images/doneandnext.png create mode 100644 tools/linguist/linguist/images/editcopy.png create mode 100644 tools/linguist/linguist/images/editcut.png create mode 100644 tools/linguist/linguist/images/editpaste.png create mode 100644 tools/linguist/linguist/images/fileopen.png create mode 100644 tools/linguist/linguist/images/filesave.png create mode 100644 tools/linguist/linguist/images/next.png create mode 100644 tools/linguist/linguist/images/nextunfinished.png create mode 100644 tools/linguist/linguist/images/pagecurl.png create mode 100644 tools/linguist/linguist/images/phrase.png create mode 100644 tools/linguist/linguist/images/prev.png create mode 100644 tools/linguist/linguist/images/prevunfinished.png create mode 100644 tools/linguist/linguist/images/print.png create mode 100644 tools/linguist/linguist/images/punctuation.png create mode 100644 tools/linguist/linguist/images/redo.png create mode 100644 tools/linguist/linguist/images/s_check_danger.png create mode 100644 tools/linguist/linguist/images/s_check_obs.png create mode 100644 tools/linguist/linguist/images/s_check_off.png create mode 100644 tools/linguist/linguist/images/s_check_on.png create mode 100644 tools/linguist/linguist/images/searchfind.png create mode 100644 tools/linguist/linguist/images/splash.png create mode 100644 tools/linguist/linguist/images/undo.png create mode 100644 tools/linguist/linguist/images/whatsthis.xpm create mode 100644 tools/linguist/linguist/linguist.icns create mode 100644 tools/linguist/linguist/linguist.ico create mode 100644 tools/linguist/linguist/linguist.pro create mode 100644 tools/linguist/linguist/linguist.rc create mode 100644 tools/linguist/linguist/linguist_de.ts create mode 100644 tools/linguist/linguist/linguist_fr.ts create mode 100644 tools/linguist/linguist/listviews.cpp create mode 100644 tools/linguist/linguist/listviews.h create mode 100644 tools/linguist/linguist/main.cpp create mode 100644 tools/linguist/linguist/msgedit.cpp create mode 100644 tools/linguist/linguist/msgedit.h create mode 100644 tools/linguist/linguist/phrase.cpp create mode 100644 tools/linguist/linguist/phrase.h create mode 100644 tools/linguist/linguist/phrasebookbox.cpp create mode 100644 tools/linguist/linguist/phrasebookbox.h create mode 100644 tools/linguist/linguist/phraselv.cpp create mode 100644 tools/linguist/linguist/phraselv.h create mode 100644 tools/linguist/linguist/printout.cpp create mode 100644 tools/linguist/linguist/printout.h create mode 100644 tools/linguist/linguist/simtexth.cpp create mode 100644 tools/linguist/linguist/simtexth.h create mode 100644 tools/linguist/linguist/statistics.ui create mode 100644 tools/linguist/linguist/statistics.ui.h create mode 100644 tools/linguist/linguist/trwindow.cpp create mode 100644 tools/linguist/linguist/trwindow.h create mode 100644 tools/linguist/lrelease/lrelease.pro create mode 100644 tools/linguist/lrelease/main.cpp create mode 100644 tools/linguist/lupdate/fetchtr.cpp create mode 100644 tools/linguist/lupdate/lupdate.pro create mode 100644 tools/linguist/lupdate/main.cpp create mode 100644 tools/linguist/lupdate/merge.cpp create mode 100644 tools/linguist/lupdate/numberh.cpp create mode 100644 tools/linguist/lupdate/sametexth.cpp create mode 100644 tools/linguist/phrasebooks/danish.qph create mode 100644 tools/linguist/phrasebooks/dutch.qph create mode 100644 tools/linguist/phrasebooks/finnish.qph create mode 100644 tools/linguist/phrasebooks/french.qph create mode 100644 tools/linguist/phrasebooks/german.qph create mode 100644 tools/linguist/phrasebooks/italian.qph create mode 100644 tools/linguist/phrasebooks/norwegian.qph create mode 100644 tools/linguist/phrasebooks/russian.qph create mode 100644 tools/linguist/phrasebooks/spanish.qph create mode 100644 tools/linguist/phrasebooks/swedish.qph create mode 100644 tools/linguist/qdoc.conf create mode 100644 tools/linguist/qm2ts/main.cpp create mode 100644 tools/linguist/qm2ts/qm2ts.1 create mode 100644 tools/linguist/qm2ts/qm2ts.pro create mode 100644 tools/linguist/shared/metatranslator.cpp create mode 100644 tools/linguist/shared/metatranslator.h create mode 100644 tools/linguist/shared/proparser.cpp create mode 100644 tools/linguist/shared/proparser.h create mode 100644 tools/linguist/tutorial/tt1/main.cpp create mode 100644 tools/linguist/tutorial/tt1/tt1.pro create mode 100644 tools/linguist/tutorial/tt2/arrowpad.cpp create mode 100644 tools/linguist/tutorial/tt2/arrowpad.h create mode 100644 tools/linguist/tutorial/tt2/main.cpp create mode 100644 tools/linguist/tutorial/tt2/mainwindow.cpp create mode 100644 tools/linguist/tutorial/tt2/mainwindow.h create mode 100644 tools/linguist/tutorial/tt2/tt2.pro create mode 100644 tools/linguist/tutorial/tt3/main.cpp create mode 100644 tools/linguist/tutorial/tt3/mainwindow.cpp create mode 100644 tools/linguist/tutorial/tt3/mainwindow.h create mode 100644 tools/linguist/tutorial/tt3/printpanel.cpp create mode 100644 tools/linguist/tutorial/tt3/printpanel.h create mode 100644 tools/linguist/tutorial/tt3/tt3.pro create mode 100644 tools/linguist/tutorial/tt3/tt3_pt.ts create mode 100644 tools/makeqpf/main.cpp create mode 100755 tools/makeqpf/makeall create mode 100644 tools/makeqpf/makeqpf.pro create mode 100644 tools/mergetr/mergetr.cpp create mode 100644 tools/mergetr/mergetr.pro create mode 100644 tools/msg2qm/msg2qm.cpp create mode 100644 tools/msg2qm/msg2qm.pro create mode 100644 tools/qconfig/LICENSE.GPL create mode 100644 tools/qconfig/main.cpp create mode 100644 tools/qconfig/main.h create mode 100644 tools/qconfig/qconfig.pro create mode 100644 tools/qembed/qembed.cpp create mode 100644 tools/qembed/qembed.pro create mode 100644 tools/qtconfig/LICENSE.GPL create mode 100644 tools/qtconfig/colorbutton.cpp create mode 100644 tools/qtconfig/colorbutton.h create mode 100644 tools/qtconfig/images/appicon.png create mode 100644 tools/qtconfig/main.cpp create mode 100644 tools/qtconfig/mainwindow.cpp create mode 100644 tools/qtconfig/mainwindow.h create mode 100644 tools/qtconfig/mainwindowbase.ui create mode 100644 tools/qtconfig/paletteeditoradvanced.cpp create mode 100644 tools/qtconfig/paletteeditoradvanced.h create mode 100644 tools/qtconfig/paletteeditoradvancedbase.ui create mode 100644 tools/qtconfig/previewframe.cpp create mode 100644 tools/qtconfig/previewframe.h create mode 100644 tools/qtconfig/previewwidget.cpp create mode 100644 tools/qtconfig/previewwidget.h create mode 100644 tools/qtconfig/previewwidgetbase.ui create mode 100644 tools/qtconfig/qtconfig.pro create mode 100644 tools/qvfb/LICENSE.GPL create mode 100644 tools/qvfb/README create mode 100644 tools/qvfb/config.ui create mode 100644 tools/qvfb/gammaview.h create mode 100644 tools/qvfb/images/logo.png create mode 100644 tools/qvfb/main.cpp create mode 100644 tools/qvfb/pda.skin create mode 100644 tools/qvfb/pda_down.png create mode 100644 tools/qvfb/pda_up.png create mode 100644 tools/qvfb/qanimationwriter.cpp create mode 100644 tools/qvfb/qanimationwriter.h create mode 100644 tools/qvfb/qvfb.cpp create mode 100644 tools/qvfb/qvfb.h create mode 100644 tools/qvfb/qvfb.pro create mode 100644 tools/qvfb/qvfbratedlg.cpp create mode 100644 tools/qvfb/qvfbratedlg.h create mode 100644 tools/qvfb/qvfbview.cpp create mode 100644 tools/qvfb/qvfbview.h create mode 100644 tools/qvfb/skin.cpp create mode 100644 tools/qvfb/skin.h create mode 100644 tools/tools.pro (limited to 'tools') diff --git a/tools/assistant/LICENSE.GPL b/tools/assistant/LICENSE.GPL new file mode 100644 index 0000000..3221c03 --- /dev/null +++ b/tools/assistant/LICENSE.GPL @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/tools/assistant/assistant.icns b/tools/assistant/assistant.icns new file mode 100644 index 0000000..a6dbcdd Binary files /dev/null and b/tools/assistant/assistant.icns differ diff --git a/tools/assistant/assistant.ico b/tools/assistant/assistant.ico new file mode 100644 index 0000000..eb43249 Binary files /dev/null and b/tools/assistant/assistant.ico differ diff --git a/tools/assistant/assistant.pro b/tools/assistant/assistant.pro new file mode 100644 index 0000000..1d8ba5c --- /dev/null +++ b/tools/assistant/assistant.pro @@ -0,0 +1,72 @@ +TEMPLATE = app +LANGUAGE = C++ +TARGET = assistant + +CONFIG += qt warn_off + +PROJECTNAME = Assistant +DESTDIR = ../../bin + +SOURCES += main.cpp \ + helpwindow.cpp \ + topicchooserimpl.cpp \ + docuparser.cpp \ + helpdialogimpl.cpp \ + settingsdialogimpl.cpp \ + index.cpp \ + profile.cpp \ + config.cpp + +HEADERS += helpwindow.h \ + topicchooserimpl.h \ + docuparser.h \ + helpdialogimpl.h \ + settingsdialogimpl.h \ + index.h \ + profile.h \ + config.h + +#DEFINES += QT_PALMTOPCENTER_DOCS +DEFINES += QT_INTERNAL_NETWORK QT_INTERNAL_XML +include( ../../src/qt_professional.pri ) + +win32:RC_FILE = assistant.rc +mac:RC_FILE = assistant.icns + +target.path = $$bins.path +INSTALLS += target + +assistanttranslations.files = *.qm +assistanttranslations.path = $$translations.path +INSTALLS += assistanttranslations + +TRANSLATIONS = assistant_de.ts \ + assistant_fr.ts + +unix:!zlib:LIBS += -lz + +FORMS = mainwindow.ui \ + topicchooser.ui \ + finddialog.ui \ + helpdialog.ui \ + settingsdialog.ui \ + tabbedbrowser.ui +IMAGES = images/editcopy.png \ + images/find.png \ + images/home.png \ + images/next.png \ + images/previous.png \ + images/print.png \ + images/whatsthis.xpm \ + images/book.png \ + images/designer.png \ + images/assistant.png \ + images/linguist.png \ + images/qt.png \ + images/zoomin.png \ + images/zoomout.png \ + images/splash.png \ + images/appicon.png \ + images/addtab.png \ + images/closetab.png \ + images/d_closetab.png diff --git a/tools/assistant/assistant.rc b/tools/assistant/assistant.rc new file mode 100644 index 0000000..b4786ce --- /dev/null +++ b/tools/assistant/assistant.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "assistant.ico" diff --git a/tools/assistant/assistant_de.qm b/tools/assistant/assistant_de.qm new file mode 100644 index 0000000..c50e90f Binary files /dev/null and b/tools/assistant/assistant_de.qm differ diff --git a/tools/assistant/assistant_de.ts b/tools/assistant/assistant_de.ts new file mode 100644 index 0000000..15b0b97 --- /dev/null +++ b/tools/assistant/assistant_de.ts @@ -0,0 +1,1084 @@ + + + Assistant + + Welcome to the <b>Qt Assistant</b>. Qt Assistant will give you quicker access to help and tips while using applications like Qt Designer. + Wilkommen bei <b>Qt Assistant</b>. Qt Assistant ermöglicht einen schnellen Zugriff der Onlinehilfe während dem Arbeiten mit Programmen wie dem Qt Designer. + + + Qt Assistant + Qt Assistant + + + + AssistantServer + + Qt Assistant + Qt Assistant + + + Failed to bind to port %1 + Kann Port %1 nicht binden + + + + FindDialog + + Find Text + Textsuche + + + &Find: + &Suchen: + + + &Find + &Suchen + + + Close + Schließen + + + &Direction + Rich&tung + + + Forwar&d + &Vorwärts + + + &Backward + &Rückwärts + + + &Options + &Optionen + + + &Whole words only + &Ganze Wörter + + + &Case sensitive + Groß- und &Kleinschreibung beachten + + + Qt Assistant - Find Text + Qt Assistant - Textsuche + + + Enter the text you are looking for. + Geben Sie den Suchtext ein. + + + Search reached end of the document + Die Suche hat das Ende des Dokuments erreicht + + + Search reached start of the document + Die Suche hat den Anfang des Dokuments erreicht + + + Text not found + Text nicht gefunden + + + Fo&rward + Vo&rwärts + + + F&ind: + Su&chen: + + + C&lose + Sch&ließen + + + Alt+L + + + + Alt+F + + + + + HelpDialog + + Index + Index + + + Bookmarks + Lesezeichen + + + Con&tents + Inhal&t + + + Qt Reference Documentation + Qt Referenzdokumentation + + + Qt Designer Manual + Qt Designer Handbuch + + + Qt Linguist Manual + Qt Linguist Handbuch + + + Qt Assistant Manual + Qt Assistant Handbuch + + + Qt Assistant + Qt Assistant + + + Open Link in Current Window + Öffne Link im aktuellen Fenster + + + Open Link in New Window + Öffne Link in neuem Fenster + + + Contents + Inhalt + + + Search + Suche + + + Prepare... + Initialisiere... + + + Cannot open the index file %1 + Kann Indexdatei %1 nicht öffnen + + + Warning + Warnung + + + Documentation file %1 does not exist! +Skipping file. + Dokumentation %1 existiert nicht! +Überspringe Datei. + + + Parse Error + Syntaxfehler + + + Done + Fertig + + + Indexing files... + Indiziere Dokumentation... + + + Reading dictionary... + Lese Suchindex... + + + Full Text Search + Volltextsuche + + + Using a wildcard within phrases is not allowed. + Wildcards innerhalb von Phrasen sind nicht zugelassen. + + + The closing quotation mark is missing. + Das schließende Anführungszeichen fehlt. + + + Open Link in Current Tab + Link im Aktuellen Tab öffnen + + + Open Link in New Tab + Link in einem neuen Tab öffnen + + + Failed to load keyword index file +Assistant will not work! + Die Indexdatei konnte nicht geladen werden. +Der Assistent ist nicht einsatzbereit! + + + Documentation file %1 is not compatible! +Skipping file. + Dokumentation %1 ist nicht kompatibel! Datei wird übersprungen. + + + Failed to save fulltext search index +Assistant will not work! + Der Index für die Volltextsuche konnte nicht gespeichert werden. +Der Assistent ist nicht einsatzbereit! + + + + HelpDialogBase + + Help + Hilfe + + + <b>Help</b><p>Choose the topic you need help for from the contents list, or search the index for keywords.</p> + <b>Hilfe</b><p>Wählen Sie ein Thema vom Inhaltsverzeichnis oder suchen Sie im Index nach Schlüsselwörtern.</p> + + + Displays help topics organized by category, index or bookmarks + Zeigt die Hilfethemen unterteilt in Kategorien, Indizes oder Lesezeichen an + + + Con&tents + Inhal&t + + + Column 1 + Spalte 1 + + + <b>Help topics organized by category.</b><p>Double-click an item to see which topics are in that category. To view a topic, select it, and then click <b>Display</b>.</p> + <b>Die Hilfethemen sind nach Kategorien organisiert.</b><p>Ein Doppelklick auf einen Eintrag zeigt die Themen dieser Kategorie an. Um ein Thema anzuzeigen, wählen Sie es aus und drücken Sie <b>Anzeigen</b>.</p> + + + &Index + &Index + + + &Look For: + Suchen &nach: + + + Enter keyword + Geben Sie ein Schlüsselwort ein + + + <b>Enter a keyword.</b><p>The list will select an item that matches the entered string best.</p> + <b>Geben Sie ein Schlüsselwort ein.</b><p>Es wird dann der Eintrag aus der Liste ausgewählt, der am besten mit dem eingegebenen Begriff übereinstimmt.</p> + + + <b>List of available help topics.</b><p>Double-click on an item to open up the help page for this topic. You will have to choose the right page if more than one are found.</p> + <b>Liste aller verfügbaren Hilfethemen.</b><p>Ein Doppelklick auf einen Eintrag öffnet die dazugehörige Hilfeseite. Wenn es mehrere Seiten zu einem Eintrag gibt, wählen Sie die gewünschte aus.</p> + + + &Bookmarks + L&esezeichen + + + Displays the list of bookmarks. + Zeigt alle Lesezeichen an. + + + &New Bookmark + &Neues Lesezeichen + + + Add new bookmark + Füge neues Lesezeichen hinzu + + + Add the current displayed page as new bookmark to the list. + Füge die aktuelle Seite als Lesezeichen hinzu. + + + D&elete Bookmark + &Lösche Lesezeichen + + + Delete bookmark + Lösche Lesezeichen + + + Delete the selected bookmark from the list. + Lösche markiertes Lesezeichen. + + + Preparing... + Initialisiere... + + + <b>Help</b><p>Choose the topic you want help on from the contents list, or search the index for keywords.</p> + <b>Hilfe</b><p>Wählen Sie ein Hilfethema aus dem Inhalt oder suchen Sie im Index nach Schlüsselwörtern.</p> + + + Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search. + Zeigt Hilfethemen geordnet nach Kategorie, Index oder Lesezeichen an. Ein weiterer Abschnitt enthält die Volltextsuche. + + + <b>Help topics organized by category.</b><p>Double-click an item to see the topics in that category. To view a topic, just double-click it.</p> + <b>Hilfethemen geordnet nach Kategorie.</b><p>Doppelklicken Sie einen Eintrag, um die Themen dieser Kategorie zu sehen. Doppelklicken Sie ein Thema, um es angezeigt zu bekommen.</p> + + + <b>List of available help topics.</b><p>Double-click on an item to open its help page. If more than one is found, you must specify which page you want.</p> + <b>Liste aller verfügbaren Hilfethemen.</b><p>Doppelklicken Sie auf einen Eintrag, um die Hilfe zu öffnen. Wenn mehr als eine Seite gefunden wurde, wählen Sie die gewünschte Seite aus.</p> + + + &New + &Neu + + + Add the currently displayed page as a new bookmark. + Füge aktuelle Seite zu den Lesezeichen hinzu. + + + &Delete + &Löschen + + + Delete the selected bookmark. + Lösche markiertes Lesezeichen. + + + &Search + &Suche + + + Searching f&or: + Suche &nach: + + + Enter searchword(s). + Suchebegriff(e). + + + <b>Enter search word(s).</b><p>Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.</p> + <b>Geben Sie Suchbegriffe ein.</b><p>Geben Sie hier die gesuchten Begriffe ein. Die Begriffe können Wildcards (*) enthalten. Eine Phrase muß in Anführungszeichen stehen.</p> + + + <b>Found documents</b><p>This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.</p> + <b>Gefundene Dokumente</b><p>Diese Liste beinhaltet alle gefundenen Dokumente der letzten Suche. Die Dokumente sind nach der Häufigkeit der Treffer geordnet.</p> + + + Found &Documents: + Gefundene &Dokumente: + + + He&lp + Hi&lfe + + + Display the help page. + Zeigt die Hilfe an. + + + Display the help page for the full text search. + Zeigt die Hilfeseite für die Volltextsuche an. + + + Start searching. + Starte Suche. + + + Pressing this button starts the search. + Startet die Suche. + + + + HelpWindow + + Qt Assistant by Trolltech - %1 + Qt Assistant von Trolltech - %1 + + + Help + Hilfe + + + Can't load and display non-local file +%1 + Kann gewünschte Datei nicht laden: +%1 + + + Open Link in New WindowShift+LMB + Öffne Link in neuem Fenster + + + Currently no Web browser is selected. +Please use the settings dialog to specify one! + + Es ist kein Webbrowser ausgewählt. +Öffnen Sie bitten den "Einstellungen" Dialog um einen Webbrowser auszuwählen. + + + + Qt Assistant by Trolltech - %1%2 + Qt Assistant von Trolltech - %1%2 + + + No PDF Viewer has been specified +Please use the settings dialog to specify one! + + Es wurde kein PDF Betrachter angegeben. +Bitte diesen im Menue Einstellungen festlegen! + + + + Qt Assistant is unable to start the PDF Viewer + +%1 + +Please make sure that the executable exists and is located at +the specified location. + Der Qt Assistent konnte den PDF betrachter +%1 nicht laden. +Bitte überprüfen Sie, das dieser an der angegeben Stelle existiert. + + + Open Link in New Tab + Link in einenm neuen Tab öffnen + + + + Index + + Untitled + Unbenannt + + + + MainWindow + + Qt Assistant by Trolltech + Qt Assistant von Trolltech + + + Toolbar + Werkzeugleiste + + + Print + Drucken + + + &Print... + &Drucken... + + + Exit + Beenden + + + E&xit + &Beenden + + + Copy + Kopieren + + + &Copy + &Kopieren + + + Find in Text + Textsuche + + + &Find in Text... + Text&suche... + + + Home + Startseite + + + &Home + St&artseite + + + Previous + Vorherige + + + &Previous + &Vorherige + + + Next + Nächste + + + &Next + &Nächste + + + About + Über + + + About Qt + Über Qt + + + Qt Class Reference + Qt Klassenreferenz + + + Qt Designer Manual + Qt Designer Handbuch + + + Zoom in + Vergrößern + + + Zoom &in + Ver&größern + + + Zoom out + Verkleinern + + + Zoom &out + Ver&kleinern + + + Qt Linguist Manual + Qt Linguist Handbuch + + + &Settings + &Einstellungen + + + &Settings... + &Einstellungen... + + + New Window + Neues Fenster + + + New Window... + Neues Fenster... + + + Close + Schließen + + + Vie&ws + A&nsicht + + + Ctrl+T + Strg+T + + + + Ctrl+I + Strg+I + + + Ctrl+B + Strg+E + + + Qt Assistant + Qt Assistant + + + &Add Bookmark + &Füge Lesezeichen hinzu + + + Qt Reference Documentation + Qt Referenzdokumention + + + &File + &Datei + + + &Edit + &Bearbeiten + + + &View + &Ansicht + + + &Go + &Gehe zu + + + Boo&kmarks + &Lesezeichen + + + &Help + &Hilfe + + + Print the currently displayed page. + Drucke aktuelle Seite. + + + Ctrl+P + Strg+P + + + Quit Qt Assistant. + Beende Qt Assistant. + + + Ctrl+Q + Strg+Q + + + Copy the selected text to the clipboard. + Kopiere den markierten Text in die Zwischenablage. + + + Ctrl+C + Strg+C + + + Open the Find dialog. Qt Assistant will search the currently displayed page for the text you enter. + Öffne den Suchdialog. Qt Assistant sucht in der aktuellen Seite nach dem eingegebenen Text. + + + Ctrl+F + Strg+F + + + Go to the home page. Qt Assistant's home page is the Qt Reference Documentation. + Gehe zur Startseite. Qt Assistants Startseite ist die Qt Referenzdokumentation. + + + Ctrl+Home + Strg+Pos1 + + + Go to the previous page. + Gehe zur vorherigen Seite. + + + Alt+Left + Alt+Links + + + Go to the next page. + Gehe zur nächsten Seite. + + + Alt+Right + Alt+Rechts + + + Display further information about Qt Assistant. + Zeigt weitere Informationen zu Qt Assistant an. + + + Display further information about Qt. + Zeigt weitere Informationen zu Qt an. + + + Display the Qt Reference Documentation. + Zeigt die Qt Referenzdokumentation an. + + + Display the Qt Designer manual. + Zeigt das Qt Designer Handbuch an. + + + Zoom in on the document, i.e. increase the font size. + Vergrößert die Schrift. + + + Ctrl++ + Strg++ + + + Zoom out on the document, i.e. decrease the font size. + Verkleinert die Schrift. + + + Ctrl+- + Strg+- + + + Display the Guide to the Qt Translation Tools. + Zeigt die Anleitung zu den Qt Übersetzungswerkzeugen an. + + + Open the settings dialog. + Öffnet den "Einstellungen" Dialog. + + + Open a new window. + Öffnet ein neues Fenster. + + + Ctrl+N + Strg+N + + + &Close + &Schließen + + + Close the current window. + Schließt das aktuelle Fenster. + + + Qt Assistant Manual + Qt Assistant Handbuch + + + Display the Qt Assistant manual. + Zeigt das Qt Assistant Handbuch an. + + + F1 + F1 + + + Add the currently displayed page as a new bookmark. + Füge aktuelle Seite zu den Lesezeichen hinzu. + + + What's This? + Direkthilfe + + + "What's This?" context sensitive help. + Kontextbezogene Direkthilfe. + + + Shift+F1 + Umschalt+F1 + + + Ctrl+S + Strg+S + + + Initializing Qt Assistant... + Initialisiere Qt Assistant... + + + Go + Gehe zu + + + Find &Next + &Nächste finden + + + Find Next + Nächste finden + + + F3 + F3 + + + Find &Previous + &Vorigen finden + + + Find Previous + Vorigen finden + + + Shift+F3 + Umschalt+F3 + + + About Qt Assistant + Über den Qt Assistent + + + Settings + Einstellungen + + + Add Bookmark + Lesezeichen einfügen + + + Add Tab + Tab einfügen + + + Ctrl+Alt+N + + + + Next Tab + Nächster Tab + + + Ctrl+Alt+Right + + + + Previous Tab + Voriger Tab + + + Ctrl+Alt+Left + + + + Close Tab + Tab schließen + + + Ctrl+Alt+Q + + + + Failed to open about application contents in file: '%1' + + + + Failed to open link: '%1' + Der Link '%1' konnte nicht geöffnet werden + + + <div align="center"><h1>The page could not be found!</h1><br><h3>'%1'</h3></div> + <div align="Hauptseite nicht gefunden!</h1> + + + Error... + Fehler ... + + + + SettingsDialog + + all + Alle + + + Qt Assistant - Add Documentation + Qt Assistant - Hinzufügen von Dokumentation + + + Qt Assistant + Qt Assistant + + + Parse Error + Syntaxfehler + + + This item can not be deleted! + Dieser Eintrag kann nicht gelöscht werden! + + + This branch is not empty! +Firstly, all contents have to be removed. + Dieser Zweig ist nicht leer! +Es müssen zuerst alle Inhalte gelöscht werden. + + + Qt Assistant - Set Web Browser + Qt Assistant - Setze Webbrowser + + + Qt Assistant - Set PDF Browser + Qt Assistent - Setze PDF Betrachter + + + Qt Assistant - Set Homepage + Qt Assistent - Setzte Startseite + + + + SettingsDialogBase + + Settings + Einstellungen + + + Font: + Schriften: + + + Link color: + Linkfarbe: + + + Underline links + Unterstreiche Links + + + OK + OK + + + Cancel + Abbrechen + + + Fixed font: + Nicht-proportionale Schrift: + + + Qt Assistant - Settings + Qt Assistant - Einstellungen + + + General + Allgemein + + + Fix&ed font: + &Nicht-proportionale Schrift: + + + &Font: + &Schrift: + + + &Underline links + &Unterstreiche Links + + + Web + Web + + + &Web Browser Application: + &Webbrowser Anwendung: + + + ... + ... + + + Documentation + Dokumentation + + + &Delete + &Lösche + + + &Add... + &Hinzufügen... + + + Categories + Kategorien + + + Category &Name: + Kategorie&name: + + + &Add + &Hinzufügen + + + &OK + &OK + + + &Cancel + &Abbrechen + + + &General + &Haupt + + + &Web + &Web + + + Web &Browser Application: + Web&browser: + + + &Home page + &Startseite + + + &PDF + &PDF + + + PDF &Application + PDF &Betrachter + + + + TabbedBrowser + + TabbedBrowser + + + + Untitled + Unbenannt + + + Add page + Seite einfügen + + + Close page + Seite schließen + + + + TopicChooser + + Choose a topic for <b>%1</b> + Wählen Sie ein Thema für <b>%1</b> + + + + TopicChooserBase + + Choose Topic + Thema wählen + + + Select a topic from the list and click the <b>Display</b>-button to open the online help. + Wählen Sie ein Thema aus der Liste aus und klicken Sie <b>Anzeigen</b> um die Hilfe zu öffnen. + + + &Topics + &Themen + + + Displays a list of available help topics for the keyword. + Zeigt eine Liste der verfügbaren Hilfethemen für diesen Begriff an. + + + &Display + &Anzeigen + + + Open the topic selected in the list. + Öffne das gewählte Thema aus der Liste. + + + &Close + &Schließen + + + Close the Dialog. + Schließt den Dialog. + + + diff --git a/tools/assistant/assistant_fr.ts b/tools/assistant/assistant_fr.ts new file mode 100644 index 0000000..0dfa69f --- /dev/null +++ b/tools/assistant/assistant_fr.ts @@ -0,0 +1,426 @@ + + + Assistant + + Welcome to the <b>Qt Assistant</b>. Qt Assistant will give you quicker access to help and tips while using applications like Qt Designer. + + + + Qt Assistant + + + + + FindDialog + + Find Text + + + + &Find: + + + + &Find + + + + Close + + + + &Direction + + + + Forwar&d + + + + &Backward + + + + &Options + + + + &Whole words only + + + + &Case sensitive + + + + + HelpDialog + + Index + + + + Bookmarks + + + + Con&tents + + + + Qt Reference Documentation + + + + Qt Designer Manual + + + + Qt Linguist Manual + + + + Qt Assistant Manual + + + + Qt Assistant + + + + + HelpDialogBase + + Help + + + + <b>Help</b><p>Choose the topic you need help for from the contents list, or search the index for keywords.</p> + + + + Displays help topics organized by category, index or bookmarks + + + + Con&tents + + + + Column 1 + + + + <b>Help topics organized by category.</b><p>Double-click an item to see which topics are in that category. To view a topic, select it, and then click <b>Display</b>.</p> + + + + &Index + + + + &Look For: + + + + Enter keyword + + + + <b>Enter a keyword.</b><p>The list will select an item that matches the entered string best.</p> + + + + <b>List of available help topics.</b><p>Double-click on an item to open up the help page for this topic. You will have to choose the right page if more than one are found.</p> + + + + &Bookmarks + + + + Displays the list of bookmarks. + + + + &New Bookmark + + + + Add new bookmark + + + + Add the current displayed page as new bookmark to the list. + + + + D&elete Bookmark + + + + Delete bookmark + + + + Delete the selected bookmark from the list. + + + + Preparing... + + + + + HelpWindow + + Qt Assistant by Trolltech - %1 + + + + Help + + + + Can't load and display non-local file +%1 + + + + Open Link in New WindowShift+LMB + + + + + MainWindow + + Qt Assistant by Trolltech + + + + Toolbar + + + + Print + + + + &Print... + + + + Exit + + + + E&xit + + + + Copy + + + + &Copy + + + + Find in Text + + + + &Find in Text... + + + + Home + + + + &Home + + + + Previous + + + + &Previous + + + + Next + + + + &Next + + + + About + + + + About + + + + About Qt + + + + About Qt + + + + Qt Class Reference + + + + Qt Designer Manual + + + + Zoom in + + + + Zoom &in + + + + Zoom out + + + + Zoom &out + + + + Qt Linguist Manual + + + + &Settings + + + + &Settings... + + + + New Window + + + + New Window... + + + + Close + + + + Vie&ws + + + + Ctrl+T + + + + Ctrl+I + + + + Ctrl+B + + + + Qt Assistant + + + + &Add Bookmark + + + + Qt Reference Documentation + + + + + SettingsDialogBase + + Settings + + + + Font: + + + + Link color: + + + + Underline links + + + + OK + + + + Cancel + + + + Fixed font: + + + + + TopicChooser + + Choose a topic for <b>%1</b> + + + + + TopicChooserBase + + Choose Topic + + + + Select a topic from the list and click the <b>Display</b>-button to open the online help. + + + + &Topics + + + + Displays a list of available help topics for the keyword. + + + + &Display + + + + Open the topic selected in the list. + + + + &Close + + + + Close the Dialog. + + + + diff --git a/tools/assistant/book/assistant.book b/tools/assistant/book/assistant.book new file mode 100644 index 0000000..feb6588 --- /dev/null +++ b/tools/assistant/book/assistant.book @@ -0,0 +1,6 @@ +\title Qt Assistant Manual + +\granularity chapter + +\input assistant.leaf + diff --git a/tools/assistant/book/assistant.leaf b/tools/assistant/book/assistant.leaf new file mode 100644 index 0000000..57bab4c --- /dev/null +++ b/tools/assistant/book/assistant.leaf @@ -0,0 +1,563 @@ +\chapter Introduction + +This document introduces \QA, a tool for presenting on-line +documentation. It also introduces the Qt Reference Documentation which +is accessible using \QA, or with a web browser. The document is +divided into the following sections: + +\list +\i Introduction to the Qt Reference Documentation +\i The 1 Minute Guide to using Qt Assistant +\i Qt Assistant in More Detail +\i Full Text Searching +\i Customizing Qt Assistant +\endlist + +\chapter Introduction to the Qt Reference Documentation + +The documentation for the Qt library is written in-line in the \File +.cpp files by the developers themselves. The documentation team +revises the documentation to ensure that it is accurate and usable, +and to provide quality control. The documentation team also writes the +larger texts, such as the class descriptions that introduce a class +along with the concepts the class uses, as well as introducing the +functions and properties that the class provides. + +The documentation focuses on the API rather than the internals, since +we make great efforts to keep our API consistent and compatible with +each new version, but we may change the internals considerably to improve +performance and enhance functionality. + +The Qt Reference Documentation consists of almost 1,500 HTML pages +(over 2,500 printed pages). The overwhelming majority of pages +document Qt classes. Since developers differ in the way they +think and work we provide a variety of approaches to navigating the +documentation set: + +\list + +\i The \link classes.html All Classes\endlink page lists every class +in Qt's public API, and consists of several hundred classes. + +\i The \link mainclasses.html Main Classes\endlink page lists the +classes you're most likely to use most often, and provides a much +shorter and more managable list than the All Classes list. + +\i The \link groups.html Grouped Classes\endlink page presents a list +of groups, each of which leads to a list of related classes, for +example, the \link advanced.html Advanced Widgets\endlink list. + +\i The \link hierarchy.html Inheritance Hierarchy\endlink page +presents a list of classes in terms of the hierarchy of Qt classes. + +\i The \link functions.html All Functions\endlink page lists all the +functions provided by Qt classes, each one with links to the class(es) +in which it appears. + +\endlist + +No matter where you find yourself in the Qt documentation, you will +find extensive cross-referencing. Even snippets of example code +contain clickable links, so that for example, if you come across a +class declaration in a code example, the class name will be a +clickable link to the class's documentation. + +In addition to the class documentation some of Qt's modules have +extensive descriptions, and there are many overview documents which +describe various aspects of the Qt library; all these are linked from +the reference documentation home page. There are also two tutorials +and numerous example programs in the examples subdirectory of the Qt +distribution. + +\chapter The 1 Minute Guide to Using Qt Assistant + +Under Windows, \QA is available as a menu option on the Qt menu. On +Unix, run \c{assistant} from an xterm. + +When you start up \QA, you will be presented with a standard +main-window style application, with a menu bar and toolbar. Below +these, on the left hand side is a navigation window called the \e +Sidebar, and on the right, taking up most of the space, is the +documentation window. By default, the Qt Reference Documentation's home +page is shown in the documentation window. + +\QA works in a similar way to a web browser. If you click underlined +text (which signifies a cross-reference), the documentation window will +present the relevant page. You can bookmark pages of particular +interest and you can click the \Toolbutton Previous and \Toolbutton +Next toolbar buttons to navigate within the pages you've visited. + +Although \QA can be used just like a web browser to navigate through +the Qt documentation set, \QA offers a powerful means of navigation +that web browsers don't provide. \QA uses an intelligent algorithm to +index all the pages in the documentation sets that it presents so that +you can search for particular words and phrases. + +To perform an index search, click the \Toolbutton Index tab on the Sidebar +(or click \Key Ctrl+I). In the 'Look For' line edit enter a word, e.g. +'homedirpath'. As you type, words are found and highlighted in a list +beneath the line edit. If the highlighted text matches what you're +looking for, double click it, (or press \Key Enter) and the +documentation window will display the relevant page. You rarely have +to type in the whole word before \QA finds a match. Note that for some +words there may be more than one possible page that is relevant. + +\QA also provides full text searching for finding specific words in +the documentation. Documents with the highest occurrences of the word +that you are looking for appear first, and every occurrence of the +word within the documentation is highlighted. + +\omit +For example, enter 'setenabled' in the 'Look For' line edit. +As you type, words are found and highlighted in the list beneath the +line edit, as before. Once the highlighted text matches what you're +looking for, double click it, (or press \Key Enter). In the case of +setEnabled, it is a function name which occurs in several classes, so +a dialog pops up listing the possible choices. Click the choice you're +interested in (or move to it using the \Key Up and \Key Down arrow +keys and press \Key Enter). The relevant page will display in the +documentation window. +\endomit + +\QA can be customized by creating profiles, a collection of +documentation. Profiles can be created for your own use, or for an +application you will distribute. With profiles, you can select which +documentation you want the end user of your application to be able to +view. + +\chapter Qt Assistant in More Detail + +\img assistant.png +\caption Qt Assistant + +\section1 The Sidebar + +\img sidebar.png + +The sidebar provides four ways of navigating documentation: +\list 1 +\i The \Toolbutton Contents tab presents a tree view of the +documentation sets that are available. If you click an item, its +documentation will appear in the documentation window. If you double +click an item or click a '+' sign to the left of an item, the item's +sub-items will appear. Click a sub-item to make its page appear in the +documentation window. Click a '-' sign to the left of an item to hide +its sub-items. +\i The \Toolbutton Index tab is used to look up key words or phrases. +See \l{The 1 Minute Guide to using Qt Assistant} for how to use this +tab. +\i The \Toolbutton Bookmarks tab lists any bookmarks you've made. +Double click a bookmark to make its page appear in the documentation +window. The \Toolbutton Bookmarks tab has a \Button{New Bookmark} +button and a \Button{Delete Bookmark} button at the bottom. Click +\Button{New Bookmark} to bookmark the page that is showing in the +documentation window. Click a bookmark in the list, then click +\Button{Delete Bookmark} to delete the highlighted bookmark. +\i The \Toolbutton Search tab provides full text search of \e all +the documents. See \l{Full Text Searching} for more information about +this feature. +\endlist + +If you want the documentation window to use as much space as possible, +you can easily hide or show the Sidebar. If the Sidebar is showing, +press \Key Ctrl+T, \Key Ctrl+I, \Key Ctrl+B or \Key Ctrl+S to hide it. +If the Sidebar is hidden, press \Key Ctrl+T to show it on the Contents +tab, or press \Key Ctrl+I to show it on the Index tab (with the focus +in the 'Look For' line edit box), or press \Key Ctrl+B to show it on +the Bookmarks tab, or press \Key Ctrl+S to show it on the (full text) +Search tab. + +The Sidebar is a dock window, so you can drag it to the top, left, +right or bottom of \QA's window, or you can drag it outside \QA to +float it. + +\section1 The Documentation Window + +\img docwindow.png + +The documentation window offers a feature for viewing documentation by +enabling you to create tabs for each documentation page that you view. +Click the \Button {Add Tab} button and a new tab will appear with the +page name as the tab's caption. This makes it convenient to switch +between pages when you are working with different documentation. You +can delete a tab by clicking the \Button {Close Tab} button located +on the right side of the documentation window. + +\section1 The Toolbar + +\img toolbar1.png + +The toolbar provides fast access to the most common actions. +\list +\i \Toolbutton Previous takes you to the previous page. The menu +option is \Menu Go|Previous and the keyboard shortcut is \Key{Alt+Left +Arrow}. +\i \Toolbutton Next takes you to the next page. The menu +option is \Menu Go|Next and the keyboard shortcut is \Key{Alt+Right +Arrow}. +\i \Toolbutton Home takes you to the home page (normally the home page +of the Qt Reference Documentation). The menu +option is \Menu Go|Home and the keyboard shortcut is \Key{Ctrl+Home}. +\i \Toolbutton Copy copies any selected text to the clipboard. The menu +option is \Menu Edit|Copy and the keyboard shortcut is \Key{Ctrl+C}. +\i \Toolbutton{Find in Text} invokes the \Dialog{Find Text} dialog. The menu +option is \Menu{Edit|Find in Text} and the keyboard shortcut is \Key{Ctrl+F}. +\i \Toolbutton{Print} invokes the \Dialog{Print} dialog. The menu +option is \Menu{File|Print} and the keyboard shortcut is \Key{Ctrl+P}. +\i \Toolbutton{Zoom in} increases the font size. The menu +option is \Menu{View|Zoom in} and the keyboard shortcut is \Key{Ctrl++}. +\i \Toolbutton{Zoom out} decreases the font size. The menu +option is \Menu{View|Zoom out} and the keyboard shortcut is \Key{Ctrl+-}. +\i \Toolbutton{What's This?} provides a description of a \QA feature. +The menu option is \Menu{Help|What's This?} and the keyboard shortcut +is \Key{Shift+F1}. +\endlist + +The remaining toolbar buttons are bookmarks and will vary depending on +your configuration. + +\section1 The Menus + +\section2 The File Menu + +\list +\i \Menu{File|Print} invokes the \Dialog{Print} dialog. +\i \Menu{File|Exit} terminates \QA. +\endlist + +\section2 The Edit Menu + +\list +\i \Menu{Edit|Copy} copies any selected text to the clipboard. +\i \Menu{Edit|Find in Text} invokes the \Dialog{Find Text} dialog. +\i \Menu{Edit|Settings} invokes the \Dialog{Settings} dialog. +\endlist + +\section2 The View Menu + +\list +\i \Menu{View|Zoom in} increases the font size. +\i \Menu{View|Zoom out} decreases the font size. +\i \Menu{View|Views|Sidebar} toggles the display of the Sidebar. +\i \Menu{View|Views|Toolbar} toggles the display of the Toolbar. +\i \Menu{View|Views|Line up} lines up the toolbar buttons in the +Toolbar. +\endlist + +\section2 The Go Menu + +\list +\i \Menu{Go|Previous} displays the previous page. +\i \Menu{Go|Next} displays the next page. +\i \Menu{Go|home} goes to the home page. +\endlist +This menu also has additional items; these are pre-defined bookmarks +that vary depending on your configuration. + +\section2 The Bookmarks Menu + +\list +\i \Menu{Bookmarks|Add} adds the current page to the list of bookmarks. +\endlist +This menu may have additional items, i.e. any bookmarks that you have +already made. If you want to delete a bookmark go to the Bookmarks tab +on the Sidebar. + +\section1 The Dialogs + +\section2 The Print Dialog + +This dialog is platform-specific. It gives access to various printer +options and can be used to print the current page. + +\section2 The Find Text Dialog + +This dialog is used to find text in the current page. Enter the text +you want to find in the Find line edit. If you check the 'Whole words +only' checkbox, the search will only consider whole words, i.e. if you +search for 'spin' with this checkbox checked it will not match +'spinbox', but will match 'spin'. If you check the 'Case sensitive' +check box then, for example, 'spin' will match 'spin' but not 'Spin'. +You can search Forward or Backward from your current position in the +page by clicking one of the Direction radio buttons. Click the \Button +Find button to search (or search again), and click the \Button Close +button to finish. + +\section2 The Settings Dialog + +The Settings dialog is used to set your preferences for \QA. The +dialog has four tabs: General Settings, Web Settings, PDF Settings, +and Profiles. \QA will remember your settings between sessions, +including window sizes and positions, and which pages you have open. +Each of the tabs is discussed as follows: + +\list +\i General Settings + +\img general.png + +To change the base font used throughout \QA, select a +font type from the Font combobox. To choose a new fixed-width +font, for example, to show code snippets, choose a font type from +the 'Fixed font' combobox. To change the color of hypertext +links, click the 'Link color' color button. Uncheck the +'Underline links' checkbox if you don't want underlined links. + +\i Web Settings + +\img web.png + +Some pages contain links to external web pages. In order to display +these links, you must specify a web browser. Type the name of your +browser's executable in the Web Browser Application line edit. +Alternatively, click the \Button {(ellipsis)} button to invoke the +\Widget {Set Web Browser} dialog and navigate until you find the web +browser you want to use. Click \Button {Save} to accept the selection. + +To change \QA's default home page, enter the file name in the Home +Page line edit. Alternatively, click the \Button {(ellipsis)} button +to invoke the \Widget {Set Homepage} dialog. Navigate until you find +the home page file you want to use and then click \Button {Save} to +accept the selection. + +\i PDF Settings + +\img pdf1.png + +Some pages contain links to PDF documents. In order to display these +links, you must specify a PDF viewer. Type in the name of your PDF viewer's +executable in the line edit. Alternatively, click the \Button {(ellipsis)} +button to invoke the \Widget {Set PDF Browser} dialog and navigate +until you find the PDF viewer you want to use. Click \Button Save to +accept the selection. + +\chapter Full Text Searching + +\img search.png + +\QA provides a powerful full text search engine. To search +for certain words or text, click the 'Search' tab in the sidebar. Then +enter the text you want to look for and press \Key Enter or click +\Button Search. The search is not case sensitive, so Foo, fOo and +FOO are all treated as the same. The following are examples of common search +patterns: + +\list +\i \c deep -- lists all the documents that contain the word 'deep' + +\i \c{deep*} -- lists all the documents that contain a word beginning +with 'deep' + +\i \c{deep copy} -- lists all documents that contain both 'deep' \e +and 'copy' + +\i \c{"deep copy"} -- list all documents that contain the phrase 'deep copy' +\endlist + +The wildcard (*) character cannot be used within quotes. + +The list of documents found is ordered according to the number of +occurrences of the search text they contain, therefore those with the +highest number of occurrences appearing first. Simply click any +document in the list to display it in the document window. + +If the documentation has changed, i.e. if documents have been added or +removed, \QA will reindex. + +\chapter Customizing Qt Assistant + +\QA can be customized by adding and removing documentation from its +documentation set. In addition, \QA introduces the profiles option, +which enables its properties to change, for example, the default +startup page, and application icon. + +\section1 Modifying the Default Documentation Set + +When it is started without any options, \QA displays a default set of +documentation. When Qt is installed, the default documentation set in +\QA contains the Qt reference documentation as well as the tools that +come with Qt, such as \QD and qmake. + +Documentation can be added or removed from \QA by +adding and removing the content files. The format of the content files are +specified below. To add a content file, type the following command line +option: \c{-addContentFile docfile}. To remove a content file from the +default set, type the following command line option: +\c{-removeContentFile docfile}. For example: + +\code +1: > assistant -addContentFile file.dcf +2: > assistant +3: > assistant -removeContentFile file.dcf +\endcode + +In line one, we add the content file \c file.dcf. In line two, we start +\QA. The default set will now be extended with the doc file +\c file.dcf. In line three we remove the file \c file.dcf from the default +documentation set so that subsequent use of \QA will not contain this +file. + +\section2 Documentation Content File Format + +The Documentation Content File must contain the documentation's table +of contents and all important keywords for the index. In addition, it +may inherit an icon for the documentation which is displayed in the +\QA toolbar. You can also specify an extra directory path for +additional images used in the documentation. + +An example of a content file that uses all the available tags and +attributes is shown below: +\code + + +
+
+ foo + bla +
+
+
+
+
+
+
+
+
+
+
+ foo +
+
+ + +\endcode + +Sections may be nested as deeply as necessary. All references should +be related. + +Note that any \c keyword tags for a given section must appear \e +before any sections nested within the given section. + +The paths in the \c refs attribute are always written Unix-style +(forward slashes) and are relative to the location of the +documentation content file itself. + +Since the introduction of the new root tag \c assistantconfig in the +fileformat from Qt version 3.2.0, it is possible to specify multiple DCF tags in +one file. Note that the old document contents file format, used up to +Qt 3.2 is still valid. + +\section1 Profiles + +Profiles enable \QA to act as a specialized help tool for displaying +documentation for applications. With profiles, the documentation +writer can change properties such as \QA's title, application icons, and +'about' dialogs. In addition, profiles can be used to run specialized +documentation sets that are separate from the Qt docs. \QA can be +customized by changing the following properties: + +\list + +\i Name- This property is used to name the profile. If multiple +profiles are used for the same installation of \QA, this +parameter is crucial to keep their profile specific settings +apart. The property name is \c name + +\i Title- This property is used to specify a caption for \QA. The +property name is \c title + +\i Application Icon- This property describes an icon that will be used +as \QA application icon. The location of the icon is relative to the +location of the profile. The property name is \c applicationicon + +\i Start Page- This property specifies which page \QA should initially +display when the profile is used. Usually, this is the HTML file which +contains the documentation's table of contents. This property also +describes the default location to go to when pressing the home button +in \QA's main user interface. The start page is specified relative to +the location of the profile. The property name is \c startpage + +\i About Menu Text- This property describes the text that appears in +the \Menu Help menu, e.g. About Application. The property name is \c +aboutmenutext + +\i About URL- This property can be used to point to an HTML file that +describes the contents in the About dialog that is opened for the +\Menu Help menu, e.g. About Application. The url is specified relative +to the location of the profile. The property name is \c abouturl + +\i \QA Documentation- This property describes the location of +the \QA documentation. This is required since \QA provides +self help, such as the full text search help and the \QA +Manual option in the \Menu Help menu. The location is a directory +relative to the location of the profile. The property name is \c +assistantdocs. + +\endlist + +To define a profile, one needs to specify a \QA Document +Profile, usually abbreviated \c{.adp}. The profile is an extension of +the Documentation Content File described above. We add a \c profile +tag containing \c property tags to the format. + +An example of a document profile file is shown below: + +\c helpdemo.adp + +\code + + + + HelpExample + Help Example + logo.png + index.html + About Help + ../about.txt + ../../../doc/html + + + +
+ Install Docs + Example Profile + Hide Sidebar + Open + Close + Display +
+
+ +
+\endcode + +These files are XML files. Characters such as \c{<}, \c{>}, and \c{&} +must be written as entities (e.g., \c{<}, \c{>}, \c{&}). + +\section2 Using Profiles + +To use a profile, run \QA with the option \c {-profile filename}. +This will load the profile specified in the file and will customize +\QA accordingly. For example, to run \QA with the example +file above, \c helpdemo.adp, we would run the command as follows: + +\code +> assistant -profile helpdemo.adp +\endcode + +See the HelpDemo example in the Qt distribution for a demonstration +on how to use \QA with profiles for your own applications. + +When distributing \QA with your application, you will also need to +copy the icon files from the \c QTDIR/tools/assistant/images +directory so that \QA finds its icons. + +\omit +For small documentation sets, the sidebar may not be necessary. You +can hide the sidebar on startup with the following: +\code +assistant -hideSidebar +\endcode +\endomit + diff --git a/tools/assistant/book/images/assistant.png b/tools/assistant/book/images/assistant.png new file mode 100644 index 0000000..9401940 Binary files /dev/null and b/tools/assistant/book/images/assistant.png differ diff --git a/tools/assistant/book/images/docwindow.png b/tools/assistant/book/images/docwindow.png new file mode 100644 index 0000000..18fa098 Binary files /dev/null and b/tools/assistant/book/images/docwindow.png differ diff --git a/tools/assistant/book/images/general.png b/tools/assistant/book/images/general.png new file mode 100644 index 0000000..2fad053 Binary files /dev/null and b/tools/assistant/book/images/general.png differ diff --git a/tools/assistant/book/images/pdf1.png b/tools/assistant/book/images/pdf1.png new file mode 100644 index 0000000..104ac16 Binary files /dev/null and b/tools/assistant/book/images/pdf1.png differ diff --git a/tools/assistant/book/images/search.png b/tools/assistant/book/images/search.png new file mode 100644 index 0000000..667a4a6 Binary files /dev/null and b/tools/assistant/book/images/search.png differ diff --git a/tools/assistant/book/images/sidebar.png b/tools/assistant/book/images/sidebar.png new file mode 100644 index 0000000..7e005cd Binary files /dev/null and b/tools/assistant/book/images/sidebar.png differ diff --git a/tools/assistant/book/images/toolbar1.png b/tools/assistant/book/images/toolbar1.png new file mode 100644 index 0000000..0f3358a Binary files /dev/null and b/tools/assistant/book/images/toolbar1.png differ diff --git a/tools/assistant/book/images/web.png b/tools/assistant/book/images/web.png new file mode 100644 index 0000000..5888f79 Binary files /dev/null and b/tools/assistant/book/images/web.png differ diff --git a/tools/assistant/config.cpp b/tools/assistant/config.cpp new file mode 100644 index 0000000..83d0bdc --- /dev/null +++ b/tools/assistant/config.cpp @@ -0,0 +1,379 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "config.h" +#include "profile.h" +#include "docuparser.h" + +#include +#include +#include +#include +#include +#include + +static Config *static_configuration = 0; + +inline QString getVersionString() +{ + return QString::number( (QT_VERSION >> 16) & 0xff ) + + "." + QString::number( (QT_VERSION >> 8) & 0xff ); +} + +Config::Config() + : hideSidebar( FALSE ), profil( 0 ), maximized(FALSE) +{ + fontSiz = qApp->font().pointSize(); + if( !static_configuration ) { + static_configuration = this; + } else { + qWarning( "Multiple configurations not allowed!" ); + } +} + +Config *Config::loadConfig(const QString &profileFileName) +{ + Config *config = new Config(); + + if (profileFileName.isEmpty()) { // no profile + config->profil = Profile::createDefaultProfile(); + config->load(); + config->loadDefaultProfile(); + return config; + } + + QFile file(profileFileName); + if (!file.exists()) { + qWarning( "File does not exist: " + profileFileName ); + return 0; + } + DocuParser *parser = DocuParser::createParser( profileFileName ); + if (!parser) { + qWarning( "Failed to create parser for file: " + profileFileName ); + return 0; + } + if (parser->parserVersion() < DocuParser::Qt320) { + qWarning( "File does not contain profile information" ); + return 0; + } + DocuParser320 *profileParser = static_cast(parser); + parser->parse(&file); + config->profil = profileParser->profile(); + if (!config->profil) { + qWarning( "Config::loadConfig(), no profile in: " + profileFileName ); + return 0; + } + config->profil->setProfileType(Profile::UserProfile); + config->profil->setDocuParser(profileParser); + config->load(); + return config; +} + +Config *Config::configuration() +{ + Q_ASSERT( static_configuration ); + return static_configuration; +} + +void Config::load() +{ + const QString key = "/Qt Assistant/" + getVersionString() + "/"; + const QString profkey = key + "Profile/" + profil->props["name"] + "/"; + + QSettings settings; + settings.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + webBrows = settings.readEntry( key + "Webbrowser" ); + home = settings.readEntry( profkey + "Homepage" ); + pdfApp = settings.readEntry( key + "PDFApplication" ); + linkUnder = settings.readBoolEntry( key + "LinkUnderline", TRUE ); + linkCol = settings.readEntry( key + "LinkColor", "#0000FF" ); + src = settings.readListEntry( profkey + "Source" ); + sideBar = settings.readNumEntry( key + "SideBarPage" ); + if (qApp->type() != QApplication::Tty) { + fontFam = settings.readEntry( key + "Family", qApp->font().family() ); + + fontFix = settings.readEntry( key + "FixedFamily", "courier" ); + fontSiz = settings.readNumEntry( key + "Size", -1 ); + if ( fontSiz < 4 ) { + fontSiz = qApp->font().pointSize(); + } + + geom.setRect( settings.readNumEntry( key + "GeometryX", QApplication::desktop()->availableGeometry().x() ), + settings.readNumEntry( key + "GeometryY", QApplication::desktop()->availableGeometry().y() ), + settings.readNumEntry( key + "GeometryWidth", 800 ), + settings.readNumEntry( key + "GeometryHeight", 600 ) ); + maximized = settings.readBoolEntry( key + "GeometryMaximized", FALSE ); + } + mainWinLayout = settings.readEntry( key + "MainwindowLayout" ); + rebuildDocs = settings.readBoolEntry( key + "RebuildDocDB", TRUE ); + + profileNames = settings.entryList( key + "Profile" ); +} + +void Config::save() +{ + saveSettings(); + saveProfile( profil ); +} + +void Config::saveSettings() +{ + const QString key = "/Qt Assistant/" + getVersionString() + "/"; + const QString profkey = key + "Profile/" + profil->props["name"] + "/"; + + QSettings settings; + settings.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + settings.writeEntry( key + "Webbrowser", webBrows ); + settings.writeEntry( profkey + "Homepage", home ); + settings.writeEntry( key + "PDFApplication", pdfApp ); + settings.writeEntry( key + "LinkUnderline", linkUnder ); + settings.writeEntry( key + "LinkColor", linkCol ); + settings.writeEntry( profkey + "Source", src ); + settings.writeEntry( key + "SideBarPage", sideBarPage() ); + if (qApp->type() != QApplication::Tty) { + settings.writeEntry( key + "GeometryX", geom.x() ); + settings.writeEntry( key + "GeometryY", geom.y() ); + settings.writeEntry( key + "GeometryWidth", geom.width() ); + settings.writeEntry( key + "GeometryHeight", geom.height() ); + settings.writeEntry( key + "GeometryMaximized", maximized ); + settings.writeEntry( key + "Family", fontFam ); + settings.writeEntry( key + "Size", fontSiz < 4 ? qApp->font().pointSize() : fontSiz ); + settings.writeEntry( key + "FixedFamily", fontFix ); + } + if ( !hideSidebar ) + settings.writeEntry( key + "MainwindowLayout", mainWinLayout ); + settings.writeEntry( key + "RebuildDocDB", rebuildDocs ); +} + +#ifdef ASSISTANT_DEBUG +static void dumpmap( const QMap &m, const QString &header ) +{ + qDebug( header ); + QMap::ConstIterator it = m.begin(); + while (it != m.end()) { + qDebug( " " + it.key() + ":\t\t" + *it ); + ++it; + } +} +#endif + +void Config::loadDefaultProfile() +{ + QSettings settings; + settings.insertSearchPath( QSettings::Windows, "/Trolltech" ); + const QString key = "/Qt Assistant/" + QString(QT_VERSION_STR) + "/Profile"; + const QString profKey = key + "/default/"; + + if( settings.entryList( key + "/default" ).count() == 0 ) { + return; + } + + // Override the defaults with settings in registry. + profil->icons.clear(); + profil->indexPages.clear(); + profil->imageDirs.clear(); + profil->docs.clear(); + profil->dcfTitles.clear(); + + QStringList titles = settings.readListEntry( profKey + "Titles" ); + QStringList iconLst = settings.readListEntry( profKey + "DocIcons" ); + QStringList indexLst = settings.readListEntry( profKey + "IndexPages" ); + QStringList imgDirLst = settings.readListEntry( profKey + "ImageDirs" ); + QStringList dcfs = settings.readListEntry( profKey + "DocFiles" ); + + QStringList::ConstIterator it = titles.begin(); + QValueListConstIterator iconIt = iconLst.begin(); + QValueListConstIterator indexIt = indexLst.begin(); + QValueListConstIterator imageIt = imgDirLst.begin(); + QValueListConstIterator dcfIt = dcfs.begin(); + for( ; it != titles.end(); + ++it, ++iconIt, ++indexIt, ++imageIt, ++dcfIt ) + { + profil->addDCFIcon( *it, *iconIt ); + profil->addDCFIndexPage( *it, *indexIt ); + profil->addDCFImageDir( *it, *imageIt ); + profil->addDCFTitle( *dcfIt, *it ); + } +#if ASSISTANT_DEBUG + dumpmap( profil->icons, "Icons" ); + dumpmap( profil->indexPages, "IndexPages" ); + dumpmap( profil->imageDirs, "ImageDirs" ); + dumpmap( profil->dcfTitles, "dcfTitles" ); + qDebug( "Docfiles: \n " + profil->docs.join( "\n " ) ); +#endif +} + +void Config::saveProfile( Profile *profile ) +{ + if (profil && profil->profileType() == Profile::UserProfile) + return; + QSettings settings; + settings.insertSearchPath( QSettings::Windows, "/Trolltech" ); + QString versionString = (profile->props["name"] == "default") + ? QString(QT_VERSION_STR) + : getVersionString(); + const QString key = "/Qt Assistant/" + versionString + "/"; + const QString profKey = key + "Profile/" + profile->props["name"] + "/"; + + QStringList indexes, icons, imgDirs, dcfs; + QValueList titles = profile->dcfTitles.keys(); + QValueListConstIterator it = titles.begin(); + for ( ; it != titles.end(); ++it ) { + indexes << profile->indexPages[*it]; + icons << profile->icons[*it]; + imgDirs << profile->imageDirs[*it]; + dcfs << profile->dcfTitles[*it]; + } + + settings.writeEntry( profKey + "Titles", titles ); + settings.writeEntry( profKey + "DocFiles", dcfs ); + settings.writeEntry( profKey + "IndexPages", indexes ); + settings.writeEntry( profKey + "DocIcons", icons ); + settings.writeEntry( profKey + "ImageDirs", imgDirs ); + +#if ASSISTANT_DEBUG + qDebug( "Titles:\n - " + ( (QStringList*) &titles )->join( "\n - " ) ); + qDebug( "Docfiles:\n - " + dcfs.join( "\n - " ) ); + qDebug( "IndexPages:\n - " + indexes.join( "\n - " ) ); + qDebug( "DocIcons:\n - " + icons.join( "\n - " ) ); + qDebug( "ImageDirs:\n - " + imgDirs.join( "\n - " ) ); +#endif +} + +QStringList Config::mimePaths() +{ + static QStringList lst; + + if( lst.count() > 0 ) + return lst; + + for (QMap::ConstIterator it = profil->dcfTitles.begin(); + it != profil->dcfTitles.end(); ++it ) { + + // Mime source for .dcf file path + QFileInfo info( *it ); + QString dcfPath = info.dirPath(TRUE); + if (lst.contains(dcfPath) == 0) + lst << dcfPath; + + // Image dir for .dcf + QString imgDir = QDir::convertSeparators( dcfPath + QDir::separator() + + profil->imageDirs[it.key()] ); + if (lst.contains(imgDir) == 0) + lst << imgDir; + } + return lst; +} + +QStringList Config::profiles() const +{ + return profileNames; +} + +QString Config::title() const +{ + return profil->props[ "title" ]; +} + +QString Config::aboutApplicationMenuText() const +{ + return profil->props[ "aboutmenutext" ]; +} + +QString Config::aboutURL() const +{ + return profil->props[ "abouturl" ]; +} + +QString Config::homePage() const +{ + return home.isEmpty() ? profil->props["startpage"] : home; +} + +QStringList Config::source() const +{ + return src.size() == 0 ? QStringList(profil->props["startpage"]) : src; +} + +QStringList Config::docFiles() const +{ + return profil->docs; +} + +QPixmap Config::docIcon( const QString &title ) const +{ + // ### To allow qdoc generated dcf files to reference the doc icons from qmake_image_col + if (!QFile::exists(profil->icons[title])) + return QPixmap::fromMimeSource( QFileInfo(profil->icons[title]).fileName() ); + return QPixmap::fromMimeSource( profil->icons[title] ); +} + +QPixmap Config::applicationIcon() const +{ + return QPixmap::fromMimeSource( profil->props["applicationicon"] ); +} + +QStringList Config::docTitles() const +{ + return QStringList(profil->indexPages.keys()); +} + +QString Config::docImageDir( const QString &docfile ) const +{ + return profil->imageDirs[docfile]; +} + +QString Config::indexPage( const QString &title ) const +{ + return profil->indexPages + [title]; +} + +void Config::hideSideBar( bool b ) +{ + hideSidebar = b; +} + +bool Config::sideBarHidden() const +{ + return hideSidebar; +} + +QString Config::assistantDocPath() const +{ + return profil->props["assistantdocs"].isEmpty() + ? QString( qInstallPathDocs() ) + "/html" + : profil->props["assistantdocs"]; +} diff --git a/tools/assistant/config.h b/tools/assistant/config.h new file mode 100644 index 0000000..4a39446 --- /dev/null +++ b/tools/assistant/config.h @@ -0,0 +1,152 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CONFIG_H +#define CONFIG_H + +#include "profile.h" + +#include +#include +#include +#include + +class Profile; + +class Config +{ +public: + + Config(); + + void load(); + void save(); + Profile *profile() const { return profil; } + QString profileName() const { return profil->props["name"]; } + bool validProfileName() const; + void hideSideBar( bool b ); + bool sideBarHidden() const; + QStringList mimePaths(); + + // From profile, read only + QStringList docFiles() const; + QStringList docTitles() const; + QString indexPage( const QString &title ) const; + QString docImageDir( const QString &title ) const; + QPixmap docIcon( const QString &title ) const; + + QStringList profiles() const; + QString title() const; + QString aboutApplicationMenuText() const; + QString aboutURL() const; + QPixmap applicationIcon() const; + + // From QSettings, read / write + QString webBrowser() const { return webBrows; } + void setWebBrowser( const QString &cmd ) { webBrows = cmd; } + + QString homePage() const; + void setHomePage( const QString &hom ) { home = hom; } + + QString pdfReader() const { return pdfApp; } + void setPdfReader( const QString &cmd ) { pdfApp = cmd; } + + int fontSize() const { return fontSiz; } + void setFontSize( int size ) { fontSiz = size; } + + QString fontFamily() const { return fontFam; } + void setFontFamily( const QString &fam ) { fontFam = fam; } + + QString fontFixedFamily() const { return fontFix; } + void setFontFixedFamily( const QString &fn ) { fontFix = fn; } + + QString linkColor() const { return linkCol; } + void setLinkColor( const QString &col ) { linkCol = col; } + + QStringList source() const; + void setSource( const QStringList &s ) { src = s; } + + int sideBarPage() const { return sideBar; } + void setSideBarPage( int sbp ) { sideBar = sbp; } + + QRect geometry() const { return geom; } + void setGeometry( const QRect &geo ) { geom = geo; } + + bool isMaximized() const { return maximized; } + void setMaximized( bool max ) { maximized = max; } + + bool isLinkUnderline() const { return linkUnder; } + void setLinkUnderline( bool ul ) { linkUnder = ul; } + + QString mainWindowLayout() const { return mainWinLayout; } + void setMainWindowLayout( const QString &layout ) { mainWinLayout = layout; } + + QString assistantDocPath() const; + + bool docRebuild() const { return rebuildDocs; } + void setDocRebuild( bool rb ) { rebuildDocs = rb; } + + void saveProfile( Profile *profile ); + void loadDefaultProfile(); + + static Config *configuration(); + static Config *loadConfig(const QString &profileFileName); + +private: + Config( const Config &c ); + Config& operator=( const Config &c ); + + void saveSettings(); + +private: + Profile *profil; + + QStringList profileNames; + QString webBrows; + QString home; + QString pdfApp; + QString fontFam; + QString fontFix; + QString linkCol; + QStringList src; + QString mainWinLayout; + QRect geom; + int sideBar; + int fontSiz; + bool maximized; + bool linkUnder; + bool hideSidebar; + bool rebuildDocs; +}; + +#endif diff --git a/tools/assistant/docuparser.cpp b/tools/assistant/docuparser.cpp new file mode 100644 index 0000000..c8f8d70 --- /dev/null +++ b/tools/assistant/docuparser.cpp @@ -0,0 +1,397 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "docuparser.h" +#include "profile.h" + +#include +#include +#include +#include +#include +#include + +QDataStream &operator>>( QDataStream &s, ContentItem &ci ) +{ + s >> ci.title; + s >> ci.reference; + s >> ci.depth; + return s; +} + +QDataStream &operator<<( QDataStream &s, const ContentItem &ci ) +{ + s << ci.title; + s << ci.reference; + s << ci.depth; + return s; +} + +const QString DocuParser::DocumentKey = "/Qt Assistant/" + QString(QT_VERSION_STR) + "/"; + +DocuParser *DocuParser::createParser( const QString &fileName ) +{ + QFile file( fileName ); + if( !file.open( IO_ReadOnly ) ) { + return 0; + } + + QString str; + int read = 0; + int maxlen = 1024; + int majVer = 0, minVer = 0, serVer = 0; + static QRegExp re( "assistantconfig +version=\"(\\d)\\.(\\d)\\.(\\d)\"", FALSE ); + Q_ASSERT( re.isValid() ); + while( read != -1 ) { + read = file.readLine( str, maxlen ); + if( re.search( str ) >= 0 ) { + majVer = re.cap( 1 ).toInt(); + minVer = re.cap( 2 ).toInt(); + serVer = re.cap( 3 ).toInt(); + } + } + + if( majVer == 3 && minVer >= 2 ) + return new DocuParser320; + + return new DocuParser310; +} + + +bool DocuParser::parse( QFile *file ) +{ + QXmlInputSource source( file ); + QXmlSimpleReader reader; + reader.setContentHandler( this ); + reader.setErrorHandler( this ); + setFileName( QFileInfo( *file ).absFilePath() ); + return reader.parse( source ); +} + + +QString DocuParser::errorProtocol() const +{ + return errorProt; +} + + +QValueList DocuParser::getContentItems() +{ + return contentList; +} + + +QPtrList DocuParser::getIndexItems() +{ + return indexList; +} + +QString DocuParser::absolutify( const QString &name ) const +{ + QFileInfo orgPath( name ); + if( orgPath.isRelative() ) + return QFileInfo( fname ).dirPath() + QDir::separator() + name; + return name; +} + + +void DocuParser310::addTo( Profile *p ) +{ + p->addDCFTitle( fname, docTitle ); + p->addDCFIcon( docTitle, iconName ); + p->addDCFIndexPage( docTitle, conURL ); +} + + +bool DocuParser310::startDocument() +{ + state = StateInit; + errorProt = ""; + + contentRef = ""; + indexRef = ""; + depth = 0; + contentList.clear(); + indexList.clear(); + + return TRUE; +} + + +bool DocuParser310::startElement( const QString &, const QString &, + const QString &qname, + const QXmlAttributes &attr ) +{ + if (qname == "DCF" && state == StateInit) { + state = StateContent; + contentRef = absolutify( attr.value( "ref" ) ); + conURL = contentRef; + docTitle = attr.value( "title" ); + iconName = absolutify( attr.value( "icon" ) ); + contentList.append( ContentItem( docTitle, contentRef, depth ) ); + } else if (qname == "section" && (state == StateContent || state == StateSect)) { + state = StateSect; + contentRef = absolutify( attr.value( "ref" ) ); + title = attr.value( "title" ); + depth++; + contentList.append( ContentItem( title, contentRef, depth ) ); + } else if (qname == "keyword" && state == StateSect) { + state = StateKeyword; + indexRef = absolutify( attr.value( "ref" ) ); + } else + return FALSE; + return TRUE; +} + +bool DocuParser310::endElement( const QString &nameSpace, const QString &localName, + const QString &qName ) +{ + switch( state ) { + case StateInit: + break; + case StateContent: + state = StateInit; + break; + case StateSect: + state = --depth ? StateSect : StateContent; + break; + case StateKeyword: + state = StateSect; + break; + } + return TRUE; +} + + +bool DocuParser310::characters( const QString& ch ) +{ + QString str = ch.simplifyWhiteSpace(); + if ( str.isEmpty() ) + return TRUE; + + switch ( state ) { + case StateInit: + case StateContent: + case StateSect: + return FALSE; + break; + case StateKeyword: + indexList.append( new IndexItem( str, indexRef ) ); + break; + default: + return FALSE; + } + return TRUE; +} + + +bool DocuParser310::fatalError( const QXmlParseException& exception ) +{ + errorProt += QString( "fatal parsing error: %1 in line %2, column %3\n" ) + .arg( exception.message() ) + .arg( exception.lineNumber() ) + .arg( exception.columnNumber() ); + + return QXmlDefaultHandler::fatalError( exception ); +} + + +DocuParser320::DocuParser320() + : prof( new Profile ) +{ +} + + +void DocuParser320::addTo( Profile *p ) +{ + QMap::ConstIterator it; + + for (it = prof->dcfTitles.begin(); it != prof->dcfTitles.end(); ++it) + p->dcfTitles[it.key()] = *it; + + for (it = prof->icons.begin(); it != prof->icons.end(); ++it) + p->icons[it.key()] = *it; + + for (it = prof->indexPages.begin(); it != prof->indexPages.end(); ++it) + p->indexPages[it.key()] = *it; +} + + +bool DocuParser320::startDocument() +{ + state = StateInit; + errorProt = ""; + + contentRef = ""; + indexRef = ""; + depth = 0; + contentList.clear(); + indexList.clear(); + + prof->addDCF( fname ); + + return TRUE; +} + +bool DocuParser320::startElement( const QString &, const QString &, + const QString &qname, + const QXmlAttributes &attr ) +{ + QString lower = qname.lower(); + + switch( state ) { + + case StateInit: + if( lower == "assistantconfig" ) + state = StateDocRoot; + break; + + case StateDocRoot: + if( lower == "dcf" ) { + state = StateContent; + contentRef = absolutify( attr.value( "ref" ) ); + conURL = contentRef; + docTitle = attr.value( "title" ); + iconName = absolutify( attr.value( "icon" ) ); + contentList.append( ContentItem( docTitle, contentRef, depth ) ); + } else if( lower == "profile" ) { + state = StateProfile; + } + break; + + case StateSect: + if ( lower == "keyword" && state == StateSect ) { + state = StateKeyword; + indexRef = absolutify( attr.value( "ref" ) ); + break; + } // else if (lower == "section") + case StateContent: + if( lower == "section" ) { + state = StateSect; + contentRef = absolutify( attr.value( "ref" ) ); + title = attr.value( "title" ); + depth++; + contentList.append( ContentItem( title, contentRef, depth ) ); + } + break; + + case StateProfile: + if( lower == "property" ) { + state = StateProperty; + propertyName = attr.value( "name" ); + } + break; + + case StateProperty: + break; + } + + return TRUE; +} + +bool DocuParser320::endElement( const QString &nameSpace, + const QString &localName, + const QString &qName ) +{ + switch( state ) { + case StateInit: + break; + case StateDocRoot: + state = StateInit; + break; + case StateProfile: + state = StateDocRoot; + break; + case StateProperty: + state = StateProfile; + if( propertyName.isEmpty() || propertyValue.isEmpty() ) + return FALSE; + { + static const QStringList lst = QStringList() << "startpage" << "abouturl" + << "applicationicon" << "assistantdocs"; + if (lst.contains(propertyName)) + propertyValue = absolutify( propertyValue ); + } + prof->addProperty( propertyName, propertyValue ); + break; + case StateContent: + if( !iconName.isEmpty() ) prof->addDCFIcon( docTitle, iconName ); + if( contentRef.isEmpty() ) + return FALSE; + prof->addDCFIndexPage( docTitle, conURL ); + prof->addDCFTitle( fname, docTitle ); + state = StateDocRoot; + break; + case StateSect: + state = --depth ? StateSect : StateContent; + break; + case StateKeyword: + state = StateSect; + break; + } + return TRUE; +} + +bool DocuParser320::characters( const QString& ch ) +{ + QString str = ch.simplifyWhiteSpace(); + if ( str.isEmpty() ) + return TRUE; + + switch ( state ) { + case StateInit: + case StateContent: + case StateSect: + return FALSE; + break; + case StateKeyword: + indexList.append( new IndexItem( str, indexRef ) ); + break; + case StateProperty: + propertyValue = ch; + break; + default: + return FALSE; + } + return TRUE; +} + +bool DocuParser320::fatalError( const QXmlParseException& exception ) +{ + errorProt += QString( "fatal parsing error: %1 in line %2, column %3\n" ) + .arg( exception.message() ) + .arg( exception.lineNumber() ) + .arg( exception.columnNumber() ); + + return QXmlDefaultHandler::fatalError( exception ); +} diff --git a/tools/assistant/docuparser.h b/tools/assistant/docuparser.h new file mode 100644 index 0000000..747295c --- /dev/null +++ b/tools/assistant/docuparser.h @@ -0,0 +1,151 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DOCUPARSER_H +#define DOCUPARSER_H + +#include +#include +#include + +class Profile; + +struct ContentItem { + ContentItem() + : title( QString::null ), reference( QString::null ), depth( 0 ) {} + ContentItem( const QString &t, const QString &r, int d ) + : title( t ), reference( r ), depth( d ) {} + QString title; + QString reference; + int depth; + Q_DUMMY_COMPARISON_OPERATOR(ContentItem) +}; + +QDataStream &operator>>( QDataStream &s, ContentItem &ci ); +QDataStream &operator<<( QDataStream &s, const ContentItem &ci ); + +struct IndexItem { + IndexItem( const QString &k, const QString &r ) + : keyword( k ), reference( r ) {} + QString keyword; + QString reference; +}; + + + +class DocuParser : public QXmlDefaultHandler +{ +public: + enum ParserVersion { Qt310, Qt320 }; + // Since We don't want problems with documentation + // from version to version, this string stores the correct + // version string to save documents. + static const QString DocumentKey; + + static DocuParser *createParser( const QString &fileName ); + + virtual bool parse( QFile *file ); + + QValueList getContentItems(); + QPtrList getIndexItems(); + + QString errorProtocol() const; + QString contentsURL() const { return conURL; } + + virtual ParserVersion parserVersion() const = 0; + virtual void addTo( Profile *p ) = 0; + + QString fileName() const { return fname; } + void setFileName( const QString &file ) { fname = file; } + +protected: + QString absolutify( const QString &input ) const; + + QString contentRef, indexRef, errorProt, conURL; + QString docTitle, title, iconName; + QValueList contentList; + QPtrList indexList; + QString fname; +}; + + +class DocuParser310 : public DocuParser +{ +public: + enum States{ StateInit, StateContent, StateSect, StateKeyword }; + + bool startDocument(); + bool startElement( const QString&, const QString&, const QString& , + const QXmlAttributes& ); + bool endElement( const QString&, const QString&, const QString& ); + bool characters( const QString & ); + bool fatalError( const QXmlParseException& exception ); + + virtual ParserVersion parserVersion() const { return Qt310; } + virtual void addTo( Profile *p ); + +private: + States state; + int depth; +}; + + +class DocuParser320 : public DocuParser +{ +public: + enum States { StateInit, StateDocRoot, StateProfile, StateProperty, + StateContent, StateSect, StateKeyword }; + + DocuParser320(); + + bool startDocument(); + bool startElement( const QString&, const QString&, const QString& , + const QXmlAttributes& ); + bool endElement( const QString&, const QString&, const QString& ); + bool characters( const QString & ); + bool fatalError( const QXmlParseException& exception ); + + virtual ParserVersion parserVersion() const { return Qt320; } + virtual void addTo( Profile *p ); + Profile *profile() const { return prof; } + +private: + + States state; + int depth; + int docfileCounter; + QString propertyValue; + QString propertyName; + Profile *prof; +}; +#endif //DOCUPARSER_H diff --git a/tools/assistant/finddialog.ui b/tools/assistant/finddialog.ui new file mode 100644 index 0000000..35f6540 --- /dev/null +++ b/tools/assistant/finddialog.ui @@ -0,0 +1,286 @@ + +FindDialog +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + FindDialog + + + + 0 + 0 + 362 + 156 + + + + Qt Assistant - Find Text + + + + unnamed + + + 0 + + + + Layout5 + + + + unnamed + + + 11 + + + + ButtonGroup2 + + + &Direction + + + + unnamed + + + 11 + + + 6 + + + + radioForward + + + Fo&rward + + + true + + + + + radioBackward + + + &Backward + + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + F&ind: + + + comboFind + + + + + comboFind + + + + 7 + 0 + 0 + 0 + + + + true + + + false + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 31 + 0 + + + + + + PushButton2 + + + C&lose + + + Alt+L + + + + + ButtonGroup1 + + + &Options + + + + unnamed + + + 11 + + + 6 + + + + checkWords + + + &Whole words only + + + + + checkCase + + + &Case sensitive + + + + + + + PushButton1 + + + &Find + + + Alt+F + + + true + + + + + + + + + PushButton1 + clicked() + FindDialog + doFind() + + + PushButton2 + clicked() + FindDialog + reject() + + + + comboFind + checkWords + checkCase + radioForward + radioBackward + PushButton1 + PushButton2 + + + qstatusbar.h + qtextbrowser.h + mainwindow.h + tabbedbrowser.h + finddialog.ui.h + + + class QTextBrowser; + class QStatusBar; + class MainWindow; + + + QStatusBar *sb; + bool onceFound; + QString findExpr; + QTextBrowser *lastBrowser; + + + init() + destroy() + doFind() + doFind(bool) + statusMessage(const QString &message) + + + mainWindow() + hasFindExpression() + + + diff --git a/tools/assistant/finddialog.ui.h b/tools/assistant/finddialog.ui.h new file mode 100644 index 0000000..d4ca133 --- /dev/null +++ b/tools/assistant/finddialog.ui.h @@ -0,0 +1,108 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +void FindDialog::init() +{ + lastBrowser = 0; + onceFound = FALSE; + findExpr = ""; + sb = new QStatusBar( this ); + FindDialogLayout->addWidget( sb ); + sb->message( tr( "Enter the text you are looking for." ) ); +} + +void FindDialog::destroy() +{ +} + +void FindDialog::doFind() +{ + doFind(radioForward->isChecked()); +} + +void FindDialog::doFind(bool forward) +{ + QTextBrowser *browser = (QTextBrowser*) mainWindow()->browsers()->currentBrowser(); + sb->clear(); + + if (comboFind->currentText() != findExpr || lastBrowser != browser) + onceFound = false; + findExpr = comboFind->currentText(); + + bool found; + if (browser->hasSelectedText()) { // Search either forward or backward from cursor. + found = browser->find(findExpr, checkCase->isChecked(), checkWords->isChecked(), + forward); + } else { + int para = forward ? 0 : INT_MAX; + int index = forward ? 0 : INT_MAX; + found = browser->find(findExpr, checkCase->isChecked(), checkWords->isChecked(), + forward, ¶, &index); + } + + if (!found) { + if (onceFound) { + if (forward) + statusMessage(tr("Search reached end of the document")); + else + statusMessage(tr("Search reached start of the document")); + } else { + statusMessage(tr( "Text not found" )); + } + } + onceFound |= found; + lastBrowser = browser; +} + + + +MainWindow* FindDialog::mainWindow() +{ + return (MainWindow*) parent(); +} + +bool FindDialog::hasFindExpression() +{ + return !findExpr.isEmpty(); +} + +void FindDialog::statusMessage(const QString &message) +{ + if (isVisible()) + sb->message(message); + else + ((MainWindow*) parent())->statusBar()->message(message, 2000); + +} diff --git a/tools/assistant/helpdialog.ui b/tools/assistant/helpdialog.ui new file mode 100644 index 0000000..cb8865d --- /dev/null +++ b/tools/assistant/helpdialog.ui @@ -0,0 +1,506 @@ + +HelpDialogBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + HelpDialogBase + + + + 0 + 0 + 268 + 448 + + + + Help + + + <b>Help</b><p>Choose the topic you want help on from the contents list, or search the index for keywords.</p> + + + + unnamed + + + 0 + + + 6 + + + + tabWidget + + + Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search. + + + + contentPage + + + Con&tents + + + + unnamed + + + 5 + + + 6 + + + + + Column 1 + + + true + + + true + + + + listContents + + + true + + + <b>Help topics organized by category.</b><p>Double-click an item to see the topics in that category. To view a topic, just double-click it.</p> + + + + + + + Widget8 + + + &Index + + + + unnamed + + + 5 + + + 6 + + + + TextLabel1 + + + &Look For: + + + editIndex + + + + + editIndex + + + Enter keyword + + + <b>Enter a keyword.</b><p>The list will select an item that matches the entered string best.</p> + + + + + listIndex + + + <b>List of available help topics.</b><p>Double-click on an item to open its help page. If more than one is found, you must specify which page you want.</p> + + + + + + + Widget9 + + + &Bookmarks + + + + unnamed + + + 5 + + + 6 + + + + + Column 1 + + + true + + + true + + + + listBookmarks + + + Displays the list of bookmarks. + + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonAdd + + + &New + + + Add new bookmark + + + Add the currently displayed page as a new bookmark. + + + + + buttonRemove + + + &Delete + + + Delete bookmark + + + Delete the selected bookmark. + + + + + + + + + searchTab + + + &Search + + + + unnamed + + + 5 + + + 6 + + + + Spacer3 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + TextLabel1_2 + + + Searching f&or: + + + termsEdit + + + + + termsEdit + + + Enter searchword(s). + + + <b>Enter search word(s).</b><p>Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.</p> + + + + + resultBox + + + <b>Found documents</b><p>This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.</p> + + + + + TextLabel2 + + + Found &Documents: + + + resultBox + + + + + Layout2 + + + + unnamed + + + + helpButton + + + He&lp + + + Display the help page. + + + Display the help page for the full text search. + + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 61 + 21 + + + + + + searchButton + + + &Search + + + Start searching. + + + Pressing this button starts the search. + + + + + + + + + + framePrepare + + + StyledPanel + + + Raised + + + + unnamed + + + 3 + + + 6 + + + + labelPrepare + + + Preparing... + + + + + progressPrepare + + + + + + + + + buttonAdd + clicked() + HelpDialogBase + addBookmark() + + + buttonRemove + clicked() + HelpDialogBase + removeBookmark() + + + termsEdit + returnPressed() + searchButton + animateClick() + + + helpButton + clicked() + HelpDialogBase + showSearchHelp() + + + searchButton + clicked() + HelpDialogBase + startSearch() + + + resultBox + returnPressed(QListBoxItem*) + HelpDialogBase + showResultPage(QListBoxItem*) + + + resultBox + mouseButtonClicked(int, QListBoxItem*, const QPoint &) + HelpDialogBase + showResultPage(int, QListBoxItem*, const QPoint & ) + + + + tabWidget + listContents + editIndex + listIndex + listBookmarks + buttonAdd + buttonRemove + termsEdit + searchButton + helpButton + resultBox + + + init() + destroy() + addBookmark() + currentBookmarkChanged( QListViewItem * ) + currentIndexChanged( QListBoxItem * ) + currentTabChanged( const QString & ) + loadIndexFile() + currentContentsChanged( QListViewItem * ) + removeBookmark() + searchInIndex( const QString & ) + showTopic() + showTopic( int, QListBoxItem *, const QPoint & ) + showSearchHelp() + startSearch() + showResultPage( QListBoxItem * ) + showResultPage( int, QListBoxItem *, const QPoint & ) + showResultPage( int, QListViewItem *, const QPoint & ) + + + diff --git a/tools/assistant/helpdialogimpl.cpp b/tools/assistant/helpdialogimpl.cpp new file mode 100644 index 0000000..ceee175 --- /dev/null +++ b/tools/assistant/helpdialogimpl.cpp @@ -0,0 +1,1161 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "helpdialogimpl.h" +#include "helpwindow.h" +#include "topicchooserimpl.h" +#include "docuparser.h" +#include "mainwindow.h" +#include "config.h" +#include "tabbedbrowser.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static QString stripAmpersand( const QString &str ) +{ + QString s( str ); + s = s.replace( '&', "" ); + return s; +} + +static bool verifyDirectory(const QString &str) +{ + QFileInfo dirInfo(str); + if (!dirInfo.exists()) + return QDir().mkdir(str); + if (!dirInfo.isDir()) { + qWarning("'%s' exists but is not a directory", str.latin1()); + return FALSE; + } + return TRUE; +} + +struct IndexKeyword { + IndexKeyword( const QString &kw, const QString &l ) + : keyword( kw ), link( l ) {} + IndexKeyword() : keyword( QString::null ), link( QString::null ) {} + bool operator<( const IndexKeyword &ik ) const { + return keyword.lower() < ik.keyword.lower(); + } + bool operator<=( const IndexKeyword &ik ) const { + return keyword.lower() <= ik.keyword.lower(); + } + bool operator>( const IndexKeyword &ik ) const { + return keyword.lower() > ik.keyword.lower(); + } + Q_DUMMY_COMPARISON_OPERATOR( IndexKeyword ) + QString keyword; + QString link; +}; + +QDataStream &operator>>( QDataStream &s, IndexKeyword &ik ) +{ + s >> ik.keyword; + s >> ik.link; + return s; +} + +QDataStream &operator<<( QDataStream &s, const IndexKeyword &ik ) +{ + s << ik.keyword; + s << ik.link; + return s; +} + +QValidator::State SearchValidator::validate( QString &str, int & ) const +{ + for ( int i = 0; i < (int) str.length(); ++i ) { + QChar c = str[i]; + if ( !c.isLetterOrNumber() && c != '\'' && c != '`' + && c != '\"' && c != ' ' && c != '-' && c != '_' + && c!= '*' ) + return QValidator::Invalid; + } + return QValidator::Acceptable; +} + +HelpNavigationListItem::HelpNavigationListItem( QListBox *ls, const QString &txt ) + : QListBoxText( ls, txt ) +{ +} + +void HelpNavigationListItem::addLink( const QString &link ) +{ + int hash = link.find( '#' ); + if ( hash == -1 ) { + linkList << link; + return; + } + + QString preHash = link.left( hash ); + if ( linkList.grep( preHash, FALSE ).count() > 0 ) + return; + linkList << link; +} + +HelpNavigationContentsItem::HelpNavigationContentsItem( QListView *v, QListViewItem *after ) + : QListViewItem( v, after ) +{ +} + +HelpNavigationContentsItem::HelpNavigationContentsItem( QListViewItem *v, QListViewItem *after ) + : QListViewItem( v, after ) +{ +} + +void HelpNavigationContentsItem::setLink( const QString &lnk ) +{ + theLink = lnk; +} + +QString HelpNavigationContentsItem::link() const +{ + return theLink; +} + + + +HelpDialog::HelpDialog( QWidget *parent, MainWindow *h ) + : HelpDialogBase( parent, 0, FALSE ), lwClosed( FALSE ), help( h ) +{ +} + +void HelpDialog::initialize() +{ + connect( tabWidget, SIGNAL( selected(const QString&) ), + this, SLOT( currentTabChanged(const QString&) ) ); + connect( listContents, SIGNAL( mouseButtonClicked(int, QListViewItem*, const QPoint &, int ) ), + this, SLOT( showTopic(int,QListViewItem*, const QPoint &) ) ); + connect( listContents, SIGNAL( currentChanged(QListViewItem*) ), + this, SLOT( currentContentsChanged(QListViewItem*) ) ); + connect( listContents, SIGNAL( selectionChanged(QListViewItem*) ), + this, SLOT( currentContentsChanged(QListViewItem*) ) ); + connect( listContents, SIGNAL( doubleClicked(QListViewItem*) ), + this, SLOT( showTopic(QListViewItem*) ) ); + connect( listContents, SIGNAL( returnPressed(QListViewItem*) ), + this, SLOT( showTopic(QListViewItem*) ) ); + connect( listContents, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint&, int ) ), + this, SLOT( showItemMenu( QListViewItem*, const QPoint& ) ) ); + connect( editIndex, SIGNAL( returnPressed() ), + this, SLOT( showTopic() ) ); + connect( editIndex, SIGNAL( textChanged(const QString&) ), + this, SLOT( searchInIndex(const QString&) ) ); + + connect( listIndex, SIGNAL( selectionChanged(QListBoxItem*) ), + this, SLOT( currentIndexChanged(QListBoxItem*) ) ); + connect( listIndex, SIGNAL( returnPressed(QListBoxItem*) ), + this, SLOT( showTopic() ) ); + connect( listIndex, SIGNAL( mouseButtonClicked(int, QListBoxItem*, const QPoint &) ), + this, SLOT( showTopic( int, QListBoxItem *, const QPoint & ) ) ); + connect( listIndex, SIGNAL( currentChanged(QListBoxItem*) ), + this, SLOT( currentIndexChanged(QListBoxItem*) ) ); + connect( listIndex, SIGNAL( contextMenuRequested( QListBoxItem*, const QPoint& ) ), + this, SLOT( showItemMenu( QListBoxItem*, const QPoint& ) ) ); + + connect( listBookmarks, SIGNAL( mouseButtonClicked(int, QListViewItem*, const QPoint&, int ) ), + this, SLOT( showTopic(int, QListViewItem*, const QPoint &) ) ); + connect( listBookmarks, SIGNAL( returnPressed(QListViewItem*) ), + this, SLOT( showTopic(QListViewItem*) ) ); + connect( listBookmarks, SIGNAL( selectionChanged(QListViewItem*) ), + this, SLOT( currentBookmarkChanged(QListViewItem*) ) ); + connect( listBookmarks, SIGNAL( currentChanged(QListViewItem*) ), + this, SLOT( currentBookmarkChanged(QListViewItem*) ) ); + connect( listBookmarks, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint&, int ) ), + this, SLOT( showItemMenu( QListViewItem*, const QPoint& ) ) ); + connect( resultBox, SIGNAL( contextMenuRequested( QListBoxItem*, const QPoint& ) ), + this, SLOT( showItemMenu( QListBoxItem*, const QPoint& ) ) ); + + cacheFilesPath = QDir::homeDirPath() + "/.assistant/"; //### Find a better location for the dbs + + editIndex->installEventFilter( this ); + listBookmarks->header()->hide(); + listBookmarks->header()->setStretchEnabled( TRUE ); + listContents->header()->hide(); + listContents->header()->setStretchEnabled( TRUE ); + framePrepare->hide(); + connect( qApp, SIGNAL(lastWindowClosed()), SLOT(lastWinClosed()) ); + + termsEdit->setValidator( new SearchValidator( termsEdit ) ); + + itemPopup = new QPopupMenu( this ); + itemPopup->insertItem( tr( "Open Link in Current Tab" ), 0 ); + itemPopup->insertItem( tr( "Open Link in New Window" ), 1 ); + itemPopup->insertItem( tr( "Open Link in New Tab" ), 2 ); + + contentList.setAutoDelete( TRUE ); + contentList.clear(); + + initDoneMsgShown = FALSE; + fullTextIndex = 0; + indexDone = FALSE; + titleMapDone = FALSE; + contentsInserted = FALSE; + bookmarksInserted = FALSE; + setupTitleMap(); +} + + +void HelpDialog::processEvents() +{ + qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput ); +} + + +void HelpDialog::lastWinClosed() +{ + lwClosed = TRUE; +} + + +void HelpDialog::removeOldCacheFiles() +{ + QString dir = cacheFilesPath; // ### remove the last '/' ? + if (!verifyDirectory(cacheFilesPath)) { + qWarning( "Failed to created assistant directory" ); + return; + } + QString pname = "." + Config::configuration()->profileName(); + + QStringList fileList; + fileList << "indexdb" << "indexdb.dict" << "indexdb.doc" << "contentdb"; + QStringList::iterator it = fileList.begin(); + for ( ; it != fileList.end(); ++it ) { + if ( QFile::exists( cacheFilesPath + *it + pname ) ) { + QFile f( cacheFilesPath + *it + pname ); + f.remove(); + } + } +} + +void HelpDialog::timerEvent(QTimerEvent *e) +{ + static int opacity = 255; + // To allow patching of 3.2.3 assistant for qsa. +#if QT_VERSION >= 0x030300 + help->setWindowOpacity((opacity-=4)/255.0); + if (opacity<=0) +#endif + qApp->quit(); +} + + +void HelpDialog::loadIndexFile() +{ + if ( indexDone ) + return; + + setCursor( waitCursor ); + indexDone = TRUE; + labelPrepare->setText( tr( "Prepare..." ) ); + framePrepare->show(); + processEvents(); + + QProgressBar *bar = progressPrepare; + bar->setTotalSteps( 100 ); + bar->setProgress( 0 ); + + keywordDocuments.clear(); + QValueList lst; + QFile indexFile( cacheFilesPath + "indexdb." + + Config::configuration()->profileName() ); + if ( !indexFile.open( IO_ReadOnly ) ) { + buildKeywordDB(); + processEvents(); + if( lwClosed ) + return; + if (!indexFile.open(IO_ReadOnly)) { + QMessageBox::warning(help, tr("Qt Assistant"), tr("Failed to load keyword index file\n" + "Assistant will not work!")); +#if defined Q_WS_WIN || defined Q_WS_MACX + startTimer(50); +#endif + return; + } + } + + editIndex->setEnabled(FALSE); + + QDataStream ds( &indexFile ); + Q_UINT32 fileAges; + ds >> fileAges; + if ( fileAges != getFileAges() ) { + indexFile.close(); + buildKeywordDB(); + if ( !indexFile.open( IO_ReadOnly ) ) { + QMessageBox::warning( help, tr( "Qt Assistant" ), + tr( "Cannot open the index file %1" ).arg( QFileInfo( indexFile ).absFilePath() ) ); + editIndex->setEnabled(TRUE); + return; + } + ds.setDevice( &indexFile ); + ds >> fileAges; + } + ds >> lst; + indexFile.close(); + + bar->setProgress( bar->totalSteps() ); + processEvents(); + + listIndex->clear(); + HelpNavigationListItem *lastItem = 0; + QString lastKeyword = QString::null; + QValueList::ConstIterator it = lst.begin(); + for ( ; it != lst.end(); ++it ) { + if ( lastKeyword.lower() != (*it).keyword.lower() ) + lastItem = new HelpNavigationListItem( listIndex, (*it).keyword ); + lastItem->addLink( (*it).link ); + lastKeyword = (*it).keyword; + + QString lnk = (*it).link; + int i = lnk.findRev('#'); + if ( i > -1 ) + lnk = lnk.left( i ); + if (!keywordDocuments.contains(lnk)) + keywordDocuments.append(lnk); + } + framePrepare->hide(); + showInitDoneMessage(); + setCursor( arrowCursor ); + editIndex->setEnabled(TRUE); +} + +Q_UINT32 HelpDialog::getFileAges() +{ + QStringList addDocuFiles = Config::configuration()->docFiles(); + QStringList::const_iterator i = addDocuFiles.begin(); + + Q_UINT32 fileAges = 0; + for( ; i != addDocuFiles.end(); ++i ) { + QFileInfo fi( *i ); + if ( fi.exists() ) + fileAges += fi.lastModified().toTime_t(); + } + + return fileAges; +} + +void HelpDialog::buildKeywordDB() +{ + QStringList addDocuFiles = Config::configuration()->docFiles(); + QStringList::iterator i = addDocuFiles.begin(); + + int steps = 0; + for( ; i != addDocuFiles.end(); i++ ) + steps += QFileInfo( *i ).size(); + + labelPrepare->setText( tr( "Prepare..." ) ); + progressPrepare->setTotalSteps( steps ); + progressPrepare->setProgress( 0 ); + processEvents(); + + QValueList lst; + Q_UINT32 fileAges = 0; + for( i = addDocuFiles.begin(); i != addDocuFiles.end(); i++ ){ + QFile file( *i ); + if ( !file.exists() ) { + QMessageBox::warning( this, tr( "Warning" ), + tr( "Documentation file %1 does not exist!\n" + "Skipping file." ).arg( QFileInfo( file ).absFilePath() ) ); + continue; + } + fileAges += QFileInfo( file ).lastModified().toTime_t(); + DocuParser *handler = DocuParser::createParser( *i ); + bool ok = handler->parse( &file ); + file.close(); + if( !ok ){ + QString msg = QString( "In file %1:\n%2" ) + .arg( QFileInfo( file ).absFilePath() ) + .arg( handler->errorProtocol() ); + QMessageBox::critical( this, tr( "Parse Error" ), tr( msg ) ); + delete handler; + continue; + } + + QPtrList indLst = handler->getIndexItems(); + QPtrListIterator it( indLst ); + IndexItem *indItem; + int counter = 0; + while ( ( indItem = it.current() ) != 0 ) { + QFileInfo fi( indItem->reference ); + lst.append( IndexKeyword( indItem->keyword, fi.absFilePath() ) ); + if ( progressPrepare ) + progressPrepare->setProgress( progressPrepare->progress() + + int(fi.absFilePath().length() * 1.6) ); + + if( ++counter%100 == 0 ) { + processEvents(); + if( lwClosed ) { + return; + } + } + ++it; + } + delete handler; + } + if ( !lst.isEmpty() ) + qHeapSort( lst ); + + QFile indexout( cacheFilesPath + "indexdb." + Config::configuration()->profileName() ); + if ( verifyDirectory(cacheFilesPath) && indexout.open( IO_WriteOnly ) ) { + QDataStream s( &indexout ); + s << fileAges; + s << lst; + indexout.close(); + } +} + +void HelpDialog::setupTitleMap() +{ + if ( titleMapDone ) + return; + if ( Config::configuration()->docRebuild() ) { + removeOldCacheFiles(); + Config::configuration()->setDocRebuild( FALSE ); + Config::configuration()->saveProfile( Config::configuration()->profile() ); + } + if ( contentList.isEmpty() ) + getAllContents(); + + titleMapDone = TRUE; + titleMap.clear(); + QDictIterator lstIt( contentList ); + for ( ; lstIt.current(); ++lstIt ) { + QValueList &lst = *(lstIt.current()); + QValueListConstIterator it; + for ( it = lst.begin(); it != lst.end(); ++it ) { + QFileInfo link( (*it).reference.simplifyWhiteSpace() ); + titleMap[ link.absFilePath() ] = (*it).title.stripWhiteSpace(); + } + } + processEvents(); +} + +void HelpDialog::getAllContents() +{ + QFile contentFile( cacheFilesPath + "contentdb." + Config::configuration()->profileName() ); + contentList.clear(); + if ( !contentFile.open( IO_ReadOnly ) ) { + buildContentDict(); + return; + } + + QDataStream ds( &contentFile ); + Q_UINT32 fileAges; + ds >> fileAges; + if ( fileAges != getFileAges() ) { + contentFile.close(); + buildContentDict(); + return; + } + QString key; + QValueList lst; + while ( !ds.atEnd() ) { + ds >> key; + ds >> lst; + contentList.insert( key, new QValueList( lst ) ); + } + contentFile.close(); + processEvents(); + +} + +void HelpDialog::buildContentDict() +{ + QStringList docuFiles = Config::configuration()->docFiles(); + + Q_UINT32 fileAges = 0; + for( QStringList::iterator it = docuFiles.begin(); it != docuFiles.end(); it++ ) { + QFile file( *it ); + if ( !file.exists() ) { + QMessageBox::warning( this, tr( "Warning" ), + tr( "Documentation file %1 does not exist!\n" + "Skipping file." ).arg( QFileInfo( file ).absFilePath() ) ); + continue; + } + fileAges += QFileInfo( file ).lastModified().toTime_t(); + DocuParser *handler = DocuParser::createParser( *it ); + if( !handler ) { + QMessageBox::warning( this, tr( "Warning" ), + tr( "Documentation file %1 is not compatible!\n" + "Skipping file." ).arg( QFileInfo( file ).absFilePath() ) ); + continue; + } + bool ok = handler->parse( &file ); + file.close(); + if( ok ) { + contentList.insert( *it, new QValueList( handler->getContentItems() ) ); + delete handler; + } else { + QString msg = QString( "In file %1:\n%2" ) + .arg( QFileInfo( file ).absFilePath() ) + .arg( handler->errorProtocol() ); + QMessageBox::critical( this, tr( "Parse Error" ), tr( msg ) ); + continue; + } + } + + QString pname = Config::configuration()->profileName(); + QFile contentOut( cacheFilesPath + "contentdb." + pname ); + QFile::remove( cacheFilesPath + "indexdb.dict." + pname ); + QFile::remove( cacheFilesPath + "indexdb.doc." + pname ); + if ( contentOut.open( IO_WriteOnly ) ) { + QDataStream s( &contentOut ); + s << fileAges; + QDictIterator it( contentList ); + for ( ; it.current(); ++it ) { + s << it.currentKey(); + s << *(it.current()); + } + contentOut.close(); + } +} + +void HelpDialog::currentTabChanged( const QString &s ) +{ + if ( stripAmpersand( s ).contains( tr( "Index" ) ) ) + QTimer::singleShot( 0, this, SLOT( loadIndexFile() ) ); + else if ( stripAmpersand( s ).contains( tr( "Bookmarks" ) ) ) + insertBookmarks(); + else if ( stripAmpersand( s ).contains( tr( "Contents" ) ) ) + QTimer::singleShot( 0, this, SLOT( insertContents() ) ); + else if ( stripAmpersand( s ).contains( tr( "Search" ) ) ) + QTimer::singleShot( 0, this, SLOT( setupFullTextIndex() ) ); +} + +void HelpDialog::showInitDoneMessage() +{ + if ( initDoneMsgShown ) + return; + initDoneMsgShown = TRUE; + help->statusBar()->message( tr( "Done" ), 3000 ); +} + +void HelpDialog::currentIndexChanged( QListBoxItem * ) +{ +} + + +void HelpDialog::showTopic( int button, QListBoxItem *item, + const QPoint & ) +{ + if( button == LeftButton && item ) + showTopic(); +} + +void HelpDialog::showTopic( int button, QListViewItem *item, + const QPoint & ) +{ + if( button == LeftButton && item ) + showTopic(); +} + +void HelpDialog::showTopic( QListViewItem *item ) +{ + if( item ) + showTopic(); +} + +void HelpDialog::showTopic() +{ + if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Index" ) ) ) + showIndexTopic(); + else if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Bookmarks" ) ) ) + showBookmarkTopic(); + else if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Contents" ) ) ) + showContentsTopic(); +} + +void HelpDialog::showIndexTopic() +{ + QListBoxItem *i = listIndex->item( listIndex->currentItem() ); + if ( !i ) + return; + + editIndex->blockSignals( TRUE ); + editIndex->setText( i->text() ); + editIndex->blockSignals( FALSE ); + + HelpNavigationListItem *item = (HelpNavigationListItem*)i; + + QStringList links = item->links(); + if ( links.count() == 1 ) { + emit showLink( links.first() ); + } else { + qHeapSort( links ); + QStringList::Iterator it = links.begin(); + QStringList linkList; + QStringList linkNames; + for ( ; it != links.end(); ++it ) { + linkList << *it; + linkNames << titleOfLink( *it ); + } + QString link = TopicChooser::getLink( this, linkNames, linkList, i->text() ); + if ( !link.isEmpty() ) + emit showLink( link ); + } +} + +void HelpDialog::searchInIndex( const QString &s ) +{ + QListBoxItem *i = listIndex->firstItem(); + QString sl = s.lower(); + while ( i ) { + QString t = i->text(); + if ( t.length() >= sl.length() && + i->text().left(s.length()).lower() == sl ) { + listIndex->setCurrentItem( i ); + listIndex->setTopItem(listIndex->index(i)); + break; + } + i = i->next(); + } +} + +QString HelpDialog::titleOfLink( const QString &link ) +{ + QString s( link ); + s.remove( s.find( '#' ), s.length() ); + s = titleMap[ s ]; + if ( s.isEmpty() ) + return link; + return s; +} + +bool HelpDialog::eventFilter( QObject * o, QEvent * e ) +{ + if ( !o || !e ) + return TRUE; + + if ( o == editIndex && e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ke->key() == Key_Up ) { + int i = listIndex->currentItem(); + if ( --i >= 0 ) { + listIndex->setCurrentItem( i ); + editIndex->blockSignals( TRUE ); + editIndex->setText( listIndex->currentText() ); + editIndex->blockSignals( FALSE ); + } + return TRUE; + } else if ( ke->key() == Key_Down ) { + int i = listIndex->currentItem(); + if ( ++i < int(listIndex->count()) ) { + listIndex->setCurrentItem( i ); + editIndex->blockSignals( TRUE ); + editIndex->setText( listIndex->currentText() ); + editIndex->blockSignals( FALSE ); + } + return TRUE; + } else if ( ke->key() == Key_Next || ke->key() == Key_Prior ) { + QApplication::sendEvent( listIndex, e); + editIndex->blockSignals( TRUE ); + editIndex->setText( listIndex->currentText() ); + editIndex->blockSignals( FALSE ); + } + } + + return QWidget::eventFilter( o, e ); +} + +void HelpDialog::addBookmark() +{ + if ( !bookmarksInserted ) + insertBookmarks(); + QString link = QUrl( help->browsers()->currentBrowser()->context(), + help->browsers()->currentBrowser()->source() ).path(); + QString title = help->browsers()->currentBrowser()->documentTitle(); + if ( title.isEmpty() ) + title = titleOfLink( link ); + HelpNavigationContentsItem *i = new HelpNavigationContentsItem( listBookmarks, 0 ); + i->setText( 0, title ); + i->setLink( link ); + saveBookmarks(); + help->updateBookmarkMenu(); +} + +void HelpDialog::removeBookmark() +{ + if ( !listBookmarks->currentItem() ) + return; + + delete listBookmarks->currentItem(); + saveBookmarks(); + if ( listBookmarks->firstChild() ) { + listBookmarks->setSelected( listBookmarks->firstChild(), TRUE ); + } + help->updateBookmarkMenu(); +} + +void HelpDialog::insertBookmarks() +{ + if ( bookmarksInserted ) + return; + bookmarksInserted = TRUE; + listBookmarks->clear(); + QFile f( cacheFilesPath + "bookmarks." + Config::configuration()->profileName() ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + while ( !ts.atEnd() ) { + HelpNavigationContentsItem *i = new HelpNavigationContentsItem( listBookmarks, 0 ); + i->setText( 0, ts.readLine() ); + i->setLink( ts.readLine() ); + } + help->updateBookmarkMenu(); + showInitDoneMessage(); +} + +void HelpDialog::currentBookmarkChanged( QListViewItem * ) +{ +} + +void HelpDialog::showBookmarkTopic() +{ + if ( !listBookmarks->currentItem() ) + return; + + HelpNavigationContentsItem *i = (HelpNavigationContentsItem*)listBookmarks->currentItem(); + QString absPath = ""; + if ( QFileInfo( i->link() ).isRelative() ) + absPath = documentationPath + "/"; + emit showLink( absPath + i->link() ); +} + +void HelpDialog::saveBookmarks() +{ + QFile f( cacheFilesPath + "bookmarks." + Config::configuration()->profileName() ); + if ( !f.open( IO_WriteOnly ) ) + return; + QTextStream ts( &f ); + QListViewItemIterator it( listBookmarks ); + for ( ; it.current(); ++it ) { + HelpNavigationContentsItem *i = (HelpNavigationContentsItem*)it.current(); + ts << i->text( 0 ) << endl; + ts << i->link() << endl; + } + f.close(); +} + +void HelpDialog::insertContents() +{ + if ( contentsInserted ) + return; + + if ( contentList.isEmpty() ) + getAllContents(); + + contentsInserted = TRUE; + listContents->clear(); + setCursor( waitCursor ); + if ( !titleMapDone ) + setupTitleMap(); + + listContents->setSorting( -1 ); + + QDictIterator lstIt( contentList ); + for ( ; lstIt.current(); ++lstIt ) { + HelpNavigationContentsItem *newEntry; + + HelpNavigationContentsItem *contentEntry = 0; + QPtrStack stack; + stack.clear(); + int depth = 0; + bool root = FALSE; + + HelpNavigationContentsItem *lastItem[64]; + for( int j = 0; j < 64; ++j ) + lastItem[j] = 0; + + + QValueList &lst = *(lstIt.current()); + QValueListConstIterator it; + for( it = lst.begin(); it != lst.end(); ++it ){ + ContentItem item = *it; + if( item.depth == 0 ){ + newEntry = new HelpNavigationContentsItem( listContents, 0 ); + newEntry->setPixmap( 0, QPixmap::fromMimeSource( "book.png" ) ); + newEntry->setText( 0, item.title ); + newEntry->setLink( item.reference ); + stack.push( newEntry ); + depth = 1; + root = TRUE; + } + else{ + if( (item.depth > depth) && root ) { + depth = item.depth; + stack.push( contentEntry ); + } + if( item.depth == depth ) { + contentEntry = new HelpNavigationContentsItem( stack.top(), lastItem[ depth ] ); + lastItem[ depth ] = contentEntry; + contentEntry->setText( 0, item.title ); + contentEntry->setLink( item.reference ); + } + else if( item.depth < depth ) { + stack.pop(); + depth--; + item = *(--it); + } + } + } + processEvents(); + } + setCursor( arrowCursor ); + showInitDoneMessage(); +} + +void HelpDialog::currentContentsChanged( QListViewItem * ) +{ +} + +void HelpDialog::showContentsTopic() +{ + HelpNavigationContentsItem *i = (HelpNavigationContentsItem*)listContents->currentItem(); + if ( !i ) + return; + emit showLink( i->link() ); +} + +void HelpDialog::toggleContents() +{ + if ( !isVisible() || tabWidget->currentPageIndex() != 0 ) { + tabWidget->setCurrentPage( 0 ); + parentWidget()->show(); + } + else + parentWidget()->hide(); +} + +void HelpDialog::toggleIndex() +{ + if ( !isVisible() || tabWidget->currentPageIndex() != 1 || !editIndex->hasFocus() ) { + tabWidget->setCurrentPage( 1 ); + parentWidget()->show(); + editIndex->setFocus(); + } + else + parentWidget()->hide(); +} + +void HelpDialog::toggleBookmarks() +{ + if ( !isVisible() || tabWidget->currentPageIndex() != 2 ) { + tabWidget->setCurrentPage( 2 ); + parentWidget()->show(); + } + else + parentWidget()->hide(); +} + +void HelpDialog::toggleSearch() +{ + if ( !isVisible() || tabWidget->currentPageIndex() != 3 ) { + tabWidget->setCurrentPage( 3 ); + parentWidget()->show(); + } + else + parentWidget()->hide(); +} + +void HelpDialog::setupFullTextIndex() +{ + if ( fullTextIndex ) + return; + + QStringList documentList; + QString pname = Config::configuration()->profileName(); + fullTextIndex = new Index( documentList, QDir::homeDirPath() ); // ### Is this correct ? + if (!verifyDirectory(cacheFilesPath)) { + QMessageBox::warning(help, tr("Qt Assistant"), + tr("Failed to save fulltext search index\n" + "Assistant will not work!")); + return; + } + searchButton->setEnabled(FALSE); + helpButton->setEnabled(FALSE); + termsEdit->setEnabled(FALSE); + + fullTextIndex->setDictionaryFile( cacheFilesPath + "indexdb.dict." + pname ); + fullTextIndex->setDocListFile( cacheFilesPath + "indexdb.doc." + pname ); + processEvents(); + + connect( fullTextIndex, SIGNAL( indexingProgress( int ) ), + this, SLOT( setIndexingProgress( int ) ) ); + QFile f( cacheFilesPath + "indexdb.dict." + pname ); + if ( !f.exists() ) { + QMap::ConstIterator it = titleMap.begin(); + QString documentName; + for ( ; it != titleMap.end(); ++it ) { + documentName = it.key(); + int i = documentName.findRev('#'); + if ( i > -1 ) + documentName = documentName.left( i ); + + if (!documentList.contains(documentName)) + documentList << documentName; + } + loadIndexFile(); + for (QStringList::Iterator it2 = keywordDocuments.begin(); it2 != keywordDocuments.end(); ++it2) { + if (!documentList.contains(*it2)) + documentList << *it2; + } + fullTextIndex->setDocList( documentList ); + + help->statusBar()->clear(); + setCursor( waitCursor ); + labelPrepare->setText( tr( "Indexing files..." ) ); + progressPrepare->setTotalSteps( 100 ); + progressPrepare->reset(); + progressPrepare->show(); + framePrepare->show(); + processEvents(); + if ( fullTextIndex->makeIndex() != -1 ) { + fullTextIndex->writeDict(); + progressPrepare->setProgress( 100 ); + framePrepare->hide(); + setCursor( arrowCursor ); + showInitDoneMessage(); + keywordDocuments.clear(); + } + } else { + setCursor( waitCursor ); + help->statusBar()->message( tr( "Reading dictionary..." ) ); + processEvents(); + fullTextIndex->readDict(); + help->statusBar()->message( tr( "Done" ), 3000 ); + setCursor( arrowCursor ); + } + searchButton->setEnabled(TRUE); + termsEdit->setEnabled(TRUE); + helpButton->setEnabled(TRUE); +} + +void HelpDialog::setIndexingProgress( int prog ) +{ + progressPrepare->setProgress( prog ); + processEvents(); +} + +void HelpDialog::startSearch() +{ + QString str = termsEdit->text(); + str = str.replace( "\'", "\"" ); + str = str.replace( "`", "\"" ); + QString buf = str; + str = str.replace( "-", " " ); + str = str.replace( QRegExp( "\\s[\\S]?\\s" ), " " ); + terms = QStringList::split( " ", str ); + QStringList termSeq; + QStringList seqWords; + QStringList::iterator it = terms.begin(); + for ( ; it != terms.end(); ++it ) { + (*it) = (*it).simplifyWhiteSpace(); + (*it) = (*it).lower(); + (*it) = (*it).replace( "\"", "" ); + } + if ( str.contains( '\"' ) ) { + if ( (str.contains( '\"' ))%2 == 0 ) { + int beg = 0; + int end = 0; + QString s; + beg = str.find( '\"', beg ); + while ( beg != -1 ) { + beg++; + end = str.find( '\"', beg ); + s = str.mid( beg, end - beg ); + s = s.lower(); + s = s.simplifyWhiteSpace(); + if ( s.contains( '*' ) ) { + QMessageBox::warning( this, tr( "Full Text Search" ), + tr( "Using a wildcard within phrases is not allowed." ) ); + return; + } + seqWords += QStringList::split( ' ', s ); + termSeq << s; + beg = str.find( '\"', end + 1); + } + } else { + QMessageBox::warning( this, tr( "Full Text Search" ), + tr( "The closing quotation mark is missing." ) ); + return; + } + } + setCursor( waitCursor ); + foundDocs.clear(); + foundDocs = fullTextIndex->query( terms, termSeq, seqWords ); + QString msg( QString( "%1 documents found." ).arg( foundDocs.count() ) ); + help->statusBar()->message( tr( msg ), 3000 ); + resultBox->clear(); + for ( it = foundDocs.begin(); it != foundDocs.end(); ++it ) + resultBox->insertItem( fullTextIndex->getDocumentTitle( *it ) ); + + terms.clear(); + bool isPhrase = FALSE; + QString s = ""; + for ( int i = 0; i < (int)buf.length(); ++i ) { + if ( buf[i] == '\"' ) { + isPhrase = !isPhrase; + s = s.simplifyWhiteSpace(); + if ( !s.isEmpty() ) + terms << s; + s = ""; + } else if ( buf[i] == ' ' && !isPhrase ) { + s = s.simplifyWhiteSpace(); + if ( !s.isEmpty() ) + terms << s; + s = ""; + } else + s += buf[i]; + } + if ( !s.isEmpty() ) + terms << s; + + setCursor( arrowCursor ); +} + +void HelpDialog::showSearchHelp() +{ + emit showLink( Config::configuration()->assistantDocPath() + "/assistant-5.html" ); +} + +void HelpDialog::showResultPage( int button, QListBoxItem *i, const QPoint & ) +{ + if( button == LeftButton ) { + showResultPage( i ); + } +} + +void HelpDialog::showResultPage( QListBoxItem *i ) +{ + if( !i ) + return; + emit showSearchLink( foundDocs[resultBox->index( i )], terms ); +} + +void HelpDialog::showItemMenu( QListBoxItem *item, const QPoint &pos ) +{ + if ( !item ) + return; + int id = itemPopup->exec( pos ); + if ( id == 0 ) { + if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Index" ) ) ) + showTopic(); + else { + showResultPage( item ); + } + } else if ( id > 0 ) { + HelpWindow *hw = help->browsers()->currentBrowser(); + if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Index" ) ) ) { + editIndex->blockSignals( TRUE ); + editIndex->setText( item->text() ); + editIndex->blockSignals( FALSE ); + + HelpNavigationListItem *hi = (HelpNavigationListItem*)item; + + QStringList links = hi->links(); + if ( links.count() == 1 ) { + if ( id == 1 ) + hw->openLinkInNewWindow( links.first() ); + else + hw->openLinkInNewPage( links.first() ); + } else { + QStringList::Iterator it = links.begin(); + QStringList linkList; + QStringList linkNames; + for ( ; it != links.end(); ++it ) { + linkList << *it; + linkNames << titleOfLink( *it ); + } + QString link = TopicChooser::getLink( this, linkNames, linkList, item->text() ); + if ( !link.isEmpty() ) { + if ( id == 1 ) + hw->openLinkInNewWindow( link ); + else + hw->openLinkInNewPage( link ); + } + } + } else { + QString link = foundDocs[ resultBox->index( item ) ]; + if ( id == 1 ) + hw->openLinkInNewWindow( link ); + else + hw->openLinkInNewPage( link ); + } + } +} + +void HelpDialog::showItemMenu( QListViewItem *item, const QPoint &pos ) +{ + if ( !item ) + return; + int id = itemPopup->exec( pos ); + if ( id == 0 ) { + if ( stripAmpersand( tabWidget->tabLabel( tabWidget->currentPage() ) ).contains( tr( "Contents" ) ) ) + showContentsTopic(); + else + showBookmarkTopic(); + } else if ( id > 0 ) { + HelpNavigationContentsItem *i = (HelpNavigationContentsItem*)item; + if ( id == 1 ) + help->browsers()->currentBrowser()->openLinkInNewWindow( i->link() ); + else + help->browsers()->currentBrowser()->openLinkInNewPage( i->link() ); + } +} diff --git a/tools/assistant/helpdialogimpl.h b/tools/assistant/helpdialogimpl.h new file mode 100644 index 0000000..f2c8b2c --- /dev/null +++ b/tools/assistant/helpdialogimpl.h @@ -0,0 +1,171 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef HELPDIALOGIMPL_H +#define HELPDIALOGIMPL_H + +#include "helpdialog.h" +#include "index.h" +#include "helpwindow.h" +#include "docuparser.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +class QProgressBar; +class MainWindow; +class QTextBrowser; + +class HelpNavigationListItem : public QListBoxText +{ +public: + HelpNavigationListItem( QListBox *ls, const QString &txt ); + + void addLink( const QString &link ); + QStringList links() const { return linkList; } +private: + QStringList linkList; + +}; + +class SearchValidator : public QValidator +{ + Q_OBJECT +public: + SearchValidator( QObject *parent, const char *name = 0 ) + : QValidator( parent, name ) {} + ~SearchValidator() {} + QValidator::State validate( QString &str, int & ) const; +}; + +class HelpNavigationContentsItem : public QListViewItem +{ +public: + HelpNavigationContentsItem( QListView *v, QListViewItem *after ); + HelpNavigationContentsItem( QListViewItem *v, QListViewItem *after ); + + void setLink( const QString &lnk ); + QString link() const; + +private: + QString theLink; +}; + +class HelpDialog : public HelpDialogBase +{ + Q_OBJECT + +public: + HelpDialog( QWidget *parent, MainWindow *h ); + + QString titleOfLink( const QString &link ); + bool eventFilter( QObject *, QEvent * ); + bool lastWindowClosed() { return lwClosed; } + + void timerEvent(QTimerEvent *e); + +protected slots: + void showTopic( int, QListBoxItem *, const QPoint & ); + void showTopic( int, QListViewItem *, const QPoint & ); + void showTopic( QListViewItem * ); + void loadIndexFile(); + void insertContents(); + void setupFullTextIndex(); + void currentTabChanged( const QString &s ); + void currentIndexChanged( QListBoxItem *i ); + void showTopic(); + void searchInIndex( const QString &s ); + void addBookmark(); + void removeBookmark(); + void currentBookmarkChanged( QListViewItem *i ); + void currentContentsChanged( QListViewItem *i ); + void startSearch(); + void showSearchHelp(); + +public slots: + void initialize(); + void toggleContents(); + void toggleIndex(); + void toggleBookmarks(); + void toggleSearch(); + + +signals: + void showLink( const QString &s ); + void showSearchLink( const QString &s, const QStringList &terms ); + +private slots: + void lastWinClosed(); + void showResultPage( int button, QListBoxItem *i, const QPoint &p ); + void showResultPage( QListBoxItem *i ); + void setIndexingProgress( int prog ); + void showItemMenu( QListBoxItem *item, const QPoint &pos ); + void showItemMenu( QListViewItem *item, const QPoint &pos ); + void insertBookmarks(); + void processEvents(); + +private: + typedef QValueList ContentList; + void removeOldCacheFiles(); + void buildKeywordDB(); + Q_UINT32 getFileAges(); + void showIndexTopic(); + void showBookmarkTopic(); + void setupTitleMap(); + void saveBookmarks(); + void showContentsTopic(); + void showInitDoneMessage(); + void buildContentDict(); + + QMap titleMap; + bool indexDone, bookmarksInserted, titleMapDone, contentsInserted; + bool lwClosed; + MainWindow *help; + QString documentationPath; + Index *fullTextIndex; + QStringList terms, foundDocs; + bool initDoneMsgShown; + void getAllContents(); + QDict contentList; + QPopupMenu *itemPopup; + QString cacheFilesPath; + QStringList keywordDocuments; +}; + +#endif diff --git a/tools/assistant/helpwindow.cpp b/tools/assistant/helpwindow.cpp new file mode 100644 index 0000000..e65b8e5 --- /dev/null +++ b/tools/assistant/helpwindow.cpp @@ -0,0 +1,282 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "helpwindow.h" +#include "mainwindow.h" +#include "tabbedbrowser.h" +#include "helpdialogimpl.h" +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(Q_OS_WIN32) +#include +#endif + +HelpWindow::HelpWindow( MainWindow *w, QWidget *parent, const char *name ) + : QTextBrowser( parent, name ), mw( w ), blockScroll( FALSE ), + shiftPressed( FALSE ), newWindow( FALSE ) +{ + connect(this, SIGNAL(forwardAvailable(bool)), this, SLOT(updateForward(bool))); + connect(this, SIGNAL(backwardAvailable(bool)), this, SLOT(updateBackward(bool))); +} + +void HelpWindow::setSource( const QString &name ) +{ + if ( name.isEmpty() ) + return; + + if (newWindow || shiftPressed) { + removeSelection(); + mw->saveSettings(); + mw->saveToolbarSettings(); + MainWindow *nmw = new MainWindow; + + QFileInfo currentInfo( source() ); + QFileInfo linkInfo( name ); + QString target = name; + if( linkInfo.isRelative() ) + target = currentInfo.dirPath( TRUE ) + "/" + name; + + nmw->setup(); + nmw->move( mw->geometry().topLeft() ); + if ( mw->isMaximized() ) + nmw->showMaximized(); + else + nmw->show(); + nmw->showLink( target ); + return; + } + + if ( name.left( 7 ) == "http://" || name.left( 6 ) == "ftp://" ) { + QString webbrowser = Config::configuration()->webBrowser(); + if ( webbrowser.isEmpty() ) { +#if defined(Q_OS_WIN32) + QT_WA( { + ShellExecute( winId(), 0, (TCHAR*)name.ucs2(), 0, 0, SW_SHOWNORMAL ); + } , { + ShellExecuteA( winId(), 0, name.local8Bit(), 0, 0, SW_SHOWNORMAL ); + } ); +#elif defined(Q_OS_MACX) + webbrowser = "/usr/bin/open"; +#else + int result = QMessageBox::information( mw, tr( "Help" ), + tr( "Currently no Web browser is selected.\nPlease use the settings dialog to specify one!\n" ), + "Open", "Cancel" ); + if ( result == 0 ) { + emit chooseWebBrowser(); + webbrowser = Config::configuration()->webBrowser(); + } +#endif + if ( webbrowser.isEmpty() ) + return; + } + QProcess *proc = new QProcess(this); + + proc->addArgument( webbrowser ); + QObject::connect(proc, SIGNAL(processExited()), proc, SLOT(deleteLater())); + proc->addArgument( name ); + proc->start(); + return; + } + + if ( name.right( 3 ) == "pdf" ) { + QString pdfbrowser = Config::configuration()->pdfReader(); + if ( pdfbrowser.isEmpty() ) { +#if defined(Q_OS_MACX) + pdfbrowser = "/usr/bin/open"; +#else + QMessageBox::information( mw, + tr( "Help" ), + tr( "No PDF Viewer has been specified\n" + "Please use the settings dialog to specify one!\n" ) ); + return; +#endif + } + QFileInfo info( pdfbrowser ); + if( !info.exists() ) { + QMessageBox::information( mw, + tr( "Help" ), + tr( "Qt Assistant is unable to start the PDF Viewer\n\n" + "%1\n\n" + "Please make sure that the executable exists and is located at\n" + "the specified location." ).arg( pdfbrowser ) ); + return; + } + QProcess *proc = new QProcess(this); + QObject::connect(proc, SIGNAL(processExited()), proc, SLOT(deleteLater())); + proc->addArgument( pdfbrowser ); + proc->addArgument( name ); + proc->start(); + + return; + } + + QUrl u( context(), name ); + if ( !u.isLocalFile() ) { + QMessageBox::information( mw, tr( "Help" ), tr( "Can't load and display non-local file\n" + "%1" ).arg( name ) ); + return; + } + + setText(""); + QTextBrowser::setSource( name ); +} + + +void HelpWindow::openLinkInNewWindow() +{ + if ( lastAnchor.isEmpty() ) + return; + newWindow = TRUE; + setSource(lastAnchor); + newWindow = FALSE; +} + +void HelpWindow::openLinkInNewWindow( const QString &link ) +{ + lastAnchor = link; + openLinkInNewWindow(); +} + +void HelpWindow::openLinkInNewPage() +{ + if( lastAnchor.isEmpty() ) + return; + mw->browsers()->newTab( lastAnchor ); + lastAnchor = QString::null; +} + +void HelpWindow::openLinkInNewPage( const QString &link ) +{ + lastAnchor = link; + openLinkInNewPage(); +} + +QPopupMenu *HelpWindow::createPopupMenu( const QPoint& pos ) +{ + QPopupMenu *m = new QPopupMenu(0); + lastAnchor = anchorAt( pos ); + if ( !lastAnchor.isEmpty() ) { + if ( lastAnchor.at( 0 ) == '#' ) { + QString src = source(); + int hsh = src.find( '#' ); + lastAnchor = ( hsh>=0 ? src.left( hsh ) : src ) + lastAnchor; + } + m->insertItem( tr("Open Link in New Window\tShift+LMB"), + this, SLOT( openLinkInNewWindow() ) ); + m->insertItem( tr("Open Link in New Tab"), + this, SLOT( openLinkInNewPage() ) ); + } + mw->actionNewWindow->addTo( m ); + mw->actionOpenPage->addTo( m ); + mw->actionClosePage->addTo( m ); + m->insertSeparator(); + mw->actionGoPrevious->addTo( m ); + mw->actionGoNext->addTo( m ); + mw->actionGoHome->addTo( m ); + m->insertSeparator(); + mw->actionZoomIn->addTo( m ); + mw->actionZoomOut->addTo( m ); + m->insertSeparator(); + mw->actionEditCopy->addTo( m ); + mw->actionEditFind->addTo( m ); + return m; +} + +void HelpWindow::blockScrolling( bool b ) +{ + blockScroll = b; +} + +void HelpWindow::ensureCursorVisible() +{ + if ( !blockScroll ) + QTextBrowser::ensureCursorVisible(); +} + +void HelpWindow::contentsMousePressEvent(QMouseEvent *e) +{ + shiftPressed = ( e->state() & ShiftButton ); + QTextBrowser::contentsMousePressEvent(e); +} + +void HelpWindow::keyPressEvent(QKeyEvent *e) +{ + shiftPressed = ( e->state() & ShiftButton ); + QTextBrowser::keyPressEvent(e); +} + +void HelpWindow::copy() +{ + if (textFormat() == PlainText) { + QTextEdit::copy(); + } else { + TextFormat oldTf = textFormat(); + setTextFormat(PlainText); + QString selectText = selectedText(); + selectText.replace("
", "\n"); + selectText.replace("\xa0", " "); + selectText.replace(">", ">"); + selectText.replace("<", "<"); + selectText.replace("&", "&"); + + QClipboard *cb = QApplication::clipboard(); + if (cb->supportsSelection()) + cb->setText(selectText, QClipboard::Selection); + cb->setText(selectText, QClipboard::Clipboard); + setTextFormat(oldTf); + } +} + +void HelpWindow::updateForward(bool fwd) +{ + fwdAvail = fwd; +} + +void HelpWindow::updateBackward(bool back) +{ + backAvail = back; +} diff --git a/tools/assistant/helpwindow.h b/tools/assistant/helpwindow.h new file mode 100644 index 0000000..c1e585a --- /dev/null +++ b/tools/assistant/helpwindow.h @@ -0,0 +1,87 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef HELPWINDOW_H +#define HELPWINDOW_H + +#include + +class MainWindow; +class QKeyEvent; +class QMime; +class QMouseEvent; + +class HelpWindow : public QTextBrowser +{ + Q_OBJECT +public: + HelpWindow( MainWindow *m, QWidget *parent = 0, const char *name = 0 ); + void setSource( const QString &name ); + QPopupMenu *createPopupMenu( const QPoint& pos ); + void blockScrolling( bool b ); + void openLinkInNewWindow( const QString &link ); + void openLinkInNewPage( const QString &link ); + void addMimePath( const QString &path ); + + void contentsMousePressEvent(QMouseEvent *e); + void keyPressEvent(QKeyEvent *); + + bool isBackwardAvailable() const { return backAvail; } + bool isForwardAvailable() const { return fwdAvail; } + +signals: + void chooseWebBrowser(); + +public slots: + void copy(); +protected slots: + void ensureCursorVisible(); + +private slots: + void openLinkInNewWindow(); + void openLinkInNewPage(); + void updateForward(bool); + void updateBackward(bool); + +private: + MainWindow *mw; + QString lastAnchor; + bool blockScroll; + bool shiftPressed; + bool newWindow; + QMimeSourceFactory *mimeSourceFactory; + bool fwdAvail; + bool backAvail; +}; + +#endif diff --git a/tools/assistant/images/addtab.png b/tools/assistant/images/addtab.png new file mode 100644 index 0000000..a88697f Binary files /dev/null and b/tools/assistant/images/addtab.png differ diff --git a/tools/assistant/images/appicon.png b/tools/assistant/images/appicon.png new file mode 100644 index 0000000..a50dc9c Binary files /dev/null and b/tools/assistant/images/appicon.png differ diff --git a/tools/assistant/images/assistant.png b/tools/assistant/images/assistant.png new file mode 100644 index 0000000..461b883 Binary files /dev/null and b/tools/assistant/images/assistant.png differ diff --git a/tools/assistant/images/book.png b/tools/assistant/images/book.png new file mode 100644 index 0000000..ede2b97 Binary files /dev/null and b/tools/assistant/images/book.png differ diff --git a/tools/assistant/images/closetab.png b/tools/assistant/images/closetab.png new file mode 100644 index 0000000..61ac034 Binary files /dev/null and b/tools/assistant/images/closetab.png differ diff --git a/tools/assistant/images/d_closetab.png b/tools/assistant/images/d_closetab.png new file mode 100644 index 0000000..f2ac158 Binary files /dev/null and b/tools/assistant/images/d_closetab.png differ diff --git a/tools/assistant/images/designer.png b/tools/assistant/images/designer.png new file mode 100644 index 0000000..d808332 Binary files /dev/null and b/tools/assistant/images/designer.png differ diff --git a/tools/assistant/images/editcopy.png b/tools/assistant/images/editcopy.png new file mode 100644 index 0000000..804c98c Binary files /dev/null and b/tools/assistant/images/editcopy.png differ diff --git a/tools/assistant/images/find.png b/tools/assistant/images/find.png new file mode 100644 index 0000000..8d73ab0 Binary files /dev/null and b/tools/assistant/images/find.png differ diff --git a/tools/assistant/images/home.png b/tools/assistant/images/home.png new file mode 100644 index 0000000..aa150a3 Binary files /dev/null and b/tools/assistant/images/home.png differ diff --git a/tools/assistant/images/linguist.png b/tools/assistant/images/linguist.png new file mode 100644 index 0000000..1021804 Binary files /dev/null and b/tools/assistant/images/linguist.png differ diff --git a/tools/assistant/images/next.png b/tools/assistant/images/next.png new file mode 100644 index 0000000..4b29ff4 Binary files /dev/null and b/tools/assistant/images/next.png differ diff --git a/tools/assistant/images/previous.png b/tools/assistant/images/previous.png new file mode 100644 index 0000000..4e3556c Binary files /dev/null and b/tools/assistant/images/previous.png differ diff --git a/tools/assistant/images/print.png b/tools/assistant/images/print.png new file mode 100644 index 0000000..cc083ed Binary files /dev/null and b/tools/assistant/images/print.png differ diff --git a/tools/assistant/images/qt.png b/tools/assistant/images/qt.png new file mode 100644 index 0000000..29a1fa8 Binary files /dev/null and b/tools/assistant/images/qt.png differ diff --git a/tools/assistant/images/splash.png b/tools/assistant/images/splash.png new file mode 100644 index 0000000..e121aa1 Binary files /dev/null and b/tools/assistant/images/splash.png differ diff --git a/tools/assistant/images/whatsthis.xpm b/tools/assistant/images/whatsthis.xpm new file mode 100644 index 0000000..799b599 --- /dev/null +++ b/tools/assistant/images/whatsthis.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *whatsthis[] = { +/* width height ncolors chars_per_pixel */ +"16 16 3 1", +/* colors */ +"# c None", +". c #000000", +"a c #000083", +/* pixels */ +".########aaaaa##", +"..######aaa#aaa#", +"...####aaa###aaa", +"....###aa#####aa", +".....##aa#####aa", +"......##a####aaa", +".......#####aaa#", +"........###aaa##", +".........#aaa###", +".....#####aaa###", +"..#...##########", +".##...####aaa###", +"####...###aaa###", +"####...#########", +"#####...########", +"#####...########" +}; diff --git a/tools/assistant/images/zoomin.png b/tools/assistant/images/zoomin.png new file mode 100644 index 0000000..667f2d6 Binary files /dev/null and b/tools/assistant/images/zoomin.png differ diff --git a/tools/assistant/images/zoomout.png b/tools/assistant/images/zoomout.png new file mode 100644 index 0000000..8755f4c Binary files /dev/null and b/tools/assistant/images/zoomout.png differ diff --git a/tools/assistant/index.cpp b/tools/assistant/index.cpp new file mode 100644 index 0000000..9e73ceb --- /dev/null +++ b/tools/assistant/index.cpp @@ -0,0 +1,526 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "index.h" + +#include +#include +#include +#include +#include + +#include + +int TermList::compareItems( QPtrCollection::Item i1, QPtrCollection::Item i2 ) +{ + if( ( (Term*)i1 )->frequency == ( (Term*)i2 )->frequency ) + return 0; + if( ( (Term*)i1 )->frequency < ( (Term*)i2 )->frequency ) + return -1; + return 1; +} + +QDataStream &operator>>( QDataStream &s, Document &l ) +{ + s >> l.docNumber; + s >> l.frequency; + return s; +} + +QDataStream &operator<<( QDataStream &s, const Document &l ) +{ + s << (Q_INT16)l.docNumber; + s << (Q_INT16)l.frequency; + return s; +} + +Index::Index( const QString &dp, const QString &hp ) + : QObject( 0, 0 ), dict( 8999 ), docPath( dp ) +{ + alreadyHaveDocList = FALSE; + lastWindowClosed = FALSE; + connect( qApp, SIGNAL( lastWindowClosed() ), + this, SLOT( setLastWinClosed() ) ); +} + +Index::Index( const QStringList &dl, const QString &hp ) + : QObject( 0, 0 ), dict( 8999 ) +{ + docList = dl; + alreadyHaveDocList = TRUE; + lastWindowClosed = FALSE; + connect( qApp, SIGNAL( lastWindowClosed() ), + this, SLOT( setLastWinClosed() ) ); +} + +void Index::setLastWinClosed() +{ + lastWindowClosed = TRUE; +} + +void Index::setDictionaryFile( const QString &f ) +{ + dictFile = f; +} + +void Index::setDocListFile( const QString &f ) +{ + docListFile = f; +} + +void Index::setDocList( const QStringList &lst ) +{ + docList = lst; +} + +int Index::makeIndex() +{ + if ( !alreadyHaveDocList ) + setupDocumentList(); + if ( docList.isEmpty() ) + return 1; + QStringList::Iterator it = docList.begin(); + int steps = docList.count() / 100; + if ( !steps ) + steps++; + int prog = 0; + for ( int i = 0; it != docList.end(); ++it, ++i ) { + if ( lastWindowClosed ) { + return -1; + } + parseDocument( *it, i ); + if ( i%steps == 0 ) { + prog++; + emit indexingProgress( prog ); + } + } + return 0; +} + +void Index::setupDocumentList() +{ + QDir d( docPath ); + QStringList lst = d.entryList( "*.html" ); + QStringList::ConstIterator it = lst.begin(); + for ( ; it != lst.end(); ++it ) + docList.append( docPath + "/" + *it ); +} + +void Index::insertInDict( const QString &str, int docNum ) +{ + if ( strcmp( str, "amp" ) == 0 || strcmp( str, "nbsp" ) == 0 ) + return; + Entry *e = 0; + if ( dict.count() ) + e = dict[ str ]; + + if ( e ) { + if ( e->documents.first().docNumber != docNum ) + e->documents.prepend( Document( docNum, 1 ) ); + else + e->documents.first().frequency++; + } else { + dict.insert( str, new Entry( docNum ) ); + } +} + +void Index::parseDocument( const QString &filename, int docNum ) +{ + QFile file( filename ); + if ( !file.open( IO_ReadOnly ) ) { + qWarning( "can not open file " + filename ); + return; + } + + QTextStream s( &file ); + QString text = s.read(); + if (text.isNull()) + return; + + bool valid = TRUE; + const QChar *buf = text.unicode(); + QChar str[64]; + QChar c = buf[0]; + int j = 0; + int i = 0; + while ( (uint)j < text.length() ) { + if ( c == '<' || c == '&' ) { + valid = FALSE; + if ( i > 1 ) + insertInDict( QString(str,i), docNum ); + i = 0; + c = buf[++j]; + continue; + } + if ( ( c == '>' || c == ';' ) && !valid ) { + valid = TRUE; + c = buf[++j]; + continue; + } + if ( !valid ) { + c = buf[++j]; + continue; + } + if ( ( c.isLetterOrNumber() || c == '_' ) && i < 63 ) { + str[i] = c.lower(); + ++i; + } else { + if ( i > 1 ) + insertInDict( QString(str,i), docNum ); + i = 0; + } + c = buf[++j]; + } + if ( i > 1 ) + insertInDict( QString(str,i), docNum ); + file.close(); +} + +void Index::writeDict() +{ + QDictIterator it( dict ); + QFile f( dictFile ); + if ( !f.open( IO_WriteOnly ) ) + return; + QDataStream s( &f ); + for( ; it.current(); ++it ) { + Entry *e = it.current(); + s << it.currentKey(); + s << e->documents; + } + f.close(); + writeDocumentList(); +} + +void Index::writeDocumentList() +{ + QFile f( docListFile ); + if ( !f.open( IO_WriteOnly ) ) + return; + QDataStream s( &f ); + s << docList; +} + +void Index::readDict() +{ + QFile f( dictFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + + dict.clear(); + QDataStream s( &f ); + QString key; + QValueList docs; + while ( !s.atEnd() ) { + s >> key; + s >> docs; + dict.insert( key, new Entry( docs ) ); + } + f.close(); + readDocumentList(); +} + +void Index::readDocumentList() +{ + QFile f( docListFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + QDataStream s( &f ); + s >> docList; +} + +QStringList Index::query( const QStringList &terms, const QStringList &termSeq, const QStringList &seqWords ) +{ + TermList termList; + + QStringList::ConstIterator it = terms.begin(); + for ( it = terms.begin(); it != terms.end(); ++it ) { + Entry *e = 0; + if ( (*it).contains( '*' ) ) { + QValueList wcts = setupDummyTerm( getWildcardTerms( *it ) ); + termList.append( new Term( "dummy", wcts.count(), wcts ) ); + } else if ( dict[ *it ] ) { + e = dict[ *it ]; + termList.append( new Term( *it, e->documents.count(), e->documents ) ); + } else { + return QStringList(); + } + } + termList.sort(); + + Term *minTerm = termList.first(); + if ( !termList.count() ) + return QStringList(); + termList.removeFirst(); + + QValueList minDocs = minTerm->documents; + QValueList::iterator C; + QValueList::ConstIterator It; + Term *t = termList.first(); + for ( ; t; t = termList.next() ) { + QValueList docs = t->documents; + C = minDocs.begin(); + while ( C != minDocs.end() ) { + bool found = FALSE; + for ( It = docs.begin(); It != docs.end(); ++It ) { + if ( (*C).docNumber == (*It).docNumber ) { + (*C).frequency += (*It).frequency; + found = TRUE; + break; + } + } + if ( !found ) + C = minDocs.remove( C ); + else + ++C; + } + } + + QStringList results; + qHeapSort( minDocs ); + if ( termSeq.isEmpty() ) { + for ( C = minDocs.begin(); C != minDocs.end(); ++C ) + results << docList[ (int)(*C).docNumber ]; + return results; + } + + QString fileName; + for ( C = minDocs.begin(); C != minDocs.end(); ++C ) { + fileName = docList[ (int)(*C).docNumber ]; + if ( searchForPattern( termSeq, seqWords, fileName ) ) + results << fileName; + } + return results; +} + +QString Index::getDocumentTitle( const QString &fileName ) +{ + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + qWarning( "cannot open file " + fileName ); + return fileName; + } + QTextStream s( &file ); + QString text = s.read(); + + int start = text.find( "", 0, FALSE ) + 7; + int end = text.find( "", 0, FALSE ); + + QString title = ( end - start <= 0 ? tr("Untitled") : text.mid( start, end - start ) ); + return title; +} + +QStringList Index::getWildcardTerms( const QString &term ) +{ + QStringList lst; + QStringList terms = split( term ); + QValueList::iterator iter; + + QDictIterator it( dict ); + for( ; it.current(); ++it ) { + int index = 0; + bool found = FALSE; + QString text( it.currentKey() ); + for ( iter = terms.begin(); iter != terms.end(); ++iter ) { + if ( *iter == "*" ) { + found = TRUE; + continue; + } + if ( iter == terms.begin() && (*iter)[0] != text[0] ) { + found = FALSE; + break; + } + index = text.find( *iter, index ); + if ( *iter == terms.last() && index != (int)text.length()-1 ) { + index = text.findRev( *iter ); + if ( index != (int)text.length() - (int)(*iter).length() ) { + found = FALSE; + break; + } + } + if ( index != -1 ) { + found = TRUE; + index += (*iter).length(); + continue; + } else { + found = FALSE; + break; + } + } + if ( found ) + lst << text; + } + + return lst; +} + +QStringList Index::split( const QString &str ) +{ + QStringList lst; + int j = 0; + int i = str.find( '*', j ); + + while ( i != -1 ) { + if ( i > j && i <= (int)str.length() ) { + lst << str.mid( j, i - j ); + lst << "*"; + } + j = i + 1; + i = str.find( '*', j ); + } + + int l = str.length() - 1; + if ( str.mid( j, l - j + 1 ).length() > 0 ) + lst << str.mid( j, l - j + 1 ); + + return lst; +} + +QValueList Index::setupDummyTerm( const QStringList &terms ) +{ + TermList termList; + QStringList::ConstIterator it = terms.begin(); + for ( ; it != terms.end(); ++it ) { + Entry *e = 0; + if ( dict[ *it ] ) { + e = dict[ *it ]; + termList.append( new Term( *it, e->documents.count(), e->documents ) ); + } + } + termList.sort(); + + QValueList maxList; + + if ( !termList.count() ) + return maxList; + maxList = termList.last()->documents; + termList.removeLast(); + + QValueList::iterator docIt; + Term *t = termList.first(); + while ( t ) { + QValueList docs = t->documents; + for ( docIt = docs.begin(); docIt != docs.end(); ++docIt ) { + if ( maxList.findIndex( *docIt ) == -1 ) + maxList.append( *docIt ); + } + t = termList.next(); + } + return maxList; +} + +void Index::buildMiniDict( const QString &str ) +{ + if ( miniDict[ str ] ) + miniDict[ str ]->positions.append( wordNum ); + ++wordNum; +} + +bool Index::searchForPattern( const QStringList &patterns, const QStringList &words, const QString &fileName ) +{ + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + qWarning( "cannot open file " + fileName ); + return FALSE; + } + + wordNum = 3; + miniDict.clear(); + QStringList::ConstIterator cIt = words.begin(); + for ( ; cIt != words.end(); ++cIt ) + miniDict.insert( *cIt, new PosEntry( 0 ) ); + + QTextStream s( &file ); + QString text = s.read(); + bool valid = TRUE; + const QChar *buf = text.unicode(); + QChar str[64]; + QChar c = buf[0]; + int j = 0; + int i = 0; + while ( (uint)j < text.length() ) { + if ( c == '<' || c == '&' ) { + valid = FALSE; + if ( i > 1 ) + buildMiniDict( QString(str,i) ); + i = 0; + c = buf[++j]; + continue; + } + if ( ( c == '>' || c == ';' ) && !valid ) { + valid = TRUE; + c = buf[++j]; + continue; + } + if ( !valid ) { + c = buf[++j]; + continue; + } + if ( ( c.isLetterOrNumber() || c == '_' ) && i < 63 ) { + str[i] = c.lower(); + ++i; + } else { + if ( i > 1 ) + buildMiniDict( QString(str,i) ); + i = 0; + } + c = buf[++j]; + } + if ( i > 1 ) + buildMiniDict( QString(str,i) ); + file.close(); + + QStringList::ConstIterator patIt = patterns.begin(); + QStringList wordLst; + QValueList a, b; + QValueList::iterator aIt; + for ( ; patIt != patterns.end(); ++patIt ) { + wordLst = QStringList::split( ' ', *patIt ); + a = miniDict[ wordLst[0] ]->positions; + for ( int j = 1; j < (int)wordLst.count(); ++j ) { + b = miniDict[ wordLst[j] ]->positions; + aIt = a.begin(); + while ( aIt != a.end() ) { + if ( b.find( *aIt + 1 ) != b.end() ) { + (*aIt)++; + ++aIt; + } else { + aIt = a.remove( aIt ); + } + } + } + } + if ( a.count() ) + return TRUE; + return FALSE; +} diff --git a/tools/assistant/index.h b/tools/assistant/index.h new file mode 100644 index 0000000..b3d2b5d --- /dev/null +++ b/tools/assistant/index.h @@ -0,0 +1,131 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef INDEX_H +#define INDEX_H + +#include +#include +#include +#include + +struct Document { + Document( int d, int f ) : docNumber( d ), frequency( f ) {} + Document() : docNumber( -1 ), frequency( 0 ) {} + bool operator==( const Document &doc ) const { + return docNumber == doc.docNumber; + } + bool operator<( const Document &doc ) const { + return frequency > doc.frequency; + } + bool operator<=( const Document &doc ) const { + return frequency >= doc.frequency; + } + bool operator>( const Document &doc ) const { + return frequency < doc.frequency; + } + Q_INT16 docNumber; + Q_INT16 frequency; +}; + +QDataStream &operator>>( QDataStream &s, Document &l ); +QDataStream &operator<<( QDataStream &s, const Document &l ); + +class Index : public QObject +{ + Q_OBJECT +public: + struct Entry { + Entry( int d ) { documents.append( Document( d, 1 ) ); } + Entry( QValueList l ) : documents( l ) {} + QValueList documents; + }; + struct PosEntry { + PosEntry( int p ) { positions.append( p ); } + QValueList positions; + }; + + Index( const QString &dp, const QString &hp ); + Index( const QStringList &dl, const QString &hp ); + void writeDict(); + void readDict(); + int makeIndex(); + QStringList query( const QStringList&, const QStringList&, const QStringList& ); + QString getDocumentTitle( const QString& ); + void setDictionaryFile( const QString& ); + void setDocListFile( const QString& ); + void setDocList( const QStringList & ); + +signals: + void indexingProgress( int ); + +private slots: + void setLastWinClosed(); + +private: + void setupDocumentList(); + void parseDocument( const QString&, int ); + void insertInDict( const QString&, int ); + void writeDocumentList(); + void readDocumentList(); + QStringList getWildcardTerms( const QString& ); + QStringList split( const QString& ); + QValueList setupDummyTerm( const QStringList& ); + bool searchForPattern( const QStringList&, const QStringList&, const QString& ); + void buildMiniDict( const QString& ); + QStringList docList; + QDict dict; + QDict miniDict; + uint wordNum; + QString docPath; + QString dictFile, docListFile; + bool alreadyHaveDocList; + bool lastWindowClosed; +}; + +struct Term { + Term( const QString &t, int f, QValueList l ) + : term( t ), frequency( f ), documents( l ) {} + QString term; + int frequency; + QValueListdocuments; +}; + +class TermList : public QPtrList +{ +public: + TermList() : QPtrList() {} + int compareItems( QPtrCollection::Item i1, QPtrCollection::Item i2 ); +}; + +#endif diff --git a/tools/assistant/lib/lib.pro b/tools/assistant/lib/lib.pro new file mode 100644 index 0000000..09beced --- /dev/null +++ b/tools/assistant/lib/lib.pro @@ -0,0 +1,23 @@ +TEMPLATE = lib +TARGET = qassistantclient +VERSION = 1.0 + +CONFIG += qt warn_on release +CONFIG += staticlib +CONFIG -= dll + +SOURCES = qassistantclient.cpp +HEADERS += $$QT_SOURCE_TREE/include/qassistantclient.h + + +DEFINES += QT_INTERNAL_NETWORK +include( ../../../src/qt_professional.pri ) + +DESTDIR = ../../../lib + +unix { + target.path=$$libs.path + QMAKE_CFLAGS += $$QMAKE_CFLAGS_SHLIB + QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SHLIB + INSTALLS += target +} diff --git a/tools/assistant/lib/qassistantclient.cpp b/tools/assistant/lib/qassistantclient.cpp new file mode 100644 index 0000000..8120cb6 --- /dev/null +++ b/tools/assistant/lib/qassistantclient.cpp @@ -0,0 +1,334 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the QAssistantClient library. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qassistantclient.h" + +#include +#include +#include +#include +#include + +class QAssistantClientPrivate +{ + friend class QAssistantClient; + QStringList arguments; +}; + +static QMap *dpointers = 0; + +static QAssistantClientPrivate *data( const QAssistantClient *client, bool create=FALSE ) +{ + if( !dpointers ) + dpointers = new QMap; + QAssistantClientPrivate *d = (*dpointers)[client]; + if( !d && create ) { + d = new QAssistantClientPrivate; + dpointers->insert( client, d ); + } + return d; +} + +/*! + \class QAssistantClient + \brief The QAssistantClient class provides a means of using Qt + Assistant as an application's help tool. + + Using Qt Assistant is simple: Create a QAssistantClient instance, + then call showPage() as often as necessary to show your help + pages. When you call showPage(), Qt Assistant will be launched if + it isn't already running. + + The QAssistantClient instance can open (openAssistant()) or close + (closeAssistant()) Qt Assistant whenever required. If Qt Assistant + is open, isOpen() returns TRUE. + + One QAssistantClient instance interacts with one Qt Assistant + instance, so every time you call openAssistant(), showPage() or + closeAssistant() they are applied to the particular Qt Assistant + instance associated with the QAssistantClient. + + When you call openAssistant() the assistantOpened() signal is + emitted. Similarly when closeAssistant() is called, + assistantClosed() is emitted. In either case, if an error occurs, + error() is emitted. + + This class is not included in the Qt library itself. To use it you + must link against \c libqassistantclient.a (Unix) or \c + qassistantclient.lib (Windows), which is built into \c INSTALL/lib + if you built the Qt tools (\c INSTALL is the directory where Qt is + installed). If you use qmake, then you can simply add the following + line to your pro file: + + \code + LIBS += -lqassistantclient + \endcode + + See also "Adding Documentation to Qt Assistant" in the \link + assistant.book Qt Assistant manual\endlink. +*/ + +/*! + \fn void QAssistantClient::assistantOpened() + + This signal is emitted when Qt Assistant is open and the + client-server communication is set up. +*/ + +/*! + \fn void QAssistantClient::assistantClosed() + + This signal is emitted when the connection to Qt Assistant is + closed. This happens when the user exits Qt Assistant, or when an + error in the server or client occurs, or if closeAssistant() is + called. +*/ + +/*! + \fn void QAssistantClient::error( const QString &msg ) + + This signal is emitted if Qt Assistant cannot be started or if an + error occurs during the initialization of the connection between + Qt Assistant and the calling application. The \a msg provides an + explanation of the error. +*/ + +/*! + Constructs an assistant client object. The \a path specifies the + path to the Qt Assistant executable. If \a path is an empty + string the system path (\c{%PATH%} or \c $PATH) is used. + + The assistant client object is a child of \a parent and is called + \a name. +*/ +QAssistantClient::QAssistantClient( const QString &path, QObject *parent, const char *name ) + : QObject( parent, name ), host ( "localhost" ) +{ + if ( path.isEmpty() ) + assistantCommand = "assistant"; + else { + QFileInfo fi( path ); + if ( fi.isDir() ) + assistantCommand = path + "/assistant"; + else + assistantCommand = path; + } + +#if defined(Q_OS_MACX) + assistantCommand += ".app/Contents/MacOS/assistant"; +#elif defined(Q_WS_WIN) + if (!assistantCommand.endsWith(".exe")) + assistantCommand += ".exe"; +#endif + socket = new QSocket( this ); + connect( socket, SIGNAL( connected() ), + SLOT( socketConnected() ) ); + connect( socket, SIGNAL( connectionClosed() ), + SLOT( socketConnectionClosed() ) ); + connect( socket, SIGNAL( error( int ) ), + SLOT( socketError( int ) ) ); + opened = FALSE; + proc = new QProcess( this ); + port = 0; + pageBuffer = ""; + connect( proc, SIGNAL( readyReadStderr() ), + this, SLOT( readStdError() ) ); +} + +/*! + Destroys the assistant client object and frees up all allocated + resources. +*/ +QAssistantClient::~QAssistantClient() +{ + if ( proc && proc->isRunning() ) { + proc->tryTerminate(); + proc->kill(); + } + + if( dpointers ) { + QAssistantClientPrivate *d = (*dpointers)[ this ]; + if( d ) { + dpointers->remove( this ); + delete d; + if( dpointers->isEmpty() ) { + delete dpointers; + dpointers = 0; + } + } + } +} + +/*! + This function opens Qt Assistant and sets up the client-server + communiction between the application and Qt Assistant. If it is + already open, this function does nothing. If an error occurs, + error() is emitted. + + \sa assistantOpened() +*/ +void QAssistantClient::openAssistant() +{ + if ( proc->isRunning() ) + return; + proc->clearArguments(); + proc->addArgument( assistantCommand ); + proc->addArgument( "-server" ); + if( !pageBuffer.isEmpty() ) { + proc->addArgument( "-file" ); + proc->addArgument( pageBuffer ); + } + + QAssistantClientPrivate *d = data( this ); + if( d ) { + QStringList::ConstIterator it = d->arguments.begin(); + while( it!=d->arguments.end() ) { + proc->addArgument( *it ); + ++it; + } + } + + if ( !proc->launch( QString::null ) ) { + emit error( tr( "Cannot start Qt Assistant '%1'" ) + .arg( proc->arguments().join( " " ) ) ); + return; + } + connect( proc, SIGNAL( readyReadStdout() ), + this, SLOT( readPort() ) ); +} + +void QAssistantClient::readPort() +{ + QString p = proc->readLineStdout(); + Q_UINT16 port = p.toUShort(); + if ( port == 0 ) { + emit error( tr( "Cannot connect to Qt Assistant." ) ); + return; + } + socket->connectToHost( host, port ); + disconnect( proc, SIGNAL( readyReadStdout() ), + this, SLOT( readPort() ) ); +} + +/*! + Use this function to close Qt Assistant. + + \sa assistantClosed() +*/ +void QAssistantClient::closeAssistant() +{ + if ( !opened ) + return; + proc->tryTerminate(); + proc->kill(); +} + +/*! + Call this function to make Qt Assistant show a particular \a page. + The \a page is a filename (e.g. \c myhelpfile.html). See "Adding + Documentation to Qt Assistant" in the \link assistant.book Qt + Assistant manual\endlink for further information. + + If Qt Assistant hasn't been \link openAssistant() opened\endlink + yet, this function will do nothing. You can use isOpen() to + determine whether Qt Assistant is up and running, or you can + connect to the asssistantOpened() signal. + + \sa isOpen(), assistantOpened() +*/ +void QAssistantClient::showPage( const QString &page ) +{ + if ( !opened ) { + pageBuffer = page; + openAssistant(); + pageBuffer = QString::null; + return; + } + QTextStream os( socket ); + os << page << "\n"; +} + +/*! + \property QAssistantClient::open + \brief Whether Qt Assistant is open. + +*/ +bool QAssistantClient::isOpen() const +{ + return opened; +} + +void QAssistantClient::socketConnected() +{ + opened = TRUE; + if ( !pageBuffer.isEmpty() ) + showPage( pageBuffer ); + emit assistantOpened(); +} + +void QAssistantClient::socketConnectionClosed() +{ + opened = FALSE; + emit assistantClosed(); +} + +void QAssistantClient::socketError( int i ) +{ + if ( i == QSocket::ErrConnectionRefused ) + emit error( tr( "Could not connect to Assistant: Connection refused" ) ); + else if ( i == QSocket::ErrHostNotFound ) + emit error( tr( "Could not connect to Assistant: Host not found" ) ); + else + emit error( tr( "Communication error" ) ); +} + +void QAssistantClient::readStdError() +{ + QString errmsg; + while ( proc->canReadLineStderr() ) { + errmsg += proc->readLineStderr(); + errmsg += "\n"; + } + if (!errmsg.isEmpty()) + emit error( tr( errmsg.simplifyWhiteSpace() ) ); +} + +/*! + Sets the command line arguments used when Qt Assistant is + started to \a args. +*/ +void QAssistantClient::setArguments( const QStringList &args ) +{ + QAssistantClientPrivate *d = data( this, TRUE ); + d->arguments = args; +} diff --git a/tools/assistant/lib/qassistantclient.h b/tools/assistant/lib/qassistantclient.h new file mode 100644 index 0000000..a05d291 --- /dev/null +++ b/tools/assistant/lib/qassistantclient.h @@ -0,0 +1,80 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the QAssistantClient library. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QASSISTANTCLIENT_H +#define QASSISTANTCLIENT_H + +#include + +class QSocket; +class QProcess; + +class QAssistantClient : public QObject +{ + Q_OBJECT + Q_PROPERTY( bool open READ isOpen ) + +public: + QAssistantClient( const QString &path, QObject *parent = 0, const char *name = 0 ); + ~QAssistantClient(); + + bool isOpen() const; + + void setArguments( const QStringList &args ); + +public slots: + virtual void openAssistant(); + virtual void closeAssistant(); + virtual void showPage( const QString &page ); + +signals: + void assistantOpened(); + void assistantClosed(); + void error( const QString &msg ); + +private slots: + void socketConnected(); + void socketConnectionClosed(); + void readPort(); + void socketError( int ); + void readStdError(); + +private: + QSocket *socket; + QProcess *proc; + Q_UINT16 port; + QString host, assistantCommand, pageBuffer; + bool opened; +}; + +#endif diff --git a/tools/assistant/main.cpp b/tools/assistant/main.cpp new file mode 100644 index 0000000..0619909 --- /dev/null +++ b/tools/assistant/main.cpp @@ -0,0 +1,342 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "mainwindow.h" +#include "helpdialogimpl.h" +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_WS_WIN +#define INDEX_CHECK( text ) if( i+1 >= argc ) { QMessageBox::information( 0, "Qt Assistant", text ); return 1; } +#else +#define INDEX_CHECK( text ) if( i+1 >= argc ) { fprintf( stderr, text "\n" ); return 1; } +#endif + +static bool allowFirstRun = TRUE; + +class AssistantSocket : public QSocket +{ + Q_OBJECT +public: + AssistantSocket( int sock, QObject *parent = 0 ); + ~AssistantSocket() {} + +signals: + void showLinkRequest( const QString& ); + +private slots: + void readClient(); + void connectionClosed(); +}; + + +class AssistantServer : public QServerSocket +{ + Q_OBJECT +public: + AssistantServer( QObject* parent = 0 ); + void newConnection( int socket ); + Q_UINT16 getPort() const; + +signals: + void showLinkRequest( const QString& ); + void newConnect(); + +private: + Q_UINT16 p; +}; + + +AssistantSocket::AssistantSocket( int sock, QObject *parent ) + : QSocket( parent, 0 ) +{ + connect( this, SIGNAL( readyRead() ), + SLOT( readClient() ) ); + connect( this, SIGNAL( connectionClosed() ), + SLOT( connectionClosed() ) ); + setSocket( sock ); +} + +void AssistantSocket::readClient() +{ + QString link = QString::null; + while ( canReadLine() ) + link = readLine(); + if ( !link.isNull() ) { + link = link.replace( "\n", "" ); + link = link.replace( "\r", "" ); + emit showLinkRequest( link ); + } +} + +void AssistantSocket::connectionClosed() +{ + delete this; +} + +AssistantServer::AssistantServer( QObject *parent ) + : QServerSocket( 0x7f000001, 0, 1, parent ) +{ + if ( !ok() ) { + QMessageBox::critical( 0, tr( "Qt Assistant" ), + tr( "Failed to bind to port %1" ).arg( port() ) ); + exit( 1 ); + } + p = port(); +} + +Q_UINT16 AssistantServer::getPort() const +{ + return p; +} + +void AssistantServer::newConnection( int socket ) +{ + AssistantSocket *as = new AssistantSocket( socket, this ); + connect( as, SIGNAL( showLinkRequest( const QString& ) ), + this, SIGNAL( showLinkRequest( const QString& ) ) ); + emit newConnect(); +} + +int main( int argc, char ** argv ) +{ + bool withGUI = TRUE; + if ( argc > 1 ) { + QString arg( argv[1] ); + arg = arg.lower(); + if ( arg == "-addcontentfile" + || arg == "-removecontentfile" +#ifndef Q_WS_WIN + || arg == "-help" +#endif + ) + withGUI = FALSE; + } + QApplication a(argc, argv, withGUI); + + QString resourceDir; + AssistantServer *as = 0; + QStringList catlist; + QString file, profileName, aDocPath; + bool server = FALSE; + bool hideSidebar = FALSE; + bool startClean = FALSE; + bool configLoaded = FALSE; + if ( argc == 2 ) { + if ( (argv[1])[0] != '-' ) + file = argv[1]; + } + if ( file.isEmpty() ) { + for ( int i = 1; i < argc; i++ ) { + if ( QString( argv[i] ).lower() == "-file" ) { + INDEX_CHECK( "Missing file argument!" ); + i++; + file = argv[i]; + } else if ( QString( argv[i] ).lower() == "-server" ) { + server = TRUE; + } else if ( QString( argv[i] ).lower() == "-profile" ) { + INDEX_CHECK( "Missing profile argument!" ); + profileName = argv[++i]; + } else if ( QString( argv[i] ).lower() == "-addcontentfile" ) { + INDEX_CHECK( "Missing content file!" ); + Config *c = Config::loadConfig( QString::null ); + QFileInfo file( argv[i+1] ); + if( !file.exists() ) { + fprintf( stderr, "Could not locate content file: '%s'\n", + file.absFilePath().latin1() ); + fflush( stderr ); + return 1; + } + DocuParser *parser = DocuParser::createParser( file.absFilePath() ); + if( parser ) { + QFile f( argv[i+1] ); + if( !parser->parse( &f ) ) { + fprintf( stderr, "Failed to parse file: '%s'\n, ", + file.absFilePath().latin1() ); + fflush( stderr ); + return 1; + } + parser->addTo( c->profile() ); + c->setDocRebuild( TRUE ); + c->save(); + } + return 0; + } else if ( QString( argv[i] ).lower() == "-removecontentfile" ) { + INDEX_CHECK( "Missing content file!" ); + Config *c = Config::loadConfig( QString::null ); + Profile *profile = c->profile(); + QStringList entries = profile->docs.grep(argv[i+1]); + if (entries.count() == 0) { + fprintf(stderr, "Could not locate content file: '%s'\n", + argv[i+1]); + fflush(stderr); + return 1; + } else if (entries.count() > 1) { + fprintf(stderr, "More than one entry matching file name found, " + "please specify full path to file"); + fflush(stderr); + return 1; + } else { + QFileInfo file(entries[0]); + if( !file.exists() ) { + fprintf( stderr, "Could not locate content file: '%s'\n", + file.absFilePath().latin1() ); + fflush( stderr ); + return 1; + } + profile->removeDocFileEntry( file.absFilePath() ); + c->setDocRebuild( TRUE ); + c->save(); + } + return 0; + } else if ( QString( argv[i] ).lower() == "-docpath" ) { + INDEX_CHECK( "Missing path!" ); + QDir dir( argv[i+1] ); + if ( dir.exists() ) { + Config *c = Config::loadConfig( QString::null ); + c->saveProfile(Profile::createDefaultProfile(dir.absPath())); + c->loadDefaultProfile(); + c->setDocRebuild( TRUE ); + c->save(); + configLoaded = TRUE; + ++i; + } else { + fprintf( stderr, "The specified path does not exist!\n"); + fflush( stderr ); + return 1; + } + } else if ( QString( argv[i] ).lower() == "-hidesidebar" ) { + hideSidebar = TRUE; + } else if ( QString( argv[i] ).lower() == "-help" ) { + QString helpText( "Usage: assistant [option]\n" + "Options:\n" + " -file Filename assistant opens the specified file\n" + " -server reads commands from a socket after\n" + " assistant has started\n" + " -profile fileName starts assistant and displays the\n" + " profile specified in the file fileName.\n" + " -addContentFile file adds the content file 'file' to the set of\n" + " documentation available by default\n" + " -removeContentFile file removes the content file 'file' from the\n" + " documentation available by default\n" + " -docPath path sets the Qt documentation root path to\n" + " 'path' and starts assistant\n" + " -hideSidebar assistant will hide the sidebar.\n" + " -resourceDir assistant will load translations from\n" + " this directory.\n" + " -help shows this help."); +#ifdef Q_WS_WIN + QMessageBox::information( 0, "Qt Assistant", "
" + helpText + "
" ); +#else + printf( "%s\n", helpText.latin1() ); +#endif + exit( 0 ); + } else if ( QString( argv[i] ).lower() == "-resourcedir" ) { + INDEX_CHECK( "Missing resource directory argument!" ); + resourceDir = QString( argv[++i] ); + } else { + fprintf( stderr, "Unrecognized option '%s'. Try -help to get help.\n", + argv[i] ); + fflush( stderr ); + return 1; + } + } + } + + if( resourceDir.isNull() ) + resourceDir = qInstallPathTranslations(); + + QTranslator translator( 0 ); + translator.load( QString("assistant_") + QTextCodec::locale(), resourceDir ); + a.installTranslator( &translator ); + + QTranslator qtTranslator( 0 ); + qtTranslator.load( QString("qt_") + QTextCodec::locale(), resourceDir ); + a.installTranslator( &qtTranslator ); + + + Config *conf = 0; + if (configLoaded) + conf = Config::configuration(); + else + conf = Config::loadConfig( profileName ); + if (!conf) { + fprintf( stderr, "Profile '%s' does not exist!\n", profileName.latin1() ); + fflush( stderr ); + return -1; + } + + bool max = conf->isMaximized(); + QStringList links = conf->source(); + conf->hideSideBar( hideSidebar ); + + QGuardedPtr mw = new MainWindow( 0, "Assistant" ); + + if ( server ) { + as = new AssistantServer(); + printf("%d\n", as->port() ); + fflush( stdout ); + as->connect( as, SIGNAL( showLinkRequest( const QString& ) ), + mw, SLOT( showLinkFromClient( const QString& ) ) ); + } + + if ( max ) + mw->showMaximized(); + else + mw->show(); + + if ( !file.isEmpty() ) + mw->showLink( file ); + else if ( file.isEmpty() ) + mw->showLinks( links ); + + a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); + + int appExec = a.exec(); + delete (MainWindow*)mw; + return appExec; +} + +#include "main.moc" diff --git a/tools/assistant/mainwindow.ui b/tools/assistant/mainwindow.ui new file mode 100644 index 0000000..5b6ddac --- /dev/null +++ b/tools/assistant/mainwindow.ui @@ -0,0 +1,670 @@ + +MainWindow +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + MainWindow + + + + 0 + 0 + 949 + 670 + + + + Qt Assistant by Trolltech + + + + + menubar + + + + 0 + 0 + 949 + 29 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Toolbar + + + Toolbar + + + + + + + + + + + + + + + + + goActionToolbar + + + Go + + + + + + + actionFilePrint + + + print.png + + + Print + + + &Print... + + + Print the currently displayed page. + + + Ctrl+P + + + + + actionFileExit + + + Exit + + + E&xit + + + Quit Qt Assistant. + + + Ctrl+Q + + + + + actionEditCopy + + + editcopy.png + + + Copy + + + &Copy + + + Copy the selected text to the clipboard. + + + Ctrl+C + + + + + actionEditFind + + + find.png + + + Find in Text + + + &Find in Text... + + + Open the Find dialog. Qt Assistant will search the currently displayed page for the text you enter. + + + Ctrl+F + + + + + actionEditFindAgain + + + Find &Next + + + Find Next + + + F3 + + + + + actionEditFindAgainPrev + + + Find &Previous + + + Find Previous + + + Shift+F3 + + + + + actionGoHome + + + home.png + + + Home + + + &Home + + + Go to the home page. Qt Assistant's home page is the Qt Reference Documentation. + + + Ctrl+Home + + + + + actionGoPrevious + + + previous.png + + + Previous + + + &Previous + + + Go to the previous page. + + + Alt+Left + + + + + actionGoNext + + + next.png + + + Next + + + &Next + + + Go to the next page. + + + Alt+Right + + + + + helpAbout_Qt_AssistantAction + + + About Qt Assistant + + + About Qt Assistant + + + Display further information about Qt Assistant. + + + + + actionAboutApplication + + + + + actionZoomIn + + + zoomin.png + + + Zoom in + + + Zoom &in + + + Zoom in on the document, i.e. increase the font size. + + + Ctrl++ + + + + + actionZoomOut + + + zoomout.png + + + Zoom out + + + Zoom &out + + + Zoom out on the document, i.e. decrease the font size. + + + Ctrl+- + + + + + actionSettings + + + Settings + + + &Settings... + + + Open the settings dialog. + + + + + actionNewWindow + + + New Window + + + New Window + + + Open a new window. + + + Ctrl+N + + + + + actionClose + + + Close + + + &Close + + + Close the current window. + + + + + actionAddBookmark + + + Add Bookmark + + + &Add Bookmark + + + Add the currently displayed page as a new bookmark. + + + + + actionHelpWhatsThis + + + whatsthis.xpm + + + What's This? + + + "What's This?" context sensitive help. + + + "What's This?" context sensitive help. + + + Shift+F1 + + + + + actionOpenPage + + + Add Tab + + + Ctrl+Alt+N + + + + + actionNextPage + + + Next Tab + + + Ctrl+Alt+Right + + + + + actionPrevPage + + + Previous Tab + + + Ctrl+Alt+Left + + + + + actionClosePage + + + Close Tab + + + Ctrl+Alt+Q + + + + + actionHelpAssistant + + + assistant.png + + + Qt Assistant Manual + + + F1 + + + + + + actionGoHome + activated() + MainWindow + goHome() + + + helpAbout_Qt_AssistantAction + activated() + MainWindow + about() + + + actionEditFind + activated() + MainWindow + find() + + + actionEditFindAgain + activated() + MainWindow + findAgain() + + + actionEditFindAgainPrev + activated() + MainWindow + findAgainPrev() + + + actionFilePrint + activated() + MainWindow + print() + + + actionSettings + activated() + MainWindow + showSettingsDialog() + + + actionNewWindow + activated() + MainWindow + newWindow() + + + actionClose + activated() + MainWindow + close() + + + actionHelpWhatsThis + activated() + MainWindow + whatsThis() + + + actionHelpAssistant + activated() + MainWindow + showAssistantHelp() + + + actionAboutApplication + activated() + MainWindow + aboutApplication() + + + + qtoolbutton.h + settingsdialogimpl.h + qmessagebox.h + qfontdatabase.h + qaccel.h + qcombobox.h + qpaintdevicemetrics.h + qsimplerichtext.h + qfileinfo.h + qtextstream.h + qdockwindow.h + stdlib.h + qmime.h + helpwindow.h + qstylesheet.h + qapplication.h + helpdialogimpl.h + qdir.h + qprinter.h + qpainter.h + qurl.h + qstatusbar.h + qlineedit.h + qsettings.h + qcheckbox.h + tabbedbrowser.h + qptrlist.h + qguardedptr.h + qmap.h + finddialog.h + qstringlist.h + helpwindow.h + mainwindow.ui.h + + + class SettingsDialog; + class HelpDialog; + class TabbedBrowser; + class QTimerEvent; + + + QPtrList<QAction> *goActions; + int setupCompleted:1; + TabbedBrowser *tabs; + SettingsDialog * settingsDia; + QMap<int, QString> bookmarks; + HelpDialog *helpDock; + QDockWindow *dw; + QGuardedPtr<FindDialog> findDialog; + static QPtrList<MainWindow> *windows; + QMap<QAction*,QString> *goActionDocFiles; + QStringList pendingLinks; + QPtrList<HelpWindow> pendingBrowsers + + + init() + setup() + destroy() + about() + aboutApplication() + find() + findAgain() + findAgainPrev() + goHome() + print() + updateBookmarkMenu() + setupBookmarkMenu() + showBookmark( int id ) + showLinkFromClient( const QString & link ) + showLink( const QString & link ) + showLinks( const QStringList & links ) + showQtHelp() + showSettingsDialog() + showWebBrowserSettings() + showSettingsDialog( int page ) + hide() + newWindow() + saveSettings() + saveToolbarSettings() + showSearchLink( const QString & link, const QStringList & terms ) + showGoActionLink() + showAssistantHelp() + updateProfileSettings() + backwardAvailable(bool) + forwardAvailable(bool) + browserTabChanged() + + + setupGoActions() + insertActionSeparator() + close( bool alsoDelete ) + browsers() + helpDialog() + timerEvent(QTimerEvent *) + + + + diff --git a/tools/assistant/mainwindow.ui.h b/tools/assistant/mainwindow.ui.h new file mode 100644 index 0000000..75acd89 --- /dev/null +++ b/tools/assistant/mainwindow.ui.h @@ -0,0 +1,698 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QPtrList *MainWindow::windows = 0; + +#if defined(Q_WS_WIN) +extern Q_EXPORT int qt_ntfs_permission_lookup; +#endif + +void MainWindow::init() +{ +#if defined(Q_WS_WIN) + // Workaround for QMimeSourceFactory failing in QFileInfo::isReadable() for + // certain user configs. See task: 34372 + qt_ntfs_permission_lookup = 0; +#endif + setupCompleted = FALSE; + + goActions = new QPtrList; + goActionDocFiles = new QMap; + goActions->setAutoDelete( TRUE ); + + if ( !windows ) + windows = new QPtrList; + windows->append( this ); + tabs = new TabbedBrowser( this, "qt_assistant_tabbedbrowser" ); + setCentralWidget( tabs ); + settingsDia = 0; + + Config *config = Config::configuration(); + + updateProfileSettings(); + + dw = new QDockWindow( QDockWindow::InDock, this ); + helpDock = new HelpDialog( dw, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + addDockWindow( dw, DockLeft ); + dw->setWidget( helpDock ); + dw->setCaption( "Sidebar" ); + dw->setFixedExtentWidth( 320 ); + + // read geometry configuration + setupGoActions(); + + if ( !config->isMaximized() ) { + QRect geom = config->geometry(); + if( geom.isValid() ) { + resize(geom.size()); + move(geom.topLeft()); + } + } + + QString mainWindowLayout = config->mainWindowLayout(); + + QTextStream ts( &mainWindowLayout, IO_ReadOnly ); + ts >> *this; + + if ( config->sideBarHidden() ) + dw->hide(); + + tabs->setup(); + QTimer::singleShot( 0, this, SLOT( setup() ) ); +#if defined(Q_OS_MACX) + // Use the same forward and backward browser shortcuts as Safari and Internet Explorer do + // on the Mac. This means that if you have access to one of those cool Intellimice, the thing + // works just fine, since that's how Microsoft hacked it. + actionGoPrevious->setAccel(QKeySequence(Qt::CTRL|Qt::Key_Left)); + actionGoNext->setAccel(QKeySequence(Qt::CTRL|Qt::Key_Right)); +#endif +} + +void MainWindow::setup() +{ + if( setupCompleted ) + return; + + qApp->setOverrideCursor( QCursor( Qt::WaitCursor ) ); + statusBar()->message( tr( "Initializing Qt Assistant..." ) ); + setupCompleted = TRUE; + helpDock->initialize(); + connect( actionGoPrevious, SIGNAL( activated() ), tabs, SLOT( backward() ) ); + connect( actionGoNext, SIGNAL( activated() ), tabs, SLOT( forward() ) ); + connect( actionEditCopy, SIGNAL( activated() ), tabs, SLOT( copy() ) ); + connect( actionFileExit, SIGNAL( activated() ), qApp, SLOT( closeAllWindows() ) ); + connect( actionAddBookmark, SIGNAL( activated() ), + helpDock, SLOT( addBookmark() ) ); + connect( helpDock, SIGNAL( showLink( const QString& ) ), + this, SLOT( showLink( const QString& ) ) ); + connect( helpDock, SIGNAL( showSearchLink( const QString&, const QStringList& ) ), + this, SLOT( showSearchLink( const QString&, const QStringList&) ) ); + + connect( bookmarkMenu, SIGNAL( activated( int ) ), + this, SLOT( showBookmark( int ) ) ); + connect( actionZoomIn, SIGNAL( activated() ), tabs, SLOT( zoomIn() ) ); + connect( actionZoomOut, SIGNAL( activated() ), tabs, SLOT( zoomOut() ) ); + + connect( actionOpenPage, SIGNAL( activated() ), tabs, SLOT( newTab() ) ); + connect( actionClosePage, SIGNAL( activated() ), tabs, SLOT( closeTab() ) ); + connect( actionNextPage, SIGNAL( activated() ), tabs, SLOT( nextTab() ) ); + connect( actionPrevPage, SIGNAL( activated() ), tabs, SLOT( previousTab() ) ); + + + +#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) + QAccel *acc = new QAccel( this ); +// acc->connectItem( acc->insertItem( Key_F5 ), browser, SLOT( reload() ) ); + acc->connectItem( acc->insertItem( QKeySequence("SHIFT+CTRL+=") ), actionZoomIn, SIGNAL(activated()) ); +#endif + + QAccel *a = new QAccel( this, dw ); + a->connectItem( a->insertItem( QAccel::stringToKey( tr("Ctrl+T") ) ), + helpDock, SLOT( toggleContents() ) ); + a->connectItem( a->insertItem( QAccel::stringToKey( tr("Ctrl+I") ) ), + helpDock, SLOT( toggleIndex() ) ); + a->connectItem( a->insertItem( QAccel::stringToKey( tr("Ctrl+B") ) ), + helpDock, SLOT( toggleBookmarks() ) ); + a->connectItem( a->insertItem( QAccel::stringToKey( tr("Ctrl+S") ) ), + helpDock, SLOT( toggleSearch() ) ); + + Config *config = Config::configuration(); + + setupBookmarkMenu(); + PopupMenu->insertItem( tr( "Vie&ws" ), createDockWindowMenu() ); + helpDock->tabWidget->setCurrentPage( config->sideBarPage() ); + + qApp->restoreOverrideCursor(); + actionGoPrevious->setEnabled( FALSE ); + actionGoNext->setEnabled( FALSE ); +} + +void MainWindow::setupGoActions() +{ + Config *config = Config::configuration(); + QStringList titles = config->docTitles(); + QAction *action = 0; + + static bool separatorInserted = FALSE; + + QAction *cur = goActions->first(); + while( cur ) { + cur->removeFrom( goMenu ); + cur->removeFrom( goActionToolbar ); + cur = goActions->next(); + } + goActions->clear(); + goActionDocFiles->clear(); + + int addCount = 0; + + QStringList::ConstIterator it = titles.begin(); + for ( ; it != titles.end(); ++it ) { + QString title = *it; + QPixmap pix = config->docIcon( title ); + if( !pix.isNull() ) { + if( !separatorInserted ) { + goMenu->insertSeparator(); + separatorInserted = TRUE; + } + action = new QAction( title, QIconSet( pix ), title, 0, 0 ); + action->addTo( goMenu ); + action->addTo( goActionToolbar ); + goActions->append( action ); + goActionDocFiles->insert( action, config->indexPage( title ) ); + connect( action, SIGNAL( activated() ), + this, SLOT( showGoActionLink() ) ); + ++addCount; + } + } + if( !addCount ) + goActionToolbar->hide(); + else + goActionToolbar->show(); + +} + +void MainWindow::browserTabChanged() +{ + if (tabs->currentBrowser()) { + actionGoPrevious->setEnabled(tabs->currentBrowser()->isBackwardAvailable()); + actionGoNext->setEnabled(tabs->currentBrowser()->isForwardAvailable()); + } +} + +bool MainWindow::insertActionSeparator() +{ + goMenu->insertSeparator(); + Toolbar->addSeparator(); + return TRUE; +} + +bool MainWindow::close( bool alsoDelete ) +{ + saveSettings(); + return QMainWindow::close( alsoDelete ); +} + +void MainWindow::destroy() +{ + windows->removeRef( this ); + if ( windows->isEmpty() ) { + delete windows; + windows = 0; + } + delete goActions; + delete goActionDocFiles; +} + +void MainWindow::about() +{ + QMessageBox box( this ); + box.setText( "
" + "

Version " + QString(QT_VERSION_STR) + "

" + "

Copyright (C) 2000-2008 Trolltech ASA. All rights reserved." + "

" + "

Qt Commercial Edition license holders: This program is" + " licensed to you under the terms of the Qt Commercial License" + " Agreement. For details, see the file LICENSE that came with" + " this software distribution.

" + "

Qt Open Source Edition users: This program is licensed to you" + " under the terms of the GNU General Public License Version 2." + " For details, see the file LICENSE.GPL that came with this" + " software distribution.

The program is provided AS IS" + " with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF" + " DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE." + "

" ); + box.setCaption( tr( "Qt Assistant" ) ); + box.setIcon( QMessageBox::NoIcon ); + box.exec(); +} + +void MainWindow::aboutApplication() +{ + QString url = Config::configuration()->aboutURL(); + if ( url == "about_qt" ) { + QMessageBox::aboutQt( this, "Qt Assistant" ); + return; + } + QString text; + QFile file( url ); + if( file.exists() && file.open( IO_ReadOnly ) ) + text = QString( file.readAll() ); + if( text.isNull() ) + text = tr( "Failed to open about application contents in file: '%1'" ).arg( url ); + + QMessageBox box( this ); + box.setText( text ); + box.setCaption( Config::configuration()->aboutApplicationMenuText() ); + box.setIcon( QMessageBox::NoIcon ); + box.exec(); +} + +void MainWindow::find() +{ + if ( !findDialog ) + findDialog = new FindDialog( this ); + findDialog->comboFind->setFocus(); + findDialog->comboFind->lineEdit()->setSelection( + 0, findDialog->comboFind->lineEdit()->text().length() ); + findDialog->show(); +} + +void MainWindow::findAgain() +{ + if (!findDialog || !findDialog->hasFindExpression()) { + find(); + return; + } + findDialog->doFind(TRUE); +} + +void MainWindow::findAgainPrev() +{ + if (!findDialog || !findDialog->hasFindExpression()) { + find(); + return; + } + findDialog->doFind(FALSE); +} + +void MainWindow::goHome() +{ + showLink( Config::configuration()->homePage() ); +} + +void MainWindow::print() +{ + QPrinter printer( QPrinter::HighResolution ); + printer.setFullPage( TRUE ); + if ( printer.setup( this ) ) { + QPainter p; + if ( !p.begin( &printer ) ) + return; + + qApp->setOverrideCursor( QCursor( Qt::WaitCursor ) ); + qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput ); + + QPaintDeviceMetrics metrics(p.device()); + QTextBrowser *browser = tabs->currentBrowser(); + int dpiy = metrics.logicalDpiY(); + int margin = (int) ( (2/2.54)*dpiy ); + QRect view( margin, + margin, + metrics.width() - 2 * margin, + metrics.height() - 2 * margin ); + QSimpleRichText richText( browser->text(), browser->QWidget::font(), browser->context(), + browser->styleSheet(), browser->mimeSourceFactory(), + view.height(), Qt::black, FALSE ); + richText.setWidth( &p, view.width() ); + int page = 1; + do { + qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput ); + + richText.draw( &p, margin, margin, view, palette().active() ); + view.moveBy( 0, view.height() ); + p.translate( 0 , -view.height() ); + p.drawText( view.right() - p.fontMetrics().width( QString::number(page) ), + view.bottom() + p.fontMetrics().ascent() + 5, QString::number(page) ); + if ( view.top() - margin >= richText.height() ) + break; + printer.newPage(); + page++; + } while (TRUE); + + qApp->eventLoop()->processEvents( QEventLoop::ExcludeUserInput ); + qApp->restoreOverrideCursor(); + } +} + +void MainWindow::updateBookmarkMenu() +{ + for ( MainWindow *mw = windows->first(); mw; mw = windows->next() ) + mw->setupBookmarkMenu(); +} + +void MainWindow::setupBookmarkMenu() +{ + bookmarkMenu->clear(); + bookmarks.clear(); + actionAddBookmark->addTo( bookmarkMenu ); + + QFile f( QDir::homeDirPath() + "/.assistant/bookmarks." + + Config::configuration()->profileName() ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + bookmarkMenu->insertSeparator(); + while ( !ts.atEnd() ) { + QString title = ts.readLine(); + QString link = ts.readLine(); + bookmarks.insert( bookmarkMenu->insertItem( title ), link ); + } +} + +void MainWindow::showBookmark( int id ) +{ + if ( bookmarks.find( id ) != bookmarks.end() ) + showLink( *bookmarks.find( id ) ); +} + +void MainWindow::showLinkFromClient( const QString &link ) +{ + setWindowState(windowState() & ~WindowMinimized); + raise(); + setActiveWindow(); + showLink( link ); +} + +void MainWindow::showLink( const QString &link ) +{ + if( link.isEmpty() ) { + qWarning( "The link is empty!" ); + } + + int find = link.find( '#' ); + QString name = find >= 0 ? link.left( find ) : link; + + QString absLink = link; + QFileInfo fi( name ); + if ( fi.isRelative() ) { + if ( find >= 0 ) + absLink = fi.absFilePath() + link.right( link.length() - find ); + else + absLink = fi.absFilePath(); + } + if( fi.exists() ) { + tabs->setSource( absLink ); + tabs->currentBrowser()->setFocus(); + } else { + // ### Default 404 site! + statusBar()->message( tr( "Failed to open link: '%1'" ).arg( link ), 5000 ); + tabs->currentBrowser()->setText( tr( "

The page could not be found!


" + "

'%1'

").arg( link ) ); + tabs->updateTitle( tr( "Error..." ) ); + } +} + +void MainWindow::showLinks( const QStringList &links ) +{ + if ( links.size() == 0 ) { + qWarning( "MainWindow::showLinks() - Empty link" ); + return; + } + + if ( links.size() == 1 ) { + showLink( links.first() ); + return; + } + + pendingLinks = links; + + QStringList::ConstIterator it = pendingLinks.begin(); + // Initial showing, The tab is empty so update that without creating it first + if ( tabs->currentBrowser()->source().isEmpty() ) { + pendingBrowsers.append(tabs->currentBrowser()); + tabs->setTitle(tabs->currentBrowser(), pendingLinks.first()); + } + ++it; + + while( it != pendingLinks.end() ) { + pendingBrowsers.append( tabs->newBackgroundTab(*it) ); + ++it; + } + + startTimer(50); + return; +} + +void MainWindow::timerEvent(QTimerEvent *e) +{ + QString link = pendingLinks.first(); + HelpWindow *win = pendingBrowsers.first(); + pendingLinks.pop_front(); + pendingBrowsers.removeFirst(); + if (pendingLinks.size() == 0) + killTimer(e->timerId()); + win->setSource(link); +} + +void MainWindow::showQtHelp() +{ + showLink( QString( qInstallPathDocs() ) + "/html/index.html" ); +} + +void MainWindow::showSettingsDialog() +{ + showSettingsDialog( -1 ); +} + +void MainWindow::showWebBrowserSettings() +{ + showSettingsDialog( 1 ); +} + +void MainWindow::showSettingsDialog( int page ) +{ + if ( !settingsDia ){ + settingsDia = new SettingsDialog( this ); + } + QFontDatabase fonts; + settingsDia->fontCombo->clear(); + settingsDia->fontCombo->insertStringList( fonts.families() ); + settingsDia->fontCombo->lineEdit()->setText( tabs->browserFont().family() ); + settingsDia->fixedfontCombo->clear(); + settingsDia->fixedfontCombo->insertStringList( fonts.families() ); + settingsDia->fixedfontCombo->lineEdit()->setText( tabs->styleSheet()->item( "pre" )->fontFamily() ); + settingsDia->linkUnderlineCB->setChecked( tabs->linkUnderline() ); + settingsDia->colorButton->setPaletteBackgroundColor( tabs->palette().color( QPalette::Active, QColorGroup::Link ) ); + if ( page != -1 ) + settingsDia->settingsTab->setCurrentPage( page ); + + int ret = settingsDia->exec(); + + if ( ret != QDialog::Accepted ) + return; + + QObjectList *lst = (QObjectList*)Toolbar->children(); + QObject *obj; + for ( obj = lst->last(); obj; obj = lst->prev() ) { + if ( obj->isA( "QToolBarSeparator" ) ) { + delete obj; + obj = 0; + break; + } + } + + setupGoActions(); + + QFont fnt( tabs->browserFont() ); + fnt.setFamily( settingsDia->fontCombo->currentText() ); + tabs->setBrowserFont( fnt ); + tabs->setLinkUnderline( settingsDia->linkUnderlineCB->isChecked() ); + + QPalette pal = tabs->palette(); + QColor lc = settingsDia->colorButton->paletteBackgroundColor(); + pal.setColor( QPalette::Active, QColorGroup::Link, lc ); + pal.setColor( QPalette::Inactive, QColorGroup::Link, lc ); + pal.setColor( QPalette::Disabled, QColorGroup::Link, lc ); + tabs->setPalette( pal ); + + QString family = settingsDia->fixedfontCombo->currentText(); + + QStyleSheet *sh = tabs->styleSheet(); + sh->item( "pre" )->setFontFamily( family ); + sh->item( "code" )->setFontFamily( family ); + sh->item( "tt" )->setFontFamily( family ); + tabs->currentBrowser()->setText( tabs->currentBrowser()->text() ); + showLink( tabs->currentBrowser()->source() ); +} + +void MainWindow::hide() +{ + saveToolbarSettings(); + QMainWindow::hide(); +} + +MainWindow* MainWindow::newWindow() +{ + saveSettings(); + saveToolbarSettings(); + MainWindow *mw = new MainWindow; + mw->move( geometry().topLeft() ); + if ( isMaximized() ) + mw->showMaximized(); + else + mw->show(); + mw->goHome(); + return mw; +} + +void MainWindow::saveSettings() +{ + Config *config = Config::configuration(); + config->setFontFamily( tabs->browserFont().family() ); + config->setFontSize( tabs->currentBrowser()->font().pointSize() ); + config->setFontFixedFamily( tabs->styleSheet()->item( "pre" )->fontFamily() ); + config->setLinkUnderline( tabs->linkUnderline() ); + config->setLinkColor( tabs->palette().color( QPalette::Active, QColorGroup::Link ).name() ); + config->setSideBarPage( helpDock->tabWidget->currentPageIndex() ); + config->setGeometry( QRect( x(), y(), width(), height() ) ); + config->setMaximized( isMaximized() ); + + // Create list of the tab urls + QStringList lst; + QPtrList browsers = tabs->browsers(); + HelpWindow *browser = browsers.first(); + while (browser) { + lst << browser->source(); + browser = browsers.next(); + } + config->setSource(lst); + config->save(); +} + +void MainWindow::saveToolbarSettings() +{ + QString mainWindowLayout; + QTextStream ts( &mainWindowLayout, IO_WriteOnly ); + ts << *this; + Config::configuration()->setMainWindowLayout( mainWindowLayout ); +} + +TabbedBrowser* MainWindow::browsers() +{ + return tabs; +} + +void MainWindow::showSearchLink( const QString &link, const QStringList &terms ) +{ + HelpWindow * hw = tabs->currentBrowser(); + hw->blockScrolling( TRUE ); + hw->setCursor( waitCursor ); + if ( hw->source() == link ) + hw->reload(); + else + showLink( link ); + hw->sync(); + hw->setCursor( arrowCursor ); + + hw->viewport()->setUpdatesEnabled( FALSE ); + int minPar = INT_MAX; + int minIndex = INT_MAX; + QStringList::ConstIterator it = terms.begin(); + for ( ; it != terms.end(); ++it ) { + int para = 0; + int index = 0; + bool found = hw->find( *it, FALSE, TRUE, TRUE, ¶, &index ); + while ( found ) { + if ( para < minPar ) { + minPar = para; + minIndex = index; + } + hw->setColor( red ); + found = hw->find( *it, FALSE, TRUE, TRUE ); + } + } + hw->blockScrolling( FALSE ); + hw->viewport()->setUpdatesEnabled( TRUE ); + hw->setCursorPosition( minPar, minIndex ); + hw->updateContents(); +} + + +void MainWindow::showGoActionLink() +{ + const QObject *origin = sender(); + if( !origin || + origin->metaObject()->className() != QString( "QAction" ) ) + return; + + QAction *action = (QAction*) origin; + QString docfile = *( goActionDocFiles->find( action ) ); + showLink( docfile ); +} + +void MainWindow::showAssistantHelp() +{ + showLink( Config::configuration()->assistantDocPath() + "/assistant.html" ); +} + +HelpDialog* MainWindow::helpDialog() +{ + return helpDock; +} + +void MainWindow::backwardAvailable( bool enable ) +{ + actionGoPrevious->setEnabled( enable ); +} + +void MainWindow::forwardAvailable( bool enable ) +{ + actionGoNext->setEnabled( enable ); +} + +void MainWindow::updateProfileSettings() +{ + Config *config = Config::configuration(); +#ifndef Q_WS_MACX + setIcon( config->applicationIcon() ); +#endif + helpMenu->clear(); + actionHelpAssistant->addTo( helpMenu ); + helpMenu->insertSeparator(); + helpAbout_Qt_AssistantAction->addTo( helpMenu ); + if ( !config->aboutApplicationMenuText().isEmpty() ) + actionAboutApplication->addTo( helpMenu ); + helpMenu->insertSeparator(); + actionHelpWhatsThis->addTo( helpMenu ); + + actionAboutApplication->setMenuText( config->aboutApplicationMenuText() ); + + if( !config->title().isNull() ) + setCaption( config->title() ); +} diff --git a/tools/assistant/profile.cpp b/tools/assistant/profile.cpp new file mode 100644 index 0000000..be83f2a --- /dev/null +++ b/tools/assistant/profile.cpp @@ -0,0 +1,124 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ +#include "profile.h" +#include +#include +#include +#include +#include + +#define QT_TITLE "Qt Reference Documentation" +#define DESIGNER_TITLE "Qt Designer Manual" +#define ASSISTANT_TITLE "Qt Assistant Manual" +#define LINGUIST_TITLE "Guide to the Qt Translation Tools" +#define QMAKE_TITLE "qmake User Guide" + +Profile *Profile::createDefaultProfile( const QString &docPath ) +{ + QString path = qInstallPathDocs(); + if ( !docPath.isEmpty() ) + path = docPath; + path = path + "/html/"; + Profile *profile = new Profile; + profile->valid = TRUE; + profile->type = DefaultProfile; + profile->props["name"] = "default"; + profile->props["applicationicon"] = "appicon.png"; + profile->props["aboutmenutext"] = "About Qt"; + profile->props["abouturl"] = "about_qt"; + profile->props["title"] = "Qt Assistant"; + profile->props["basepath"] = path; + profile->props["startpage"] = path + "index.html"; + + profile->addDCFTitle( path + "qt.dcf", QT_TITLE ); + profile->addDCFTitle( path + "designer.dcf", DESIGNER_TITLE ); + profile->addDCFTitle( path + "assistant.dcf", ASSISTANT_TITLE ); + profile->addDCFTitle( path + "linguist.dcf", LINGUIST_TITLE ); + profile->addDCFTitle( path + "qmake.dcf", QMAKE_TITLE ); + + profile->addDCFIcon( QT_TITLE, "qt.png" ); + profile->addDCFIcon( DESIGNER_TITLE, "designer.png" ); + profile->addDCFIcon( ASSISTANT_TITLE, "assistant.png" ); + profile->addDCFIcon( LINGUIST_TITLE, "linguist.png" ); + + profile->addDCFIndexPage( QT_TITLE, path + "index.html" ); + profile->addDCFIndexPage( DESIGNER_TITLE, path + "designer-manual.html" ); + profile->addDCFIndexPage( ASSISTANT_TITLE, path + "assistant.html" ); + profile->addDCFIndexPage( LINGUIST_TITLE, path + "linguist-manual.html" ); + profile->addDCFIndexPage( QMAKE_TITLE, path + "qmake-manual.html" ); + + profile->addDCFImageDir( QT_TITLE, "../../gif/" ); + profile->addDCFImageDir( DESIGNER_TITLE, "../../gif/" ); + profile->addDCFImageDir( ASSISTANT_TITLE, "../../gif/" ); + profile->addDCFImageDir( LINGUIST_TITLE, "../../gif/" ); + profile->addDCFImageDir( QMAKE_TITLE, "../../gif/" ); + + return profile; +} + + +Profile::Profile() + : valid( TRUE ), dparser( 0 ) +{ +} + + +void Profile::removeDocFileEntry( const QString &docfile ) +{ + docs.remove( docfile ); + + QStringList titles; + + for( QMap::Iterator it = dcfTitles.begin(); + it != dcfTitles.end(); ++it ) { + if( (*it) == docfile ) { + indexPages.remove( *it ); + icons.remove( *it ); + imageDirs.remove( *it ); + titles << it.key(); + } + } + + for( QStringList::ConstIterator title = titles.begin(); + title != titles.end(); ++title ) { + + dcfTitles.remove( *title ); + } + +#ifdef ASSISTANT_DEBUG + qDebug( "docs:\n - " + docs.join( "\n - " ) ); + qDebug( "titles:\n - " + titles.join( "\n - " ) ); + qDebug( "keys:\n - " + ( (QStringList*) &(dcfTitles.keys()) )->join( "\n - " ) ); + qDebug( "values:\n - " + ( (QStringList*) &(dcfTitles.values()) )->join( "\n - " ) ); +#endif +} diff --git a/tools/assistant/profile.h b/tools/assistant/profile.h new file mode 100644 index 0000000..dfa7159 --- /dev/null +++ b/tools/assistant/profile.h @@ -0,0 +1,130 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PROFILE_H +#define PROFILE_H + +#include +#include +#include +#include + +class DocuParser; + +class Profile +{ +public: + enum ProfileType { DefaultProfile, UserProfile }; + Profile(); + + inline bool isValid() const; + + inline void addDCF( const QString &docfile ); + inline void addDCFIcon( const QString title, const QString &icon ); + inline void addDCFIndexPage( const QString title, const QString &indexPage ); + inline void addDCFImageDir( const QString title, const QString &imgDir ); + inline void addDCFTitle( const QString &dcf, const QString &title ); + inline void addProperty( const QString &name, const QString &value ); + inline bool hasDocFile( const QString &docFile ); + void removeDocFileEntry( const QString &title ); + + inline ProfileType profileType() const { return type; } + inline void setProfileType( ProfileType t ) { type = t; } + + inline DocuParser *docuParser() const { return dparser; } + inline void setDocuParser( DocuParser *dp ) { dparser = dp; } + + static Profile* createDefaultProfile( const QString &docPath = QString::null ); + static QString makeRelativePath( const QString &base, const QString &path ); + + int valid:1; + ProfileType type; + DocuParser *dparser; + QMap props; + QMap icons; + QMap indexPages; + QMap imageDirs; + QMap dcfTitles; + QStringList docs; +}; + + +inline bool Profile::isValid() const +{ + return valid; +} + +inline void Profile::addDCFTitle(const QString &dcf, const QString &title) +{ + QString absdcf = QFileInfo(dcf).absFilePath(); + dcfTitles[title] = absdcf; + if (docs.contains(absdcf) == 0) + docs << absdcf; +} + +inline void Profile::addDCF( const QString &docfile ) +{ + if( !docs.contains( docfile ) == 0 ) + docs << docfile; +} + +inline void Profile::addDCFIcon( const QString docfile, + const QString &icon ) +{ + icons[docfile] = icon; +} + +inline void Profile::addDCFIndexPage( const QString title, + const QString &indexPage ) +{ + indexPages[title] = indexPage; +} + +inline void Profile::addDCFImageDir( const QString docfile, + const QString &imgDir ) +{ + imageDirs[docfile] = imgDir; +} + +inline void Profile::addProperty( const QString &name, + const QString &value ) +{ + props[name] = value; +} + +inline bool Profile::hasDocFile( const QString &name ) +{ + return docs.contains( name ) > 0; +} + +#endif diff --git a/tools/assistant/settingsdialog.ui b/tools/assistant/settingsdialog.ui new file mode 100644 index 0000000..0b949fe --- /dev/null +++ b/tools/assistant/settingsdialog.ui @@ -0,0 +1,516 @@ + +SettingsDialogBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + SettingsDialogBase + + + + 0 + 0 + 389 + 253 + + + + Qt Assistant - Settings + + + true + + + + unnamed + + + + settingsTab + + + + 5 + 5 + 0 + 0 + + + + + tab + + + &General + + + + unnamed + + + + Layout2 + + + + unnamed + + + + fixedfontCombo + + + + 7 + 0 + 0 + 0 + + + + true + + + + + TextLabel1 + + + Fix&ed font: + + + fixedfontCombo + + + + + TextLabel2 + + + Link color: + + + + + fontCombo + + + + 7 + 0 + 0 + 0 + + + + true + + + + + fontLabel + + + &Font: + + + fontCombo + + + + + linkUnderlineCB + + + &Underline links + + + true + + + + + colorButton + + + + 0 + 0 + 0 + 0 + + + + + 40 + 20 + + + + + 255 + 0 + 0 + + + + TabFocus + + + + + + + + + + + + tab + + + &Web + + + + unnamed + + + + Spacer11 + + + Vertical + + + Expanding + + + + 20 + 30 + + + + + + TextLabel1_3 + + + Web &Browser Application: + + + browserApp + + + + + Layout9 + + + + unnamed + + + + browserApp + + + + + buttonBrowse + + + + 1 + 0 + 0 + 0 + + + + + 30 + 32767 + + + + ... + + + + + + + TextLabel1_3_3 + + + &Home page + + + homePage + + + + + layout8 + + + + unnamed + + + + homePage + + + + + buttonHome + + + + 1 + 0 + 0 + 0 + + + + + 30 + 32767 + + + + ... + + + + + + + + + pdfTab + + + &PDF + + + + unnamed + + + + TextLabel1_3_2 + + + PDF &Application + + + pdfApp + + + + + spacer10 + + + Vertical + + + Expanding + + + + 20 + 81 + + + + + + layout9 + + + + unnamed + + + + pdfApp + + + + + buttonPDF + + + + 1 + 0 + 0 + 0 + + + + + 30 + 32767 + + + + ... + + + + + + + + + + Layout1 + + + + unnamed + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 0 + 20 + + + + + + buttonOk + + + &OK + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + true + + + + + + + + + buttonOk + clicked() + SettingsDialogBase + accept() + + + buttonCancel + clicked() + SettingsDialogBase + reject() + + + colorButton + clicked() + SettingsDialogBase + selectColor() + + + buttonBrowse + clicked() + SettingsDialogBase + browseWebApp() + + + buttonHome + clicked() + SettingsDialogBase + browseHomepage() + + + buttonPDF + clicked() + SettingsDialogBase + browsePDFApplication() + + + + settingsTab + fontCombo + fixedfontCombo + colorButton + linkUnderlineCB + browserApp + buttonBrowse + homePage + buttonHome + pdfApp + buttonPDF + buttonOk + buttonCancel + + + selectColor() + browseWebApp() + browsePDFApplication() + browseHomepage() + + + diff --git a/tools/assistant/settingsdialogimpl.cpp b/tools/assistant/settingsdialogimpl.cpp new file mode 100644 index 0000000..0d3ebea --- /dev/null +++ b/tools/assistant/settingsdialogimpl.cpp @@ -0,0 +1,122 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "settingsdialogimpl.h" +#include "docuparser.h" +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +SettingsDialog::SettingsDialog( QWidget *parent, const char* name ) + : SettingsDialogBase( parent, name ) +{ + init(); +} + +void SettingsDialog::init() +{ + Config *config = Config::configuration(); + + browserApp->setText( config->webBrowser() ); + homePage->setText( config->homePage() ); + pdfApp->setText( config->pdfReader() ); +} + +void SettingsDialog::selectColor() +{ + QColor c = QColorDialog::getColor( colorButton->paletteBackgroundColor(), this ); + colorButton->setPaletteBackgroundColor( c ); +} + +void SettingsDialog::browseWebApp() +{ + setFile( browserApp, tr( "Qt Assistant - Set Web Browser" ) ); +} + +void SettingsDialog::browsePDFApplication() +{ + setFile( pdfApp, tr( "Qt Assistant - Set PDF Browser" ) ); +} + +void SettingsDialog::browseHomepage() +{ + setFile( homePage, tr( "Qt Assistant - Set Homepage" ) ); +} + +void SettingsDialog::setFile( QLineEdit *le, const QString &caption ) +{ + QFileDialog *fd = new QFileDialog( this ); + fd->setCaption( caption ); + fd->setMode( QFileDialog::AnyFile ); + fd->setDir( QDir::homeDirPath() ); + + if ( fd->exec() == QDialog::Accepted ) { + if ( !fd->selectedFile().isEmpty() ) + le->setText( fd->selectedFile() ); + } +} + +void SettingsDialog::accept() +{ + Config *config = Config::configuration(); + + config->setWebBrowser( browserApp->text() ); + config->setHomePage( homePage->text() ); + config->setPdfReader( pdfApp->text() ); + + hide(); + done( Accepted ); +} + +void SettingsDialog::reject() +{ + init(); + done( Rejected ); +} diff --git a/tools/assistant/settingsdialogimpl.h b/tools/assistant/settingsdialogimpl.h new file mode 100644 index 0000000..12ddc6c --- /dev/null +++ b/tools/assistant/settingsdialogimpl.h @@ -0,0 +1,63 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SETTINGSDIALOGIMPL_H +#define SETTINGSDIALOGIMPL_H + +#include "settingsdialog.h" + +#include +#include +#include + +class SettingsDialog : public SettingsDialogBase +{ + Q_OBJECT + +public: + SettingsDialog( QWidget *parent, const char* name = 0 ); + +protected slots: + void selectColor(); + void browseWebApp(); + void browsePDFApplication(); + void browseHomepage(); + void accept(); + void reject(); + +private: + void init(); + void setFile( QLineEdit *le, const QString &caption ); +}; + +#endif diff --git a/tools/assistant/tabbedbrowser.ui b/tools/assistant/tabbedbrowser.ui new file mode 100644 index 0000000..10affc8 --- /dev/null +++ b/tools/assistant/tabbedbrowser.ui @@ -0,0 +1,141 @@ + +TabbedBrowser +********************************************************************* +** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + TabbedBrowser + + + + 0 + 0 + 710 + 681 + + + + TabbedBrowser + + + + unnamed + + + 0 + + + 0 + + + + tab + + + + frontpage + + + Untitled + + + + unnamed + + + + + + + + qsettings.h + helpwindow.h + mainwindow.h + qstylesheet.h + qmime.h + tabbedbrowser.ui.h + + + class HelpWindow; + class MainWindow; + class QStyleSheet; + class QMimeSourceFactory; + + + QStyleSheet *tabStyleSheet; + bool tabLinkUnderline; + QMimeSourceFactory *mimeSourceFactory; + QWidget *lastCurrentTab; + QFont tabFont; + + + forward() + backward() + setSource( const QString & ref ) + reload() + home() + nextTab() + previousTab() + newTab( const QString & lnk ) + zoomIn() + zoomOut() + updateTitle( const QString & title ) + newTab() + transferFocus() + initHelpWindow( HelpWindow * win ) + setup() + setLinkUnderline( bool uline ) + setPalette( const QPalette & pal ) + copy() + closeTab() + sourceChanged() + + + currentBrowser() + init() + mainWindow() + styleSheet() + linkUnderline() + sources() + setMimePath( QStringList lst ) + setMimeExtension( const QString & ext ) + setBrowserFont( const QFont & fnt ) + browserFont() + browsers() const + newBackgroundTab( const QString & url ) + createHelpWindow(const QString &) + setTitle(HelpWindow*, const QString &) + + + + diff --git a/tools/assistant/tabbedbrowser.ui.h b/tools/assistant/tabbedbrowser.ui.h new file mode 100644 index 0000000..bb7fd61 --- /dev/null +++ b/tools/assistant/tabbedbrowser.ui.h @@ -0,0 +1,347 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** Qt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "config.h" + +static QString reduceLabelLength( const QString &s ) +{ + uint maxLength = 16; + QString str = s; + if ( str.length() < maxLength ) + return str; + str = str.left( maxLength - 3 ); + str += "..."; + return str; +} + +void TabbedBrowser::forward() +{ + currentBrowser()->forward(); +} + +void TabbedBrowser::backward() +{ + currentBrowser()->backward(); +} + +void TabbedBrowser::setSource( const QString &ref ) +{ + HelpWindow * win = currentBrowser(); + win->setSource(ref); +} + +void TabbedBrowser::reload() +{ + currentBrowser()->reload(); +} + +void TabbedBrowser::home() +{ + currentBrowser()->home(); +} + +HelpWindow * TabbedBrowser::currentBrowser() +{ + return (HelpWindow*) tab->currentPage(); +} + +void TabbedBrowser::nextTab() +{ + if( tab->currentPageIndex()<=tab->count()-1 ) + tab->setCurrentPage( tab->currentPageIndex()+1 ); +} + +void TabbedBrowser::previousTab() +{ + int idx = tab->currentPageIndex()-1; + if( idx>=0 ) + tab->setCurrentPage( idx ); +} + +HelpWindow *TabbedBrowser::createHelpWindow(const QString &title) +{ + MainWindow *mainWin = mainWindow(); + HelpWindow *win = new HelpWindow( mainWin, this, "qt_assistant_helpwin" ); + win->setFont( browserFont() ); + win->setPalette( palette() ); + win->setLinkUnderline( tabLinkUnderline ); + win->setStyleSheet( tabStyleSheet ); + win->setMimeSourceFactory( mimeSourceFactory ); + tab->addTab(win, reduceLabelLength(title)); + connect( win, SIGNAL( highlighted( const QString & ) ), + (const QObject*) (mainWin->statusBar()), SLOT( message( const QString & ) ) ); + connect( win, SIGNAL( chooseWebBrowser() ), mainWin, SLOT( showWebBrowserSettings() ) ); + connect( win, SIGNAL( backwardAvailable(bool) ), + mainWin, SLOT( backwardAvailable(bool) ) ); + connect( win, SIGNAL( forwardAvailable(bool) ), + mainWin, SLOT( forwardAvailable(bool) ) ); + connect( win, SIGNAL( sourceChanged(const QString &) ), this, SLOT( sourceChanged() )); + + tab->cornerWidget( Qt::TopRight )->setEnabled( tab->count() > 1 ); + return win; +} + +HelpWindow *TabbedBrowser::newBackgroundTab( const QString &url ) +{ + HelpWindow *win = createHelpWindow(url); + return win; +} + +void TabbedBrowser::newTab( const QString &lnk ) +{ + QString link( lnk ); + if( link.isNull() ) { + HelpWindow *w = currentBrowser(); + if( w ) + link = w->source(); + } + HelpWindow *win = createHelpWindow(link); + tab->showPage( win ); + if( !link.isNull() ) { + win->setSource( link ); + } +} + +void TabbedBrowser::zoomIn() +{ + currentBrowser()->zoomIn(); +} + +void TabbedBrowser::zoomOut() +{ + currentBrowser()->zoomOut(); +} + +void TabbedBrowser::init() +{ + tabLinkUnderline = FALSE; + tabStyleSheet = new QStyleSheet( QStyleSheet::defaultSheet() ); + lastCurrentTab = 0; + while( tab->count() ) + tab->removePage( tab->page(0) ); + + mimeSourceFactory = new QMimeSourceFactory(); + mimeSourceFactory->setExtensionType("html","text/html;charset=UTF-8"); + mimeSourceFactory->setExtensionType("htm","text/html;charset=UTF-8"); + mimeSourceFactory->setExtensionType("png", "image/png" ); + mimeSourceFactory->setExtensionType("jpg", "image/jpeg" ); + mimeSourceFactory->setExtensionType("jpeg", "image/jpeg" ); + setMimePath( Config::configuration()->mimePaths() ); + + connect( tab, SIGNAL( currentChanged( QWidget* ) ), + this, SLOT( transferFocus() ) ); + connect( tab, SIGNAL( currentChanged( QWidget* ) ), + mainWindow(), SLOT( browserTabChanged() ) ); + + QTabBar *tabBar = (QTabBar*)tab->child( 0, "QTabBar", FALSE ); + int m = ( tabBar ? style().pixelMetric( QStyle::PM_TabBarTabVSpace, (QWidget*)tabBar ) + + style().pixelMetric( QStyle::PM_TabBarBaseHeight, (QWidget*)tabBar ) : 0 ); + int s = tab->height() - m; + + // workaround for sgi style + QPalette pal = palette(); + pal.setColor(QPalette::Active, QColorGroup::Button, pal.active().background()); + pal.setColor(QPalette::Disabled, QColorGroup::Button, pal.disabled().background()); + pal.setColor(QPalette::Inactive, QColorGroup::Button, pal.inactive().background()); + + QToolButton *newTabButton = new QToolButton( this ); + newTabButton->setPalette(pal); + tab->setCornerWidget( newTabButton, Qt::TopLeft ); + newTabButton->setCursor( arrowCursor ); + newTabButton->setAutoRaise( TRUE ); + newTabButton->setPixmap( QPixmap::fromMimeSource( "addtab.png" ) ); + newTabButton->setFixedSize( s, s ); + QObject::connect( newTabButton, SIGNAL( clicked() ), this, SLOT( newTab() ) ); + QToolTip::add( newTabButton, tr( "Add page" ) ); + + QToolButton *closeTabButton = new QToolButton( this ); + closeTabButton->setPalette(pal); + tab->setCornerWidget( closeTabButton, Qt::TopRight ); + closeTabButton->setCursor( arrowCursor ); + closeTabButton->setAutoRaise( TRUE ); + QIconSet is( QPixmap::fromMimeSource( "closetab.png") ); + QPixmap disabledPix = QPixmap::fromMimeSource( "d_closetab.png" ); + is.setPixmap( disabledPix, QIconSet::Small, QIconSet::Disabled ); + closeTabButton->setIconSet( is ); + closeTabButton->setFixedSize( s, s ); + QObject::connect( closeTabButton, SIGNAL( clicked() ), this, SLOT( closeTab() ) ); + QToolTip::add( closeTabButton, tr( "Close page" ) ); + closeTabButton->setEnabled( FALSE ); +} + +void TabbedBrowser::setMimePath( QStringList lst ) +{ + mimeSourceFactory->setFilePath( lst ); +} + +void TabbedBrowser::setMimeExtension( const QString &ext ) +{ + mimeSourceFactory->setExtensionType( "html", ext ); + mimeSourceFactory->setExtensionType( "htm", ext ); +} + +void TabbedBrowser::updateTitle( const QString &title ) +{ + tab->changeTab( currentBrowser(), title ); +} + +MainWindow* TabbedBrowser::mainWindow() +{ + return (MainWindow*) parent(); +} + +void TabbedBrowser::newTab() +{ + newTab( QString::null ); +} + +void TabbedBrowser::transferFocus() +{ + if( currentBrowser() ) { + currentBrowser()->setFocus(); + } + mainWindow()->setCaption(Config::configuration()->title() + + " - " + currentBrowser()->documentTitle()); +} + +void TabbedBrowser::initHelpWindow( HelpWindow * /*win*/ ) +{ +} + +void TabbedBrowser::setup() +{ + Config *config = Config::configuration(); + + QFont fnt( font() ); + QFontInfo fntInfo( fnt ); + fnt.setFamily( config->fontFamily() ); + fnt.setPointSize( config->fontSize() ); + setBrowserFont( fnt ); + + QPalette pal = palette(); + QColor lc( config->linkColor() ); + pal.setColor( QPalette::Active, QColorGroup::Link, lc ); + pal.setColor( QPalette::Inactive, QColorGroup::Link, lc ); + pal.setColor( QPalette::Disabled, QColorGroup::Link, lc ); + setPalette( pal ); + + tabLinkUnderline = config->isLinkUnderline(); + + QString family = config->fontFixedFamily(); + tabStyleSheet->item( "pre" )->setFontFamily( family ); + tabStyleSheet->item( "code" )->setFontFamily( family ); + tabStyleSheet->item( "tt" )->setFontFamily( family ); + + newTab( QString::null ); +} + +void TabbedBrowser::setLinkUnderline( bool uline ) +{ + if( uline==tabLinkUnderline ) + return; + tabLinkUnderline = uline; + int cnt = tab->count(); + for( int i=0; ipage( i ) )->setLinkUnderline( tabLinkUnderline ); +} + +QFont TabbedBrowser::browserFont() +{ + return tabFont; +} + +void TabbedBrowser::setBrowserFont( const QFont &fnt ) +{ + if( tabFont == fnt ) + return; + tabFont = fnt; + int cnt = tab->count(); + for( int i=0; ipage( i ) )->setFont( fnt ); +} + +void TabbedBrowser::setPalette( const QPalette &pal ) +{ + if( palette()==pal ) + return; + QWidget::setPalette( pal ); + int cnt = tab->count(); + for( int i=0; ipage( i ) )->setPalette( pal ); +} + +QStyleSheet* TabbedBrowser::styleSheet() +{ + return tabStyleSheet; +} + +bool TabbedBrowser::linkUnderline() +{ + return tabLinkUnderline; +} + +void TabbedBrowser::copy() +{ + currentBrowser()->copy(); +} + +void TabbedBrowser::closeTab() +{ + if( tab->count()==1 ) + return; + HelpWindow *win = currentBrowser(); + tab->removePage( win ); + QTimer::singleShot(0, win, SLOT(deleteLater())); + tab->cornerWidget( Qt::TopRight )->setEnabled( tab->count() > 1 ); +} + +QStringList TabbedBrowser::sources() +{ + QStringList lst; + int cnt = tab->count(); + for( int i=0; ipage(i) )->source() ); + } + return lst; +} + +QPtrList TabbedBrowser::browsers() const +{ + QPtrList list; + for (int i=0; icount(); ++i) { + Q_ASSERT(::qt_cast(tab->page(i))); + list.append(::qt_cast(tab->page(i))); + } + return list; +} + +void TabbedBrowser::sourceChanged() +{ + HelpWindow *win = ::qt_cast( QObject::sender() ); + Q_ASSERT( win ); + QString docTitle(win->documentTitle()); + if (docTitle.isEmpty()) + docTitle = "..."; + setTitle(win, docTitle); +} + +void TabbedBrowser::setTitle(HelpWindow *win, const QString &title) +{ + tab->setTabLabel(win, reduceLabelLength(title)); + if (win == currentBrowser()) + mainWindow()->setCaption(Config::configuration()->title() + " - " + title); +} + diff --git a/tools/assistant/topicchooser.ui b/tools/assistant/topicchooser.ui new file mode 100644 index 0000000..d87f2c9 --- /dev/null +++ b/tools/assistant/topicchooser.ui @@ -0,0 +1,182 @@ + +TopicChooserBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + TopicChooserBase + + + + 0 + 0 + 391 + 223 + + + + Choose Topic + + + true + + + Select a topic from the list and click the <b>Display</b>-button to open the online help. + + + + unnamed + + + 11 + + + 6 + + + + label + + + &Topics + + + listbox + + + + + listbox + + + Displays a list of available help topics for the keyword. + + + + + Layout16 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonDisplay + + + &Display + + + true + + + true + + + Open the topic selected in the list. + + + + + buttonCancel + + + &Close + + + true + + + Close the Dialog. + + + + + + + + + buttonDisplay + clicked() + TopicChooserBase + accept() + + + buttonCancel + clicked() + TopicChooserBase + reject() + + + listbox + doubleClicked(QListBoxItem*) + TopicChooserBase + accept() + + + listbox + returnPressed(QListBoxItem*) + TopicChooserBase + accept() + + + + init() + destroy() + + + diff --git a/tools/assistant/topicchooserimpl.cpp b/tools/assistant/topicchooserimpl.cpp new file mode 100644 index 0000000..799a894 --- /dev/null +++ b/tools/assistant/topicchooserimpl.cpp @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "topicchooserimpl.h" + +#include +#include +#include + +TopicChooser::TopicChooser( QWidget *parent, const QStringList &lnkNames, + const QStringList &lnks, const QString &title ) + : TopicChooserBase( parent, 0, TRUE ), links( lnks ), linkNames( lnkNames ) +{ + label->setText( tr( "Choose a topic for %1" ).arg( title ) ); + listbox->insertStringList( linkNames ); + listbox->setCurrentItem( listbox->firstItem() ); + listbox->setFocus(); +} + +QString TopicChooser::link() const +{ + if ( listbox->currentItem() == -1 ) + return QString::null; + QString s = listbox->currentText(); + if ( s.isEmpty() ) + return s; + int i = linkNames.findIndex( s ); + return links[ i ]; +} + +QString TopicChooser::getLink( QWidget *parent, const QStringList &lnkNames, + const QStringList &lnks, const QString &title ) +{ + TopicChooser *dlg = new TopicChooser( parent, lnkNames, lnks, title ); + QString lnk; + if ( dlg->exec() == QDialog::Accepted ) + lnk = dlg->link(); + delete dlg; + return lnk; +} diff --git a/tools/assistant/topicchooserimpl.h b/tools/assistant/topicchooserimpl.h new file mode 100644 index 0000000..f7e9b9a --- /dev/null +++ b/tools/assistant/topicchooserimpl.h @@ -0,0 +1,60 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Assistant. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TOPICCHOOSERIMPL_H +#define TOPICCHOOSERIMPL_H + +#include "topicchooser.h" + +#include + +class TopicChooser : public TopicChooserBase +{ + Q_OBJECT + +public: + TopicChooser( QWidget *parent, const QStringList &lnkNames, + const QStringList &lnks, const QString &title ); + + QString link() const; + + static QString getLink( QWidget *parent, const QStringList &lnkNames, + const QStringList &lnks, const QString &title ); + +private: + QString theLink; + QStringList links, linkNames; + +}; + +#endif diff --git a/tools/designer/LICENSE.GPL b/tools/designer/LICENSE.GPL new file mode 100644 index 0000000..3221c03 --- /dev/null +++ b/tools/designer/LICENSE.GPL @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/tools/designer/app/app.pro b/tools/designer/app/app.pro new file mode 100644 index 0000000..0d66797 --- /dev/null +++ b/tools/designer/app/app.pro @@ -0,0 +1,26 @@ +TEMPLATE = app +TARGET = designer + +CONFIG -= moc +DESTDIR = $$QT_BUILD_TREE/bin + +SOURCES += main.cpp +INCLUDEPATH += ../designer +LIBS += -ldesignercore -lqui -lqassistantclient -L$$QT_BUILD_TREE/lib +win32 { + RC_FILE = designer.rc + win32-g++ { + TARGETDEPS += $$QT_BUILD_TREE/lib/libdesignercore.a + } else { + TARGETDEPS += $$QT_BUILD_TREE/lib/designercore.lib + } +} +mac { + RC_FILE = designer.icns + QMAKE_INFO_PLIST = Info_mac.plist + staticlib:CONFIG -= global_init_link_order #yuck +} + + +target.path=$$bins.path +INSTALLS += target diff --git a/tools/designer/app/designer.icns b/tools/designer/app/designer.icns new file mode 100644 index 0000000..211cc24 Binary files /dev/null and b/tools/designer/app/designer.icns differ diff --git a/tools/designer/app/designer.ico b/tools/designer/app/designer.ico new file mode 100644 index 0000000..7312d20 Binary files /dev/null and b/tools/designer/app/designer.ico differ diff --git a/tools/designer/app/designer.rc b/tools/designer/app/designer.rc new file mode 100644 index 0000000..4b6324b --- /dev/null +++ b/tools/designer/app/designer.rc @@ -0,0 +1,2 @@ +IDI_ICON1 ICON DISCARDABLE "designer.ico" + diff --git a/tools/designer/app/main.cpp b/tools/designer/app/main.cpp new file mode 100644 index 0000000..ef3e907 --- /dev/null +++ b/tools/designer/app/main.cpp @@ -0,0 +1,228 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qplatformdefs.h" + +// SCO OpenServer redefines raise -> kill +#if defined(raise) +# undef raise +#endif + +#include "mainwindow.h" +#include "formwindow.h" + +#include "designerapp.h" + +#include +#include +#include +#include +#include + +#include +#include + +// SCO OpenServer redefines raise -> kill +#if defined(raise) +# undef raise +#endif + +#if defined(Q_WS_WIN) +#include +#include +#endif + +#if defined(Q_OS_UNIX) +#if defined(Q_C_CALLBACKS) +extern "C" { +#endif + +static void signalHandler( QT_SIGNAL_ARGS ) +{ + QFile f( QDir::homeDirPath() + "/.designerargs" ); + f.open( IO_ReadOnly ); + QString args; + f.readLine( args, f.size() ); + QStringList lst = QStringList::split( " ", args ); + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + QString arg = (*it).stripWhiteSpace(); + if ( arg[0] != '-' ) { + QObjectList* l = MainWindow::self->queryList( "FormWindow" ); + FormWindow* fw = (FormWindow*) l->first(); +#if 0 // ### what's this dead code for? + FormWindow* totop; +#endif + bool haveit = FALSE; + while ( fw ) { + haveit = haveit || fw->fileName() == arg; +#if 0 // ### what's this dead code for? + if ( haveit ) + totop = fw; +#endif + fw = (FormWindow*) l->next(); + } + if ( !haveit ) + MainWindow::self->openFormWindow( arg ); + } + } + MainWindow::self->raise(); + MainWindow::self->setActiveWindow(); +} + +#if defined(Q_C_CALLBACKS) +} +#endif + +#endif + +#if defined(Q_C_CALLBACKS) +extern "C" { +#endif + +static void exitHandler( QT_SIGNAL_ARGS ) +{ + QDir d( QDir::homeDirPath() ); + d.remove( ".designerpid" ); + exit( -1 ); +} + +#if defined(Q_C_CALLBACKS) +} +#endif + +int main( int argc, char *argv[] ) +{ + QApplication::setColorSpec( QApplication::ManyColor ); + + DesignerApplication a( argc, argv ); + + DesignerApplication::setOverrideCursor( Qt::WaitCursor ); + + bool creatPid = FALSE; + if ( a.argc() > 1 ) { + QString arg1 = a.argv()[ 1 ]; + if ( arg1 == "-client" ) { + QFile pf( QDir::homeDirPath() + "/.designerpid" ); + if ( pf.exists() && pf.open( IO_ReadOnly ) ) { + QString pidStr; + pf.readLine( pidStr, pf.size() ); + QFile f( QDir::homeDirPath() + "/.designerargs" ); + f.open( IO_WriteOnly ); + QTextStream ts( &f ); + for ( int i = 1; i < a.argc(); ++i ) + ts << a.argv()[ i ] << " "; + ts << endl; + f.close(); +#if defined(Q_OS_UNIX) + if ( kill( pidStr.toInt(), SIGUSR1 ) == -1 ) + creatPid = TRUE; + else + return 0; +#elif defined(Q_OS_WIN32) + if ( !GetProcessVersion( pidStr.toUInt() ) ) { + creatPid = TRUE; + } else { + if ( a.winVersion() & Qt::WV_NT_based ) + SendMessage( HWND_BROADCAST, RegisterWindowMessage((TCHAR*)"QT_DESIGNER_OPEN_FILE"), 0, 0 ); + else + SendMessage( HWND_BROADCAST, RegisterWindowMessageA("QT_DESIGNER_OPEN_FILE"), 0, 0 ); + return 0; + } +#endif + } else { + creatPid = TRUE; + } + } else if(arg1 == "-debug_stderr") { + extern bool debugToStderr; //outputwindow.cpp + debugToStderr = TRUE; + } + } + + if ( creatPid ) { + QFile pf( QDir::homeDirPath() + "/.designerpid" ); + pf.open( IO_WriteOnly ); + QTextStream ts( &pf ); +#if defined(Q_OS_UNIX) + signal( SIGUSR1, signalHandler ); +#endif + ts << getpid() << endl; + + pf.close(); + signal( SIGABRT, exitHandler ); + signal( SIGFPE, exitHandler ); + signal( SIGILL, exitHandler ); + signal( SIGINT, exitHandler ); + signal( SIGSEGV, exitHandler ); + signal( SIGTERM, exitHandler ); + } + + extern void qInitImages_designercore(); + qInitImages_designercore(); + + QSettings config; + QString keybase = DesignerApplication::settingsKey(); + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + QStringList pluginPaths = config.readListEntry( keybase + "PluginPaths" ); + if (pluginPaths.count()) + QApplication::setLibraryPaths(pluginPaths); + + QSplashScreen *splash = a.showSplash(); + + MainWindow *mw = new MainWindow( creatPid ); + a.setMainWidget( mw ); +#if defined(QT_NON_COMMERCIAL) + mw->setCaption( "Qt Designer by Trolltech for non-commercial use" ); +#else + mw->setCaption( "Qt Designer by Trolltech" ); +#endif + if ( config.readBoolEntry( keybase + "Geometries/MainwindowMaximized", FALSE ) ) { + int x = config.readNumEntry( keybase + "Geometries/MainwindowX", 0 ); + int y = config.readNumEntry( keybase + "Geometries/MainwindowY", 0 ); + mw->move( x, y ); + mw->showMaximized(); + } else { + mw->show(); + } + if ( splash ) + splash->finish( mw ); + delete splash; + + QApplication::restoreOverrideCursor(); + for ( int i = 1; i < a.argc(); ++i ) { + QString arg = a.argv()[ i ]; + if ( arg[0] != '-' ) + mw->fileOpen( "", "", arg ); + } + + return a.exec(); +} diff --git a/tools/designer/designer.pro b/tools/designer/designer.pro new file mode 100644 index 0000000..337bbb4 --- /dev/null +++ b/tools/designer/designer.pro @@ -0,0 +1,14 @@ +TEMPLATE = subdirs + +CONFIG += ordered + +SUBDIRS = uic \ + uilib \ + designer \ + app \ + tools/createcw \ + tools/conv2ui + +dll:SUBDIRS *= editor plugins +shared:SUBDIRS *= editor plugins +REQUIRES=full-config nocrosscompiler diff --git a/tools/designer/designer/about.ui b/tools/designer/designer/about.ui new file mode 100644 index 0000000..261ed9d --- /dev/null +++ b/tools/designer/designer/about.ui @@ -0,0 +1,222 @@ + +AboutDialog +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + AboutDialog + + + + 0 + 0 + 544 + 667 + + + + Qt Designer + + + + unnamed + + + 11 + + + 6 + + + + aboutPixmap + + + NoFrame + + + Plain + + + designer_splash.png + + + false + + + AlignCenter + + + + + + + aboutVersion + + + Version 3.2 + + + AlignCenter + + + + + + + aboutCopyright + + + Copyright (C) 2000-2008 Trolltech ASA. All Rights Reserved. + + + AlignCenter + + + + + + + aboutLicense + + + + 1 + 0 + 0 + 0 + + + + <p>Qt Commercial Edition license holders: This program is licensed to you under the terms of the Qt Commercial License Agreement. For details, see the file LICENSE that came with this software distribution.</p><p></p><p>Qt Open Source Edition users: This program is licensed to you under the terms of the GNU General Public License Version 2. For details, see the file LICENSE.GPL that came with this software distribution.</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> + + + WordBreak|AlignVCenter|AlignLeft + + + + + + + Spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + PushButton1 + + + &OK + + + true + + + true + + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + + + PushButton1 + clicked() + AboutDialog + accept() + + + + + diff --git a/tools/designer/designer/actiondnd.cpp b/tools/designer/designer/actiondnd.cpp new file mode 100644 index 0000000..84ec0f6 --- /dev/null +++ b/tools/designer/designer/actiondnd.cpp @@ -0,0 +1,743 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "actiondnd.h" +#include "command.h" +#include "defs.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "widgetfactory.h" +#include "hierarchyview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QAction *ActionDrag::the_action = 0; + +ActionDrag::ActionDrag(QAction *action, QWidget *source) +: QStoredDrag("application/x-designer-actions", source) +{ + Q_ASSERT(the_action == 0); + the_action = action; +} + +ActionDrag::ActionDrag(QActionGroup *group, QWidget *source) +: QStoredDrag("application/x-designer-actiongroup", source) +{ + Q_ASSERT(the_action == 0); + the_action = group; +} + +ActionDrag::ActionDrag(const QString &type, QAction *action, QWidget *source) +: QStoredDrag(type, source) +{ + Q_ASSERT(the_action == 0); + the_action = action; +} + +bool ActionDrag::canDecode(QDropEvent *e) +{ + return e->provides( "application/x-designer-actions" ) || + e->provides( "application/x-designer-actiongroup" ) || + e->provides( "application/x-designer-separator" ); +} + +ActionDrag::~ActionDrag() +{ + the_action = 0; +} + +void QDesignerAction::init() +{ + MetaDataBase::addEntry( this ); + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( this ) ); + WidgetFactory::saveDefaultProperties( this, id ); + WidgetFactory::saveChangedProperties( this, id ); +} + +void QDesignerActionGroup::init() +{ + MetaDataBase::addEntry( this ); + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( this ) ); + WidgetFactory::saveDefaultProperties( this, id ); + WidgetFactory::saveChangedProperties( this, id ); +} + +bool QDesignerAction::addTo( QWidget *w ) +{ + if ( !widgetToInsert ) + return QAction::addTo( w ); + + if ( ::qt_cast(w) ) + return FALSE; + + widgetToInsert->reparent( w, QPoint( 0, 0 ), FALSE ); + widgetToInsert->show(); + addedTo( widgetToInsert, w ); + return TRUE; +} + +bool QDesignerAction::removeFrom( QWidget *w ) +{ + if ( !widgetToInsert ) + return QAction::removeFrom( w ); + + remove(); + return TRUE; +} + +void QDesignerAction::remove() +{ + if ( !widgetToInsert ) + return; + MainWindow::self->formWindow()->selectWidget( widgetToInsert, FALSE ); + widgetToInsert->reparent( 0, QPoint( 0, 0 ), FALSE ); +} + +class QDesignerIndicatorWidget : public QWidget +{ + Q_OBJECT + +public: + QDesignerIndicatorWidget( QWidget *p ) + : QWidget( p, "qt_dockwidget_internal" ) { + setBackgroundColor( red ); + } + +}; + +QDesignerToolBarSeparator::QDesignerToolBarSeparator(Orientation o , QToolBar *parent, + const char* name ) + : QWidget( parent, name ) +{ + connect( parent, SIGNAL(orientationChanged(Orientation)), + this, SLOT(setOrientation(Orientation)) ); + setOrientation( o ); + setBackgroundMode( parent->backgroundMode() ); + setBackgroundOrigin( ParentOrigin ); + setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) ); +} + +void QDesignerToolBarSeparator::setOrientation( Orientation o ) +{ + orient = o; +} + +void QDesignerToolBarSeparator::styleChange( QStyle& ) +{ + setOrientation( orient ); +} + +QSize QDesignerToolBarSeparator::sizeHint() const +{ + int extent = style().pixelMetric( QStyle::PM_DockWindowSeparatorExtent, + this ); + if ( orient == Horizontal ) + return QSize( extent, 0 ); + else + return QSize( 0, extent ); +} + +void QDesignerToolBarSeparator::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + QStyle::SFlags flags = QStyle::Style_Default; + + if ( orientation() == Horizontal ) + flags |= QStyle::Style_Horizontal; + + style().drawPrimitive( QStyle::PE_DockWindowSeparator, &p, rect(), + colorGroup(), flags ); +} + + + +QSeparatorAction::QSeparatorAction( QObject *parent ) + : QAction( parent, "qt_designer_separator" ), wid( 0 ) +{ +} + +bool QSeparatorAction::addTo( QWidget *w ) +{ + if ( ::qt_cast(w) ) { + QToolBar *tb = (QToolBar*)w; + wid = new QDesignerToolBarSeparator( tb->orientation(), tb ); + return TRUE; + } else if ( ::qt_cast(w) ) { + idx = ( (QPopupMenu*)w )->count(); + ( (QPopupMenu*)w )->insertSeparator( idx ); + return TRUE; + } + return FALSE; +} + +bool QSeparatorAction::removeFrom( QWidget *w ) +{ + if ( ::qt_cast(w) ) { + delete wid; + return TRUE; + } else if ( ::qt_cast(w) ) { + ( (QPopupMenu*)w )->removeItemAt( idx ); + return TRUE; + } + return FALSE; +} + +QWidget *QSeparatorAction::widget() const +{ + return wid; +} + + + +QDesignerToolBar::QDesignerToolBar( QMainWindow *mw ) + : QToolBar( mw ), lastIndicatorPos( -1, -1 ) +{ + insertAnchor = 0; + afterAnchor = TRUE; + setAcceptDrops( TRUE ); + MetaDataBase::addEntry( this ); + lastIndicatorPos = QPoint( -1, -1 ); + indicator = new QDesignerIndicatorWidget( this ); + indicator->hide(); + installEventFilter( this ); + widgetInserting = FALSE; + findFormWindow(); + mw->setDockEnabled( DockTornOff, FALSE ); +} + +QDesignerToolBar::QDesignerToolBar( QMainWindow *mw, Dock dock ) + : QToolBar( QString::null, mw, dock), lastIndicatorPos( -1, -1 ) +{ + insertAnchor = 0; + afterAnchor = TRUE; + setAcceptDrops( TRUE ); + indicator = new QDesignerIndicatorWidget( this ); + indicator->hide(); + MetaDataBase::addEntry( this ); + installEventFilter( this ); + widgetInserting = FALSE; + findFormWindow(); + mw->setDockEnabled( DockTornOff, FALSE ); +} + +void QDesignerToolBar::findFormWindow() +{ + QWidget *w = this; + while ( w ) { + formWindow = ::qt_cast(w); + if ( formWindow ) + break; + w = w->parentWidget(); + } +} + +void QDesignerToolBar::addAction( QAction *a ) +{ + actionList.append( a ); + connect( a, SIGNAL( destroyed() ), this, SLOT( actionRemoved() ) ); + if ( ::qt_cast(a) ) { + ( (QDesignerActionGroup*)a )->widget()->installEventFilter( this ); + actionMap.insert( ( (QDesignerActionGroup*)a )->widget(), a ); + } else if ( ::qt_cast(a) ) { + ( (QSeparatorAction*)a )->widget()->installEventFilter( this ); + actionMap.insert( ( (QSeparatorAction*)a )->widget(), a ); + } else { + ( (QDesignerAction*)a )->widget()->installEventFilter( this ); + actionMap.insert( ( (QDesignerAction*)a )->widget(), a ); + } +} + +static void fixObject( QObject *&o ) +{ + while ( o && o->parent() && !::qt_cast(o->parent()) ) + o = o->parent(); +} + +bool QDesignerToolBar::eventFilter( QObject *o, QEvent *e ) +{ + if ( !o || !e || o->inherits( "QDockWindowHandle" ) || o->inherits( "QDockWindowTitleBar" ) ) + return QToolBar::eventFilter( o, e ); + + if ( o == this && e->type() == QEvent::MouseButtonPress && + ( ( QMouseEvent*)e )->button() == LeftButton ) { + mousePressEvent( (QMouseEvent*)e ); + return TRUE; + } + + if ( o == this ) + return QToolBar::eventFilter( o, e ); + + if ( e->type() == QEvent::MouseButtonPress ) { + QMouseEvent *ke = (QMouseEvent*)e; + fixObject( o ); + if ( !o ) + return FALSE; + buttonMousePressEvent( ke, o ); + return TRUE; + } else if(e->type() == QEvent::ContextMenu ) { + QContextMenuEvent *ce = (QContextMenuEvent*)e; + fixObject( o ); + if( !o ) + return FALSE; + buttonContextMenuEvent( ce, o ); + return TRUE; + } else if ( e->type() == QEvent::MouseMove ) { + QMouseEvent *ke = (QMouseEvent*)e; + fixObject( o ); + if ( !o ) + return FALSE; + buttonMouseMoveEvent( ke, o ); + return TRUE; + } else if ( e->type() == QEvent::MouseButtonRelease ) { + QMouseEvent *ke = (QMouseEvent*)e; + fixObject( o ); + if ( !o ) + return FALSE; + buttonMouseReleaseEvent( ke, o ); + return TRUE; + } else if ( e->type() == QEvent::DragEnter ) { + QDragEnterEvent *de = (QDragEnterEvent*)e; + if (ActionDrag::canDecode(de)) + de->accept(); + } else if ( e->type() == QEvent::DragMove ) { + QDragMoveEvent *de = (QDragMoveEvent*)e; + if (ActionDrag::canDecode(de)) + de->accept(); + } + + return QToolBar::eventFilter( o, e ); +} + +void QDesignerToolBar::paintEvent( QPaintEvent *e ) +{ + QToolBar::paintEvent( e ); + if ( e->rect() != rect() ) + return; + lastIndicatorPos = QPoint( -1, -1 ); +} + +void QDesignerToolBar::contextMenuEvent( QContextMenuEvent *e ) +{ + e->accept(); + QPopupMenu menu( 0 ); + menu.insertItem( tr( "Delete Toolbar" ), 1 ); + int res = menu.exec( e->globalPos() ); + if ( res != -1 ) { + RemoveToolBarCommand *cmd = new RemoveToolBarCommand( tr( "Delete Toolbar '%1'" ).arg( name() ), + formWindow, 0, this ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void QDesignerToolBar::mousePressEvent( QMouseEvent *e ) +{ + widgetInserting = FALSE; + if ( e->button() == LeftButton && + MainWindow::self->currentTool() != POINTER_TOOL && + MainWindow::self->currentTool() != ORDER_TOOL && + MainWindow::self->currentTool() != CONNECT_TOOL && + MainWindow::self->currentTool() != BUDDY_TOOL ) + widgetInserting = TRUE; +} + +void QDesignerToolBar::mouseReleaseEvent( QMouseEvent *e ) +{ + if ( widgetInserting ) + doInsertWidget( mapFromGlobal( e->globalPos() ) ); + widgetInserting = FALSE; +} + +void QDesignerToolBar::buttonMouseReleaseEvent( QMouseEvent *e, QObject *w ) +{ + if ( widgetInserting ) + doInsertWidget( mapFromGlobal( e->globalPos() ) ); + else if ( w->isWidgetType() && formWindow->widgets()->find( w ) ) { + formWindow->clearSelection( FALSE ); + formWindow->selectWidget( w ); + } + widgetInserting = FALSE; +} + +void QDesignerToolBar::buttonContextMenuEvent( QContextMenuEvent *e, QObject *o ) +{ + e->accept(); + QPopupMenu menu( 0 ); + const int ID_DELETE = 1; + const int ID_SEP = 2; + const int ID_DELTOOLBAR = 3; + QMap::Iterator it = actionMap.find( (QWidget*)o ); + if ( it != actionMap.end() && ::qt_cast(*it) ) + menu.insertItem( tr( "Delete Separator" ), ID_DELETE ); + else + menu.insertItem( tr( "Delete Item" ), ID_DELETE ); + menu.insertItem( tr( "Insert Separator" ), ID_SEP ); + menu.insertSeparator(); + menu.insertItem( tr( "Delete Toolbar" ), ID_DELTOOLBAR ); + int res = menu.exec( e->globalPos() ); + if ( res == ID_DELETE ) { + QMap::Iterator it = actionMap.find( (QWidget*)o ); + if ( it == actionMap.end() ) + return; + QAction *a = *it; + int index = actionList.find( a ); + RemoveActionFromToolBarCommand *cmd = new RemoveActionFromToolBarCommand( + tr( "Delete Action '%1' from Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( res == ID_SEP ) { + calcIndicatorPos( mapFromGlobal( e->globalPos() ) ); + QAction *a = new QSeparatorAction( 0 ); + int index = actionList.findRef( *actionMap.find( insertAnchor ) ); + if ( index != -1 && afterAnchor ) + ++index; + if ( !insertAnchor ) + index = 0; + + AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( + tr( "Add Separator to Toolbar '%1'" ). + arg( a->name() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( res == ID_DELTOOLBAR ) { + RemoveToolBarCommand *cmd = new RemoveToolBarCommand( tr( "Delete Toolbar '%1'" ).arg( name() ), + formWindow, 0, this ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void QDesignerToolBar::buttonMousePressEvent( QMouseEvent *e, QObject * ) +{ + widgetInserting = FALSE; + + if ( e->button() == MidButton ) + return; + + if ( e->button() == LeftButton && + MainWindow::self->currentTool() != POINTER_TOOL && + MainWindow::self->currentTool() != ORDER_TOOL && + MainWindow::self->currentTool() != CONNECT_TOOL && + MainWindow::self->currentTool() != BUDDY_TOOL ) { + widgetInserting = TRUE; + return; + } + + dragStartPos = e->pos(); +} + +void QDesignerToolBar::removeWidget( QWidget *w ) +{ + QMap::Iterator it = actionMap.find( w ); + if ( it == actionMap.end() ) + return; + QAction *a = *it; + int index = actionList.find( a ); + RemoveActionFromToolBarCommand *cmd = + new RemoveActionFromToolBarCommand( tr( "Delete Action '%1' from Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + QApplication::sendPostedEvents(); + adjustSize(); +} + +void QDesignerToolBar::buttonMouseMoveEvent( QMouseEvent *e, QObject *o ) +{ + if ( widgetInserting || ( e->state() & LeftButton ) == 0 ) + return; + if ( QABS( QPoint( dragStartPos - e->pos() ).manhattanLength() ) < QApplication::startDragDistance() ) + return; + QMap::Iterator it = actionMap.find( (QWidget*)o ); + if ( it == actionMap.end() ) + return; + QAction *a = *it; + if ( !a ) + return; + int index = actionList.find( a ); + RemoveActionFromToolBarCommand *cmd = + new RemoveActionFromToolBarCommand( tr( "Delete Action '%1' from Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + QApplication::sendPostedEvents(); + adjustSize(); + + QString type = ::qt_cast(a) ? QString( "application/x-designer-actiongroup" ) : + ::qt_cast(a) ? QString( "application/x-designer-separator" ) : QString( "application/x-designer-actions" ); + QStoredDrag *drag = new ActionDrag( type, a, this ); + drag->setPixmap( a->iconSet().pixmap() ); + if ( ::qt_cast(a) ) { + if ( formWindow->widgets()->find( ( (QDesignerAction*)a )->widget() ) ) + formWindow->selectWidget( ( (QDesignerAction*)a )->widget(), FALSE ); + } + if ( !drag->drag() ) { + AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( tr( "Add Action '%1' to Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + lastIndicatorPos = QPoint( -1, -1 ); + indicator->hide(); +} + +#ifndef QT_NO_DRAGANDDROP + +void QDesignerToolBar::dragEnterEvent( QDragEnterEvent *e ) +{ + widgetInserting = FALSE; + lastIndicatorPos = QPoint( -1, -1 ); + if (ActionDrag::canDecode(e)) + e->accept(); +} + +void QDesignerToolBar::dragMoveEvent( QDragMoveEvent *e ) +{ + if (ActionDrag::canDecode(e)) { + e->accept(); + drawIndicator( calcIndicatorPos( e->pos() ) ); + } +} + +void QDesignerToolBar::dragLeaveEvent( QDragLeaveEvent * ) +{ + indicator->hide(); + insertAnchor = 0; + afterAnchor = TRUE; +} + +void QDesignerToolBar::dropEvent( QDropEvent *e ) +{ + if (!ActionDrag::canDecode(e)) + return; + + e->accept(); + + indicator->hide(); + QAction *a = 0; + int index = actionList.findRef( *actionMap.find( insertAnchor ) ); + if ( index != -1 && afterAnchor ) + ++index; + if ( !insertAnchor ) + index = 0; + if ( e->provides( "application/x-designer-actions" ) || + e->provides( "application/x-designer-separator" ) ) { + if ( e->provides( "application/x-designer-actions" ) ) + a = ::qt_cast(ActionDrag::action()); + else + a = ::qt_cast(ActionDrag::action()); + } else { + a = ::qt_cast(ActionDrag::action()); + } + + if ( actionList.findRef( a ) != -1 ) { + QMessageBox::warning( MainWindow::self, tr( "Insert/Move Action" ), + tr( "Action '%1' has already been added to this toolbar.\n" + "An Action may only occur once in a given toolbar." ). + arg( a->name() ) ); + return; + } + + AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( tr( "Add Action '%1' to Toolbar '%2'" ). + arg( a->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + + lastIndicatorPos = QPoint( -1, -1 ); +} + +#endif + +void QDesignerToolBar::reInsert() +{ + QAction *a = 0; + actionMap.clear(); + clear(); + for ( a = actionList.first(); a; a = actionList.next() ) { + a->addTo( this ); + if ( ::qt_cast(a) ) { + actionMap.insert( ( (QDesignerActionGroup*)a )->widget(), a ); + if ( ( (QDesignerActionGroup*)a )->widget() ) + ( (QDesignerActionGroup*)a )->widget()->installEventFilter( this ); + } else if ( ::qt_cast(a) ) { + actionMap.insert( ( (QDesignerAction*)a )->widget(), a ); + ( (QDesignerAction*)a )->widget()->installEventFilter( this ); + } else if ( ::qt_cast(a) ) { + actionMap.insert( ( (QSeparatorAction*)a )->widget(), a ); + ( (QSeparatorAction*)a )->widget()->installEventFilter( this ); + } + } + QApplication::sendPostedEvents(); + adjustSize(); +} + +void QDesignerToolBar::actionRemoved() +{ + actionList.removeRef( (QAction*)sender() ); +} + +QPoint QDesignerToolBar::calcIndicatorPos( const QPoint &pos ) +{ + if ( orientation() == Horizontal ) { + QPoint pnt( width() - 2, 0 ); + insertAnchor = 0; + afterAnchor = TRUE; + if ( !children() ) + return pnt; + pnt = QPoint( 13, 0 ); + QObjectListIt it( *children() ); + QObject * obj; + while( (obj=it.current()) != 0 ) { + ++it; + if ( obj->isWidgetType() && + qstrcmp( "qt_dockwidget_internal", obj->name() ) != 0 ) { + QWidget *w = (QWidget*)obj; + if ( w->x() < pos.x() ) { + pnt.setX( w->x() + w->width() + 1 ); + insertAnchor = w; + afterAnchor = TRUE; + } + } + } + return pnt; + } else { + QPoint pnt( 0, height() - 2 ); + insertAnchor = 0; + afterAnchor = TRUE; + if ( !children() ) + return pnt; + pnt = QPoint( 0, 13 ); + QObjectListIt it( *children() ); + QObject * obj; + while( (obj=it.current()) != 0 ) { + ++it; + if ( obj->isWidgetType() && + qstrcmp( "qt_dockwidget_internal", obj->name() ) != 0 ) { + QWidget *w = (QWidget*)obj; + if ( w->y() < pos.y() ) { + pnt.setY( w->y() + w->height() + 1 ); + insertAnchor = w; + afterAnchor = TRUE; + } + } + } + return pnt; + } +} + +void QDesignerToolBar::drawIndicator( const QPoint &pos ) +{ + if ( lastIndicatorPos == pos ) + return; + bool wasVsisible = indicator->isVisible(); + if ( orientation() == Horizontal ) { + indicator->resize( 3, height() ); + if ( pos != QPoint( -1, -1 ) ) + indicator->move( pos.x() - 1, 0 ); + indicator->show(); + indicator->raise(); + lastIndicatorPos = pos; + } else { + indicator->resize( width(), 3 ); + if ( pos != QPoint( -1, -1 ) ) + indicator->move( 0, pos.y() - 1 ); + indicator->show(); + indicator->raise(); + lastIndicatorPos = pos; + } + if ( !wasVsisible ) + QApplication::sendPostedEvents(); +} + +void QDesignerToolBar::doInsertWidget( const QPoint &p ) +{ + if ( formWindow != MainWindow::self->formWindow() ) + return; + calcIndicatorPos( p ); + QWidget *w = WidgetFactory::create( MainWindow::self->currentTool(), this, 0, TRUE ); + installEventFilters( w ); + MainWindow::self->formWindow()->insertWidget( w, TRUE ); + QDesignerAction *a = new QDesignerAction( w, parent() ); + int index = actionList.findRef( *actionMap.find( insertAnchor ) ); + if ( index != -1 && afterAnchor ) + ++index; + if ( !insertAnchor ) + index = 0; + AddActionToToolBarCommand *cmd = new AddActionToToolBarCommand( tr( "Add Widget '%1' to Toolbar '%2'" ). + arg( w->name() ).arg( caption() ), + formWindow, a, this, index ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + MainWindow::self->resetTool(); +} + +void QDesignerToolBar::clear() +{ + for ( QAction *a = actionList.first(); a; a = actionList.next() ) { + if ( ::qt_cast(a) ) + ( (QDesignerAction*)a )->remove(); + } + QToolBar::clear(); +} + +void QDesignerToolBar::installEventFilters( QWidget *w ) +{ + if ( !w ) + return; + QObjectList *l = w->queryList( "QWidget" ); + for ( QObject *o = l->first(); o; o = l->next() ) + o->installEventFilter( this ); + delete l; +} + +#include "actiondnd.moc" diff --git a/tools/designer/designer/actiondnd.h b/tools/designer/designer/actiondnd.h new file mode 100644 index 0000000..5c3d16b --- /dev/null +++ b/tools/designer/designer/actiondnd.h @@ -0,0 +1,242 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef ACTIONDND_H +#define ACTIONDND_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../shared/widgetdatabase.h" + +//class QDesignerPopupMenu; +class QDesignerIndicatorWidget; +class FormWindow; +class QPopupMenu; + +class ActionDrag : public QStoredDrag +{ + Q_OBJECT + +public: + ActionDrag(const QString &type, QAction *action, QWidget *source); + ActionDrag(QAction *action, QWidget *source); + ActionDrag(QActionGroup *group, QWidget *source); + + ~ActionDrag(); + + static bool canDecode(QDropEvent *e); + + static QAction *action() + { + return the_action; + } + +private: + static QAction *the_action; +}; + +class QDesignerActionGroup : public QActionGroup +{ + Q_OBJECT + +public: + QDesignerActionGroup( QObject *parent ) + : QActionGroup( ::qt_cast(parent) ? parent : 0 ), wid( 0 ), idx( -1 ) { init(); } + + void init(); + + QWidget *widget() const { return wid; } + QWidget *widget( QAction *a ) const { return *widgets.find( a ); } + int index() const { return idx; } + +protected: +#if !defined(Q_NO_USING_KEYWORD) + using QActionGroup::addedTo; +#endif + void addedTo( QWidget *w, QWidget * ) { + wid = w; + } + void addedTo( QWidget *w, QWidget *, QAction *a ) { + widgets.insert( a, w ); + } + void addedTo( int index, QPopupMenu * ) { + idx = index; + } + +private: + QWidget *wid; + QMap widgets; + int idx; + +}; + +class QDesignerAction : public QAction +{ + Q_OBJECT + +public: + QDesignerAction( QObject *parent ) + : QAction( ::qt_cast(parent) ? parent : 0 ), wid( 0 ), idx( -1 ), widgetToInsert( 0 ) { init(); } + QDesignerAction( QWidget *w, QObject *parent ) + : QAction( ::qt_cast(parent) ? parent : 0 ), wid( 0 ), idx( -1 ), widgetToInsert( w ) { init(); } + + void init(); + + QWidget *widget() const { return wid; } + int index() const { return idx; } + + bool addTo( QWidget *w ); + bool removeFrom( QWidget *w ); + + void remove(); + bool supportsMenu() const { return !widgetToInsert; } + +protected: + void addedTo( QWidget *w, QWidget * ) { + wid = w; + } + void addedTo( int index, QPopupMenu * ) { + idx = index; + } + +private: + QWidget *wid; + int idx; + QWidget *widgetToInsert; + +}; + +class QDesignerToolBarSeparator : public QWidget +{ + Q_OBJECT + +public: + QDesignerToolBarSeparator( Orientation, QToolBar *parent, const char* name=0 ); + + QSize sizeHint() const; + Orientation orientation() const { return orient; } +public slots: + void setOrientation( Orientation ); +protected: + void styleChange( QStyle& ); + void paintEvent( QPaintEvent * ); +private: + Orientation orient; +}; + + +class QSeparatorAction : public QAction +{ + Q_OBJECT + +public: + QSeparatorAction( QObject *parent ); + + bool addTo( QWidget *w ); + bool removeFrom( QWidget *w ); + QWidget *widget() const; + int index() const; + +private: + QWidget *wid; + int idx; + +}; + + +class QDesignerToolBar : public QToolBar +{ + Q_OBJECT + +public: + QDesignerToolBar( QMainWindow *mw ); + QDesignerToolBar( QMainWindow *mw, Dock dock ); + QPtrList insertedActions() const { return actionList; } + void addAction( QAction *a ); + + void clear(); + void installEventFilters( QWidget *w ); + void insertAction( QWidget *w, QAction *a ) { actionMap.insert( w, a ); } + void insertAction( int index, QAction *a ) { actionList.insert( index, a ); } + void appendAction( QAction *a ) { actionList.append( a ); } + void removeAction( QAction *a ) { actionList.remove( a ); } + void reInsert(); + void removeWidget( QWidget *w ); + +protected: + bool eventFilter( QObject *, QEvent * ); + void paintEvent( QPaintEvent * ); +#ifndef QT_NO_DRAGANDDROP + void dragEnterEvent( QDragEnterEvent * ); + void dragMoveEvent( QDragMoveEvent * ); + void dragLeaveEvent( QDragLeaveEvent * ); + void dropEvent( QDropEvent * ); +#endif + void contextMenuEvent( QContextMenuEvent *e ); + void mousePressEvent( QMouseEvent *e ); + void mouseReleaseEvent( QMouseEvent *e ); + +private slots: + void actionRemoved(); + +private: + void drawIndicator( const QPoint &pos ); + QPoint calcIndicatorPos( const QPoint &pos ); + void buttonContextMenuEvent( QContextMenuEvent *e, QObject *o ); + void buttonMousePressEvent( QMouseEvent *e, QObject *o ); + void buttonMouseMoveEvent( QMouseEvent *e, QObject *o ); + void buttonMouseReleaseEvent( QMouseEvent *e, QObject *o ); + void doInsertWidget( const QPoint &p ); + void findFormWindow(); + +private: + QPoint lastIndicatorPos; + QWidget *insertAnchor; + bool afterAnchor; + QPtrList actionList; + QMap actionMap; + QPoint dragStartPos; + QDesignerIndicatorWidget *indicator; + bool widgetInserting; + FormWindow *formWindow; + +}; + +#endif diff --git a/tools/designer/designer/actioneditor.ui b/tools/designer/designer/actioneditor.ui new file mode 100644 index 0000000..97efa6a --- /dev/null +++ b/tools/designer/designer/actioneditor.ui @@ -0,0 +1,230 @@ + +ActionEditorBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + ActionEditorBase + + + + 0 + 0 + 206 + 227 + + + + Edit Actions + + + + + + unnamed + + + 4 + + + 6 + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + buttonNewAction + + + + + + designer_filenew.png + + + true + + + Create new Action + + + + + buttonDeleteAction + + + + + + designer_s_editcut.png + + + true + + + Delete current Action + + + + + buttonConnect + + + + + + designer_connecttool.png + + + true + + + Connect current Action + + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + listActions + + + + + + + ActionListView +
actionlistview.h
+ + 200 + 200 + + 0 + + 7 + 7 + 0 + 0 + + image0 + selectionChanged( QListViewItem * ) + currentChanged( QListViewItem * ) + clicked( QListViewItem * ) +
+
+ + + 789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758 + + + + + listActions + currentChanged( QListViewItem * ) + ActionEditorBase + currentActionChanged(QListViewItem*) + + + listActions + clicked( QListViewItem * ) + ActionEditorBase + currentActionChanged(QListViewItem*) + + + listActions + selectionChanged( QListViewItem * ) + ActionEditorBase + currentActionChanged(QListViewItem*) + + + buttonNewAction + clicked() + ActionEditorBase + newAction() + + + buttonConnect + clicked() + ActionEditorBase + connectionsClicked() + + + buttonDeleteAction + clicked() + ActionEditorBase + deleteAction() + + + + class QListViewItem; + + + init() + destroy() + connectionsClicked() + currentActionChanged( QListViewItem * ) + deleteAction() + newAction() + + + +
diff --git a/tools/designer/designer/actioneditorimpl.cpp b/tools/designer/designer/actioneditorimpl.cpp new file mode 100644 index 0000000..fc2dff4 --- /dev/null +++ b/tools/designer/designer/actioneditorimpl.cpp @@ -0,0 +1,325 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "actioneditorimpl.h" +#include "formwindow.h" +#include "metadatabase.h" +#include "actionlistview.h" +#include "connectiondialog.h" +#include "mainwindow.h" +#include "hierarchyview.h" +#include "formfile.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ActionEditor::ActionEditor( QWidget* parent, const char* name, WFlags fl ) + : ActionEditorBase( parent, name, fl ), currentAction( 0 ), formWindow( 0 ), + explicitlyClosed(false) +{ + listActions->addColumn( tr( "Actions" ) ); + setEnabled( FALSE ); + buttonConnect->setEnabled( FALSE ); + + QPopupMenu *popup = new QPopupMenu( this ); + popup->insertItem( tr( "New &Action" ), this, SLOT( newAction() ) ); + popup->insertItem( tr( "New Action &Group" ), this, SLOT( newActionGroup() ) ); + popup->insertItem( tr( "New &Dropdown Action Group" ), this, SLOT( newDropDownActionGroup() ) ); + buttonNewAction->setPopup( popup ); + buttonNewAction->setPopupDelay( 0 ); + + connect( listActions, SIGNAL( insertAction() ), this, SLOT( newAction() ) ); + connect( listActions, SIGNAL( insertActionGroup() ), this, SLOT( newActionGroup() ) ); + connect( listActions, SIGNAL( insertDropDownActionGroup() ), this, SLOT( newDropDownActionGroup() ) ); + connect( listActions, SIGNAL( deleteAction() ), this, SLOT( deleteAction() ) ); + connect( listActions, SIGNAL( connectAction() ), this, SLOT( connectionsClicked() ) ); +} + +void ActionEditor::closeEvent( QCloseEvent *e ) +{ + emit hidden(); + e->accept(); +} + +void ActionEditor::currentActionChanged( QListViewItem *i ) +{ + buttonConnect->setEnabled( i != 0 ); + if ( !i ) + return; + currentAction = ( (ActionItem*)i )->action(); + if ( !currentAction ) + currentAction = ( (ActionItem*)i )->actionGroup(); + if ( formWindow && currentAction ) + formWindow->setActiveObject( currentAction ); + MainWindow::self->objectHierarchy()->hierarchyList()->setCurrent( currentAction ); +} + +void ActionEditor::setCurrentAction( QAction *a ) +{ + QListViewItemIterator it( listActions ); + while ( it.current() ) { + if ( ( (ActionItem*)it.current() )->action() == a || ( (ActionItem*)it.current() )->actionGroup() == a ) { + listActions->setCurrentItem( it.current() ); + listActions->ensureItemVisible( it.current() ); + break; + } + ++it; + } +} + +QAction *ActionEditor::newActionEx() +{ + ActionItem *i = new ActionItem( listActions, (bool)FALSE ); + QAction *a = i->action(); + QObject::connect( a, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject* ) ) ); + MetaDataBase::addEntry( i->action() ); + QString n = "Action"; + formWindow->unify( i->action(), n, TRUE ); + i->setText( 0, n ); + i->action()->setName( n ); + i->action()->setText( i->action()->name() ); + MetaDataBase::setPropertyChanged( i->action(), "text", TRUE ); + MetaDataBase::setPropertyChanged( i->action(), "name", TRUE ); + formWindow->actionList().append( i->action() ); + if ( formWindow->formFile() ) + formWindow->formFile()->setModified( TRUE ); + return i->action(); +} + +void ActionEditor::deleteAction() +{ + if ( !currentAction ) + return; + + QListViewItemIterator it( listActions ); + ActionItem *ai = 0; + while ( it.current() ) { + ai = (ActionItem*)it.current(); + if ( ai->action() == currentAction || ai->actionGroup() == currentAction ) { + emit removing( currentAction ); + formWindow->actionList().removeRef( currentAction ); + delete currentAction; + currentAction = 0; + delete it.current(); + break; + } + ++it; + } + if ( formWindow ) { + formWindow->setActiveObject( formWindow->mainContainer() ); + if ( formWindow->formFile() ) + formWindow->formFile()->setModified( TRUE ); + } +} + +void ActionEditor::newAction() +{ + ActionItem *actionParent = (ActionItem*)listActions->selectedItem(); + if ( actionParent ) { + if ( !::qt_cast(actionParent->actionGroup()) ) + actionParent = (ActionItem*)actionParent->parent(); + } + + ActionItem *i = 0; + if ( actionParent ) + i = new ActionItem( actionParent ); + else + i = new ActionItem( listActions, (bool)FALSE ); + QAction *a = i->action(); + QObject::connect( a, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject* ) ) ); + MetaDataBase::addEntry( i->action() ); + QString n = "Action"; + formWindow->unify( i->action(), n, TRUE ); + i->setText( 0, n ); + i->action()->setName( n ); + i->action()->setText( i->action()->name() ); + if ( actionParent && actionParent->actionGroup() && + actionParent->actionGroup()->usesDropDown() ) { + i->action()->setToggleAction( TRUE ); + MetaDataBase::setPropertyChanged( i->action(), "toggleAction", TRUE ); + } + MetaDataBase::setPropertyChanged( i->action(), "text", TRUE ); + MetaDataBase::setPropertyChanged( i->action(), "name", TRUE ); + listActions->setCurrentItem( i ); + if ( !actionParent ) + formWindow->actionList().append( i->action() ); + if ( formWindow->formFile() ) + formWindow->formFile()->setModified( TRUE ); +} + +void ActionEditor::newActionGroup() +{ + ActionItem *actionParent = (ActionItem*)listActions->selectedItem(); + if ( actionParent ) { + if ( !::qt_cast(actionParent->actionGroup()) ) + actionParent = (ActionItem*)actionParent->parent(); + } + + ActionItem *i = 0; + if ( actionParent ) + i = new ActionItem( actionParent, TRUE ); + else + i = new ActionItem( listActions, TRUE ); + QAction *ag = i->actionGroup(); + QObject::connect( ag, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject* ) ) ); + MetaDataBase::addEntry( i->actionGroup() ); + MetaDataBase::setPropertyChanged( i->actionGroup(), "usesDropDown", TRUE ); + QString n = "ActionGroup"; + formWindow->unify( i->action(), n, TRUE ); + i->setText( 0, n ); + i->actionGroup()->setName( n ); + i->actionGroup()->setText( i->actionGroup()->name() ); + MetaDataBase::setPropertyChanged( i->actionGroup(), "text", TRUE ); + MetaDataBase::setPropertyChanged( i->actionGroup(), "name", TRUE ); + listActions->setCurrentItem( i ); + i->setOpen( TRUE ); + if ( !actionParent ) + formWindow->actionList().append( i->actionGroup() ); + if ( formWindow->formFile() ) + formWindow->formFile()->setModified( TRUE ); +} + +void ActionEditor::newDropDownActionGroup() +{ + newActionGroup(); + ( (ActionItem*)listActions->currentItem() )->actionGroup()->setUsesDropDown( TRUE ); +} + +void ActionEditor::setFormWindow( FormWindow *fw ) +{ + listActions->clear(); + formWindow = fw; + if ( !formWindow || + !::qt_cast(formWindow->mainContainer()) ) { + setEnabled( FALSE ); + } else { + setEnabled( TRUE ); + for ( QAction *a = formWindow->actionList().first(); a; a = formWindow->actionList().next() ) { + ActionItem *i = 0; + if ( ::qt_cast(a->parent()) ) + continue; + i = new ActionItem( listActions, a ); + i->setText( 0, a->name() ); + i->setPixmap( 0, a->iconSet().pixmap() ); + // make sure we don't duplicate the connection + QObject::disconnect( a, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject * ) ) ); + QObject::connect( a, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject* ) ) ); + if ( ::qt_cast(a) ) { + insertChildActions( i ); + } + } + if ( listActions->firstChild() ) { + listActions->setCurrentItem( listActions->firstChild() ); + listActions->setSelected( listActions->firstChild(), TRUE ); + } + } +} + +void ActionEditor::insertChildActions( ActionItem *i ) +{ + if ( !i->actionGroup() || !i->actionGroup()->children() ) + return; + QObjectListIt it( *i->actionGroup()->children() ); + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast(o) ) + continue; + QAction *a = (QAction*)o; + ActionItem *i2 = new ActionItem( (QListViewItem*)i, a ); + i->setOpen( TRUE ); + i2->setText( 0, a->name() ); + i2->setPixmap( 0, a->iconSet().pixmap() ); + // make sure we don't duplicate the connection + QObject::disconnect( o, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject * ) ) ); + QObject::connect( o, SIGNAL( destroyed( QObject * ) ), + this, SLOT( removeConnections( QObject * ) ) ); + if ( ::qt_cast(a) ) + insertChildActions( i2 ); + } +} + +void ActionEditor::updateActionName( QAction *a ) +{ + QListViewItemIterator it( listActions ); + while ( it.current() ) { + if ( ( (ActionItem*)it.current() )->action() == a ) + ( (ActionItem*)it.current() )->setText( 0, a->name() ); + else if ( ( (ActionItem*)it.current() )->actionGroup() == a ) + ( (ActionItem*)it.current() )->setText( 0, a->name() ); + ++it; + } +} + +void ActionEditor::updateActionIcon( QAction *a ) +{ + QListViewItemIterator it( listActions ); + while ( it.current() ) { + if ( ( (ActionItem*)it.current() )->action() == a ) + ( (ActionItem*)it.current() )->setPixmap( 0, a->iconSet().pixmap() ); + else if ( ( (ActionItem*)it.current() )->actionGroup() == a ) + ( (ActionItem*)it.current() )->setPixmap( 0, a->iconSet().pixmap() ); + ++it; + } +} + +void ActionEditor::connectionsClicked() +{ + ConnectionDialog dlg( formWindow->mainWindow() ); + dlg.setDefault( currentAction, formWindow ); + dlg.addConnection(); + dlg.exec(); +} + +void ActionEditor::removeConnections( QObject *o ) +{ + QValueList conns = + MetaDataBase::connections( formWindow, o ); + for ( QValueList::Iterator it2 = conns.begin(); + it2 != conns.end(); ++it2 ) + MetaDataBase::removeConnection( formWindow, (*it2).sender, (*it2).signal, + (*it2).receiver, (*it2).slot ); +} diff --git a/tools/designer/designer/actioneditorimpl.h b/tools/designer/designer/actioneditorimpl.h new file mode 100644 index 0000000..86beb38 --- /dev/null +++ b/tools/designer/designer/actioneditorimpl.h @@ -0,0 +1,86 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef ACTIONEDITORIMPL_H +#define ACTIONEDITORIMPL_H + +#include "actioneditor.h" + +class QAction; +class FormWindow; +class ActionItem; + +class ActionEditor : public ActionEditorBase +{ + Q_OBJECT + +public: + ActionEditor( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + void setFormWindow( FormWindow *fw ); + void updateActionName( QAction *a ); + void updateActionIcon( QAction *a ); + FormWindow *form() const { return formWindow; } + + bool wantToBeShown() const { return !explicitlyClosed; } + void setWantToBeShown( bool b ) { explicitlyClosed = !b; } + + void setCurrentAction( QAction *a ); + QAction *newActionEx(); + +protected: + void closeEvent( QCloseEvent *e ); + +protected slots: + void currentActionChanged( QListViewItem * ); + void deleteAction(); + void newAction(); + void newActionGroup(); + void newDropDownActionGroup(); + void connectionsClicked(); + void removeConnections( QObject *o ); + +signals: + void hidden(); + void removing( QAction * ); + +private: + void insertChildActions( ActionItem *i ); + +private: + QAction *currentAction; + FormWindow *formWindow; + bool explicitlyClosed; + +}; + +#endif // ACTIONEDITORIMPL_H diff --git a/tools/designer/designer/actionlistview.cpp b/tools/designer/designer/actionlistview.cpp new file mode 100644 index 0000000..7d1a6d9 --- /dev/null +++ b/tools/designer/designer/actionlistview.cpp @@ -0,0 +1,115 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "actiondnd.h" +#include "actionlistview.h" +#include + +ActionListView::ActionListView( QWidget *parent, const char *name ) + : QListView( parent, name ) +{ + setShowSortIndicator( TRUE ); + setResizeMode( LastColumn ); + setRootIsDecorated( TRUE ); + connect( this, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint &, int ) ), + this, SLOT( rmbMenu( QListViewItem *, const QPoint & ) ) ); +} + +ActionItem::ActionItem( QListView *lv, QAction *ac ) + : QListViewItem( lv ), a( 0 ), g( 0 ) +{ + g = ::qt_cast(ac); + if ( !g ) + a = ::qt_cast(ac); + setDragEnabled( TRUE ); +} + +ActionItem::ActionItem( QListViewItem *i, QAction *ac ) + : QListViewItem( i ), a( 0 ), g( 0 ) +{ + g = ::qt_cast(ac); + if ( !g ) + a = ::qt_cast(ac); + setDragEnabled( TRUE ); + moveToEnd(); +} + +void ActionItem::moveToEnd() +{ + QListViewItem *i = this; + while ( i->nextSibling() ) + i = i->nextSibling(); + if ( i != this ) + moveItem( i ); +} + +QDragObject *ActionListView::dragObject() +{ + ActionItem *i = (ActionItem*)currentItem(); + if ( !i ) + return 0; + QStoredDrag *drag = 0; + if ( i->action() ) { + drag = new ActionDrag( i->action(), viewport() ); + drag->setPixmap( i->action()->iconSet().pixmap() ); + } else { + drag = new ActionDrag( i->actionGroup(), viewport() ); + drag->setPixmap( i->actionGroup()->iconSet().pixmap() ); + } + return drag; +} + +void ActionListView::rmbMenu( QListViewItem *i, const QPoint &p ) +{ + QPopupMenu *popup = new QPopupMenu( this ); + popup->insertItem( tr( "New &Action" ), 0 ); + popup->insertItem( tr( "New Action &Group" ), 1 ); + popup->insertItem( tr( "New &Dropdown Action Group" ), 2 ); + if ( i ) { + popup->insertSeparator(); + popup->insertItem( tr( "&Connect Action..." ), 3 ); + popup->insertSeparator(); + popup->insertItem( tr( "Delete Action" ), 4 ); + } + int res = popup->exec( p ); + if ( res == 0 ) + emit insertAction(); + else if ( res == 1 ) + emit insertActionGroup(); + else if ( res == 2 ) + emit insertDropDownActionGroup(); + else if ( res == 3 ) + emit connectAction(); + else if ( res == 4 ) + emit deleteAction(); +} diff --git a/tools/designer/designer/actionlistview.h b/tools/designer/designer/actionlistview.h new file mode 100644 index 0000000..6a5edaa --- /dev/null +++ b/tools/designer/designer/actionlistview.h @@ -0,0 +1,88 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef ACTIONLISTVIEW_H +#define ACTIONLISTVIEW_H + +#include +#include "actiondnd.h" + +class ActionItem : public QListViewItem +{ +public: + ActionItem( QListView *lv, bool group ) + : QListViewItem( lv ), + a( group ? 0 : new QDesignerAction( 0 ) ), + g( group ? new QDesignerActionGroup( 0 ) : 0 ) { setDragEnabled( TRUE ); } + ActionItem( QListView *lv, QAction *ac ); + ActionItem( QListViewItem *i, QAction *ac ); + ActionItem( ActionItem *parent, bool group = FALSE ) + : QListViewItem( parent ), + a( group ? 0 : new QDesignerAction( parent->actionGroup() ) ), + g( group ? new QDesignerActionGroup( parent->actionGroup() ) : 0 ) { setDragEnabled( TRUE ); moveToEnd(); } + + QDesignerAction *action() const { return a; } + QDesignerActionGroup *actionGroup() const { return g; } + +private: + void moveToEnd(); + +private: + QDesignerAction *a; + QDesignerActionGroup *g; + +}; + +class ActionListView : public QListView +{ + Q_OBJECT + +public: + ActionListView( QWidget *parent = 0, const char *name = 0 ); + +protected: + QDragObject *dragObject(); + +private slots: + void rmbMenu( QListViewItem *i, const QPoint &p ); + +signals: + void insertAction(); + void insertActionGroup(); + void insertDropDownActionGroup(); + void deleteAction(); + void connectAction(); + +}; + +#endif diff --git a/tools/designer/designer/asciivalidator.cpp b/tools/designer/designer/asciivalidator.cpp new file mode 100644 index 0000000..e4f92e6 --- /dev/null +++ b/tools/designer/designer/asciivalidator.cpp @@ -0,0 +1,101 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "asciivalidator.h" + +#include + +AsciiValidator::AsciiValidator( QObject * parent, const char *name ) + : QValidator( parent, name ), functionName( FALSE ) +{ +} + +AsciiValidator::AsciiValidator( bool funcName, QObject * parent, const char *name ) + : QValidator( parent, name ), functionName( funcName ) +{ +} + +AsciiValidator::AsciiValidator( const QString &allow, QObject * parent, const char *name ) + : QValidator( parent, name ), functionName( FALSE ), allowedChars( allow ) +{ +} + +AsciiValidator::~AsciiValidator() +{ +} + +QValidator::State AsciiValidator::validate( QString &s, int & ) const +{ + bool inParen = FALSE; + bool outParen = FALSE; + if ( !s.isEmpty() && s[0].row() == 0 && s[0].cell() >= '0' && s[0].cell() <= '9' ) + s[0] = '_'; + for ( int i = 0, j = 0; i < (int) s.length(); i++ ) { + uchar r = s[i].row(); + uchar c = s[i].cell(); + + if ( outParen ) { // check if we have 'const' or 'volatile' + static const QString con = " const"; + static const QString vol = " volatile"; + QString mid = s.mid( j ); + if ( !( con.startsWith( mid ) || vol.startsWith( mid ) ) ) + return QValidator::Invalid; + } + + if ( inParen && c != ')' ) + continue; + + if ( r == 0 && ( ( c >= '0' && c <= '9' ) || + ( c >= 'a' && c <= 'z' ) || + ( c >= 'A' && c <= 'Z' ) ) ) + continue; + + if ( functionName ) { + if ( c == '(' ) { + inParen = TRUE; + continue; + } + if ( c == ')' ) { + outParen = TRUE; + j = i + 1; + continue; + } + } + + if ( allowedChars.find( s[ i ] ) != -1 ) + continue; + + s[i] = '_'; + } + return QValidator::Acceptable; +} diff --git a/tools/designer/designer/asciivalidator.h b/tools/designer/designer/asciivalidator.h new file mode 100644 index 0000000..13bdced --- /dev/null +++ b/tools/designer/designer/asciivalidator.h @@ -0,0 +1,59 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef ASCIIVALIDATOR_H +#define ASCIIVALIDATOR_H + + +#include + + +class AsciiValidator: public QValidator +{ + Q_OBJECT +public: + AsciiValidator( QObject * parent, const char *name = 0 ); + AsciiValidator( bool funcName, QObject * parent, const char *name = 0 ); + AsciiValidator( const QString &allow, QObject * parent, const char *name = 0 ); + ~AsciiValidator(); + + QValidator::State validate( QString &, int & ) const; + +private: + bool functionName; + QString allowedChars; + +}; + + +#endif diff --git a/tools/designer/designer/command.cpp b/tools/designer/designer/command.cpp new file mode 100644 index 0000000..74a6b19 --- /dev/null +++ b/tools/designer/designer/command.cpp @@ -0,0 +1,2402 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ +#include "command.h" +#include "formwindow.h" +#include "widgetfactory.h" +#include "propertyeditor.h" +#include "metadatabase.h" +#include +#include "mainwindow.h" +#include "hierarchyview.h" +#include "workspace.h" +#include "actioneditorimpl.h" +#include "actiondnd.h" +#include "formfile.h" +#include "../interfaces/languageinterface.h" +#include "menubareditor.h" +#include "popupmenueditor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef QT_NO_TABLE +#include +#endif +#include + +CommandHistory::CommandHistory( int s ) + : current( -1 ), steps( s ), savedAt( -1 ) +{ + history.setAutoDelete( TRUE ); + modified = FALSE; + compressedCommand = 0; +} + +void CommandHistory::addCommand( Command *cmd, bool tryCompress ) +{ + if ( tryCompress ) { + if ( !compressedCommand || + compressedCommand->type() != cmd->type() || + !compressedCommand->canMerge( cmd ) ) { + checkCompressedCommand(); + compressedCommand = 0; + } + + if ( compressedCommand ) { + compressedCommand->merge( cmd ); + modified = TRUE; + modificationChanged( modified ); + return; + } + compressedCommand = cmd; + } else { + checkCompressedCommand(); + } + + if ( current < (int)history.count() - 1 ) { + if ( current < savedAt ) + savedAt = -2; + + QPtrList commands; + commands.setAutoDelete( FALSE ); + + for( int i = 0; i <= current; ++i ) { + commands.insert( i, history.at( 0 ) ); + history.take( 0 ); + } + + commands.append( cmd ); + history.clear(); + history = commands; + history.setAutoDelete( TRUE ); + } else { + history.append( cmd ); + } + + if ( (int)history.count() > steps ) { + savedAt--; + history.removeFirst(); + } else { + ++current; + } + + emitUndoRedo(); + modified = TRUE; + modificationChanged( modified ); +} + +void CommandHistory::undo() +{ + checkCompressedCommand(); + compressedCommand = 0; + if ( current > -1 ) { + history.at( current )->unexecute(); + --current; + } + emitUndoRedo(); + modified = savedAt != current; + modificationChanged( modified ); +} + +void CommandHistory::redo() +{ + checkCompressedCommand(); + compressedCommand = 0; + if ( current > -1 ) { + if ( current < (int)history.count() - 1 ) { + ++current; + history.at( current )->execute(); + } + } else { + if ( history.count() > 0 ) { + ++current; + history.at( current )->execute(); + } + } + emitUndoRedo(); + modified = savedAt != current; + modificationChanged( modified ); +} + +void CommandHistory::emitUndoRedo() +{ + Command *undoCmd = 0; + Command *redoCmd = 0; + + if ( current >= 0 && current < (int)history.count() ) + undoCmd = history.at( current ); + if ( current + 1 >= 0 && current + 1 < (int)history.count() ) + redoCmd = history.at( current + 1 ); + + bool ua = (undoCmd != 0); + QString uc; + if ( ua ) + uc = undoCmd->name(); + bool ra = (redoCmd != 0); + QString rc; + if ( ra ) + rc = redoCmd->name(); + emit undoRedoChanged( ua, ra, uc, rc ); +} + +void CommandHistory::setModified( bool m ) +{ + modified = m; + if ( !modified ) + savedAt = current; + modificationChanged( modified ); +} + +bool CommandHistory::isModified() const +{ + return modified; +} + +void CommandHistory::checkCompressedCommand() +{ + if ( compressedCommand && compressedCommand->type() == Command::SetProperty ) { + Command *c = compressedCommand; + compressedCommand = 0; + if ( !( (SetPropertyCommand*)c )->checkProperty() ) { + history.remove( current ); + --current; + emitUndoRedo(); + } + } +} + +// ------------------------------------------------------------ + +Command::Command( const QString &n, FormWindow *fw ) + : cmdName( n ), formWin( fw ) +{ +} + +Command::~Command() +{ +} + +QString Command::name() const +{ + return cmdName; +} + +FormWindow *Command::formWindow() const +{ + return formWin; +} + +void Command::merge( Command * ) +{ +} + +bool Command::canMerge( Command * ) +{ + return FALSE; +} + +// ------------------------------------------------------------ + +ResizeCommand::ResizeCommand( const QString &n, FormWindow *fw, + QWidget *w, const QRect &oldr, const QRect &nr ) + : Command( n, fw ), widget( w ), oldRect( oldr ), newRect( nr ) +{ +} + +void ResizeCommand::execute() +{ + widget->setGeometry( newRect ); + formWindow()->updateSelection( widget ); + formWindow()->emitUpdateProperties( widget ); + if ( WidgetFactory::layoutType( widget ) != WidgetFactory::NoLayout ) + formWindow()->updateChildSelections( widget ); +} + +void ResizeCommand::unexecute() +{ + widget->setGeometry( oldRect ); + formWindow()->updateSelection( widget ); + formWindow()->emitUpdateProperties( widget ); + if ( WidgetFactory::layoutType( widget ) != WidgetFactory::NoLayout ) + formWindow()->updateChildSelections( widget ); +} + +// ------------------------------------------------------------ + +InsertCommand::InsertCommand( const QString &n, FormWindow *fw, + QWidget *w, const QRect &g ) + : Command( n, fw ), widget( w ), geometry( g ) +{ +} + +void InsertCommand::execute() +{ + if ( geometry.size() == QSize( 0, 0 ) ) { + widget->move( geometry.topLeft() ); + widget->adjustSize(); + } else { + QSize s = geometry.size().expandedTo( widget->minimumSize() ); + s = s.expandedTo( widget->minimumSizeHint() ); + QRect r( geometry.topLeft(), s ); + widget->setGeometry( r ); + } + widget->show(); + formWindow()->widgets()->insert( widget, widget ); + formWindow()->clearSelection( FALSE ); + formWindow()->selectWidget( widget ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( widget ); +} + +void InsertCommand::unexecute() +{ + widget->hide(); + formWindow()->selectWidget( widget, FALSE ); + formWindow()->widgets()->remove( widget ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( widget ); + } + +// ------------------------------------------------------------ + +MoveCommand::MoveCommand( const QString &n, FormWindow *fw, + const QWidgetList &w, + const QValueList op, + const QValueList np, + QWidget *opr, QWidget *npr ) + : Command( n, fw ), widgets( w ), oldPos( op ), newPos( np ), + oldParent( opr ), newParent( npr ) +{ + widgets.setAutoDelete( FALSE ); +} + +void MoveCommand::merge( Command *c ) +{ + MoveCommand *cmd = (MoveCommand*)c; + newPos = cmd->newPos; +} + +bool MoveCommand::canMerge( Command *c ) +{ + MoveCommand *cmd = (MoveCommand*)c; + return widgets == cmd->widgets; +} + + +void MoveCommand::execute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) { + if ( newParent && oldParent && newParent != oldParent ) { + QPoint pos = newParent->mapFromGlobal( w->mapToGlobal( QPoint( 0,0 ) ) ); + w->reparent( newParent, pos, TRUE ); + formWindow()->raiseSelection( w ); + formWindow()->raiseChildSelections( w ); + formWindow()->widgetChanged( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( w ); + } + w->move( newPos[ widgets.at() ] ); + } + formWindow()->updateSelection( w ); + formWindow()->updateChildSelections( w ); + formWindow()->emitUpdateProperties( w ); + } +} + +void MoveCommand::unexecute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) { + if ( newParent && oldParent && newParent != oldParent ) { + QPoint pos = oldParent->mapFromGlobal( w->mapToGlobal( QPoint( 0,0 ) ) ); + w->reparent( oldParent, pos, TRUE ); + formWindow()->raiseSelection( w ); + formWindow()->raiseChildSelections( w ); + formWindow()->widgetChanged( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( w ); + } + w->move( oldPos[ widgets.at() ] ); + } + formWindow()->updateSelection( w ); + formWindow()->updateChildSelections( w ); + formWindow()->emitUpdateProperties( w ); + } +} + +// ------------------------------------------------------------ + +DeleteCommand::DeleteCommand( const QString &n, FormWindow *fw, + const QWidgetList &wl ) + : Command( n, fw ), widgets( wl ) +{ + widgets.setAutoDelete( FALSE ); + QWidgetList copyOfWidgets = widgets; + copyOfWidgets.setAutoDelete(FALSE); + + // Include the children of the selected items when deleting + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + QObjectList *children = w->queryList( "QWidget" ); + for ( QWidget *c = (QWidget *)children->first(); c; c = (QWidget *)children->next() ) { + if ( copyOfWidgets.find( c ) == -1 && formWindow()->widgets()->find( c ) ) { + widgets.insert(widgets.at() + 1, c); + widgets.prev(); + copyOfWidgets.append(c); + } + } + delete children; + } +} + +void DeleteCommand::execute() +{ + formWindow()->setPropertyShowingBlocked( TRUE ); + connections.clear(); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->hide(); + QString s = w->name(); + s.prepend( "qt_dead_widget_" ); + w->setName( s ); + formWindow()->selectWidget( w, FALSE ); + formWindow()->widgets()->remove( w ); + QValueList conns = MetaDataBase::connections( formWindow(), w ); + connections.insert( w, conns ); + QValueList::Iterator it = conns.begin(); + for ( ; it != conns.end(); ++it ) { + MetaDataBase::removeConnection( formWindow(), (*it).sender, + (*it).signal, (*it).receiver, (*it).slot ); + } + } + formWindow()->setPropertyShowingBlocked( FALSE ); + formWindow()->emitShowProperties(); + formWindow()->mainWindow()->objectHierarchy()->widgetsRemoved( widgets ); + +} + +void DeleteCommand::unexecute() +{ + formWindow()->setPropertyShowingBlocked( TRUE ); + formWindow()->clearSelection( FALSE ); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->show(); + QString s = w->name(); + s.remove( 0, QString( "qt_dead_widget_" ).length() ); + w->setName( s ); + formWindow()->widgets()->insert( w, w ); + formWindow()->selectWidget( w ); + QValueList conns = *connections.find( w ); + QValueList::Iterator it = conns.begin(); + for ( ; it != conns.end(); ++it ) { + MetaDataBase::addConnection( formWindow(), (*it).sender, + (*it).signal, (*it).receiver, (*it).slot ); + } + } + formWindow()->setPropertyShowingBlocked( FALSE ); + formWindow()->emitShowProperties(); + formWindow()->mainWindow()->objectHierarchy()->widgetsInserted( widgets ); +} + +// ------------------------------------------------------------ + +SetPropertyCommand::SetPropertyCommand( const QString &n, FormWindow *fw, + QObject *w, PropertyEditor *e, + const QString &pn, const QVariant &ov, + const QVariant &nv, const QString &ncut, + const QString &ocut, bool reset ) + : Command( n, fw ), widget( w ), editor( e ), propName( pn ), + oldValue( ov ), newValue( nv ), oldCurrentItemText( ocut ), newCurrentItemText( ncut ), + wasChanged( TRUE ), isResetCommand( reset ) +{ + wasChanged = MetaDataBase::isPropertyChanged( w, propName ); + if ( oldCurrentItemText.isNull() ) + oldCurrentItemText = ""; + if ( newCurrentItemText.isNull() ) + newCurrentItemText = ""; +} + + +void SetPropertyCommand::execute() +{ + if ( !wasChanged ) + MetaDataBase::setPropertyChanged( widget, propName, TRUE ); + if ( isResetCommand ) { + MetaDataBase::setPropertyChanged( widget, propName, FALSE ); + if ( WidgetFactory::resetProperty( widget, propName ) ) { + if ( !formWindow()->isWidgetSelected( widget ) && formWindow() != (QObject *)widget ) + formWindow()->selectWidget( (QObject *)widget ); + if ( editor->widget() != widget ) + editor->setWidget( widget, formWindow() ); + editor->propertyList()->setCurrentProperty( propName ); + PropertyItem *i = (PropertyItem*)editor->propertyList()->currentItem(); + if ( !i ) + return; + i->setValue( widget->property( propName ) ); + i->setChanged( FALSE ); + editor->refetchData(); + editor->emitWidgetChanged(); + return; + } + } + setProperty( newValue, newCurrentItemText ); +} + +void SetPropertyCommand::unexecute() +{ + if ( !wasChanged ) + MetaDataBase::setPropertyChanged( widget, propName, FALSE ); + if ( isResetCommand ) + MetaDataBase::setPropertyChanged( widget, propName, TRUE ); + setProperty( oldValue, oldCurrentItemText ); +} + +bool SetPropertyCommand::canMerge( Command *c ) +{ + SetPropertyCommand *cmd = (SetPropertyCommand*)c; + if ( !widget ) + return FALSE; + const QMetaProperty *p = + widget->metaObject()->property( widget->metaObject()->findProperty( propName, TRUE ), TRUE ); + if ( !p ) { + if ( propName == "toolTip" || propName == "whatsThis" ) + return TRUE; + if ( ::qt_cast((QObject *)widget) ) { + MetaDataBase::CustomWidget *cw = ((CustomWidget*)(QObject*)widget)->customWidget(); + if ( !cw ) + return FALSE; + for ( QValueList::Iterator it = cw->lstProperties.begin(); it != cw->lstProperties.end(); ++it ) { + if ( QString( (*it ).property ) == propName ) { + if ( (*it).type == "String" || (*it).type == "CString" || (*it).type == "Int" || (*it).type == "UInt" ) + return TRUE; + } + } + } + return FALSE; + } + QVariant::Type t = QVariant::nameToType( p->type() ); + return ( cmd->propName == propName && + t == QVariant::String || t == QVariant::CString || t == QVariant::Int || t == QVariant::UInt ); +} + +void SetPropertyCommand::merge( Command *c ) +{ + SetPropertyCommand *cmd = (SetPropertyCommand*)c; + newValue = cmd->newValue; + newCurrentItemText = cmd->newCurrentItemText; +} + +bool SetPropertyCommand::checkProperty() +{ + if ( propName == "name" /*|| propName == "itemName"*/ ) { // ### fix that + QString s = newValue.toString(); + if ( !formWindow()->unify( widget, s, FALSE ) ) { + QMessageBox::information( formWindow()->mainWindow(), + FormWindow::tr( "Set 'name' property" ), + FormWindow::tr( "The name of a widget must be unique.\n" + "'%1' is already used in form '%2',\n" + "so the name has been reverted to '%3'." ). + arg( newValue.toString() ). + arg( formWindow()->name() ). + arg( oldValue.toString() )); + setProperty( oldValue, oldCurrentItemText, FALSE ); + return FALSE; + } + if ( s.isEmpty() ) { + QMessageBox::information( formWindow()->mainWindow(), + FormWindow::tr( "Set 'name' property" ), + FormWindow::tr( "The name of a widget must not be null.\n" + "The name has been reverted to '%1'." ). + arg( oldValue.toString() )); + setProperty( oldValue, oldCurrentItemText, FALSE ); + return FALSE; + } + + if ( ::qt_cast(widget->parent()) ) + formWindow()->mainWindow()->formNameChanged( (FormWindow*)((QWidget*)(QObject*)widget)->parentWidget() ); + } + return TRUE; +} + +void SetPropertyCommand::setProperty( const QVariant &v, const QString ¤tItemText, bool select ) +{ + if ( !widget ) + return; + + if ( !formWindow()->isWidgetSelected( widget ) && !formWindow()->isMainContainer( widget ) && select ) + formWindow()->selectWidget( widget ); + if ( editor->widget() != widget && select ) + editor->setWidget( widget, formWindow() ); + if ( select ) + editor->propertyList()->setCurrentProperty( propName ); + const QMetaProperty *p = + widget->metaObject()->property( widget->metaObject()->findProperty( propName, TRUE ), TRUE ); + if ( !p ) { + if ( propName == "hAlign" ) { + p = widget->metaObject()->property( widget->metaObject()->findProperty( "alignment", TRUE ), TRUE ); + int align = widget->property( "alignment" ).toInt(); + align &= ~( AlignHorizontal_Mask ); + align |= p->keyToValue( currentItemText ); + widget->setProperty( "alignment", QVariant( align ) ); + } else if ( propName == "vAlign" ) { + p = widget->metaObject()->property( widget->metaObject()->findProperty( "alignment", TRUE ), TRUE ); + int align = widget->property( "alignment" ).toInt(); + align &= ~( AlignVertical_Mask ); + align |= p->keyToValue( currentItemText ); + widget->setProperty( "alignment", QVariant( align ) ); + } else if ( propName == "wordwrap" ) { + int align = widget->property( "alignment" ).toInt(); + align &= ~WordBreak; + if ( v.toBool() ) + align |= WordBreak; + widget->setProperty( "alignment", QVariant( align ) ); + } else if ( propName == "layoutSpacing" ) { + QVariant val = v; + if ( val.toString() == "default" ) + val = -1; + MetaDataBase::setSpacing( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ), val.toInt() ); + } else if ( propName == "layoutMargin" ) { + QVariant val = v; + if ( val.toString() == "default" ) + val = -1; + MetaDataBase::setMargin( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ), val.toInt() ); + } else if ( propName == "resizeMode" ) { + MetaDataBase::setResizeMode( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ), currentItemText ); + } else if ( propName == "toolTip" || propName == "whatsThis" || propName == "database" || propName == "frameworkCode" ) { + MetaDataBase::setFakeProperty( editor->widget(), propName, v ); + } else if ( ::qt_cast(editor->widget()) ) { + MetaDataBase::CustomWidget *cw = ((CustomWidget *)(QObject *)widget)->customWidget(); + if ( cw ) { + MetaDataBase::setFakeProperty( editor->widget(), propName, v ); + } + } + editor->refetchData(); + editor->emitWidgetChanged(); + ( ( PropertyItem* )editor->propertyList()->currentItem() )->setChanged( MetaDataBase::isPropertyChanged( widget, propName ) ); +#ifndef QT_NO_SQL + if ( propName == "database" ) { + formWindow()->mainWindow()->objectHierarchy()->databasePropertyChanged( (QWidget*)((QObject *)widget), MetaDataBase::fakeProperty( widget, "database" ).toStringList() ); + } +#endif + return; + } + + if ( p->isSetType() ) { + QStrList strlst; + QStringList lst = QStringList::split( "|", currentItemText ); + QValueListConstIterator it = lst.begin(); + for ( ; it != lst.end(); ++it ) + strlst.append( (*it).latin1() ); + widget->setProperty( propName, p->keysToValue( strlst ) ); + } else if ( p->isEnumType() ) { + widget->setProperty( propName, p->keyToValue( currentItemText ) ); + } else if ( qstrcmp( p->name(), "buddy" ) == 0 ) { + widget->setProperty( propName, currentItemText ); + } else { + QVariant ov; + if ( propName == "name" || propName == "itemName" ) + ov = widget->property( propName ); + int oldSerNum = -1; + if ( v.type() == QVariant::Pixmap ) + oldSerNum = v.toPixmap().serialNumber(); + widget->setProperty( propName, v ); + if ( oldSerNum != -1 && oldSerNum != widget->property( propName ).toPixmap().serialNumber() ) + MetaDataBase::setPixmapKey( formWindow(), + widget->property( propName ).toPixmap().serialNumber(), + MetaDataBase::pixmapKey( formWindow(), oldSerNum ) ); + if ( propName == "cursor" ) { + MetaDataBase::setCursor( (QWidget*)((QObject *)widget), v.toCursor() ); + } + if ( propName == "name" && widget->isWidgetType() ) { + formWindow()->mainWindow()->objectHierarchy()->namePropertyChanged( ((QWidget*)(QObject *)widget), ov ); + if ( formWindow()->isMainContainer( widget ) ) + formWindow()->setName( v.toCString() ); + } + if ( propName == "name" && ::qt_cast((QObject *)widget) && ::qt_cast(formWindow()->mainContainer()) ) { + formWindow()->mainWindow()->actioneditor()->updateActionName( (QAction*)(QObject *)widget ); + } + if ( propName == "iconSet" && ::qt_cast((QObject *)widget) && ::qt_cast(formWindow()->mainContainer()) ) { + formWindow()->mainWindow()->actioneditor()->updateActionIcon( (QAction*)(QObject *)widget ); + } + if ( propName == "caption" ) { + if ( formWindow()->isMainContainer( widget ) ) + formWindow()->setCaption( v.toString() ); + } + if ( propName == "icon" ) { + if ( formWindow()->isMainContainer( widget ) ) + formWindow()->setIcon( v.toPixmap() ); + } + } + editor->refetchData(); + if ( editor->propertyList()->currentItem() && select ) { + ( ( PropertyItem* )editor->propertyList()->currentItem() )->showEditor(); + ( ( PropertyItem* )editor->propertyList()->currentItem() )->setChanged( MetaDataBase::isPropertyChanged( widget, propName ) ); + } + editor->emitWidgetChanged(); + formWindow()->killAccels( widget ); +} + +// ------------------------------------------------------------ + +LayoutHorizontalCommand::LayoutHorizontalCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase ) +{ +} + +void LayoutHorizontalCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutHorizontalCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +LayoutHorizontalSplitCommand::LayoutHorizontalSplitCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase, TRUE, TRUE ) +{ +} + +void LayoutHorizontalSplitCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutHorizontalSplitCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +LayoutVerticalCommand::LayoutVerticalCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase ) +{ +} + +void LayoutVerticalCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutVerticalCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +LayoutVerticalSplitCommand::LayoutVerticalSplitCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase, TRUE, TRUE ) +{ +} + +void LayoutVerticalSplitCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutVerticalSplitCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +LayoutGridCommand::LayoutGridCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl, int xres, int yres ) + : Command( n, fw ), layout( wl, parent, fw, layoutBase, QSize( QMAX(5,xres), QMAX(5,yres) ) ) +{ +} + +void LayoutGridCommand::execute() +{ + formWindow()->clearSelection( FALSE ); + layout.doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void LayoutGridCommand::unexecute() +{ + formWindow()->clearSelection( FALSE ); + layout.undoLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +BreakLayoutCommand::BreakLayoutCommand( const QString &n, FormWindow *fw, + QWidget *layoutBase, const QWidgetList &wl ) + : Command( n, fw ), lb( layoutBase ), widgets( wl ) +{ + WidgetFactory::LayoutType lay = WidgetFactory::layoutType( layoutBase ); + spacing = MetaDataBase::spacing( layoutBase ); + margin = MetaDataBase::margin( layoutBase ); + layout = 0; + if ( lay == WidgetFactory::HBox ) + layout = new HorizontalLayout( wl, layoutBase, fw, layoutBase, FALSE, ::qt_cast(layoutBase) != 0 ); + else if ( lay == WidgetFactory::VBox ) + layout = new VerticalLayout( wl, layoutBase, fw, layoutBase, FALSE, ::qt_cast(layoutBase) != 0 ); + else if ( lay == WidgetFactory::Grid ) + layout = new GridLayout( wl, layoutBase, fw, layoutBase, QSize( QMAX( 5, fw->grid().x()), QMAX( 5, fw->grid().y()) ), FALSE ); +} + +void BreakLayoutCommand::execute() +{ + if ( !layout ) + return; + formWindow()->clearSelection( FALSE ); + layout->breakLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) + w->resize( QMAX( 16, w->width() ), QMAX( 16, w->height() ) ); +} + +void BreakLayoutCommand::unexecute() +{ + if ( !layout ) + return; + formWindow()->clearSelection( FALSE ); + layout->doLayout(); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); + MetaDataBase::setSpacing( WidgetFactory::containerOfWidget( lb ), spacing ); + MetaDataBase::setMargin( WidgetFactory::containerOfWidget( lb ), margin ); +} + +// ------------------------------------------------------------ + +MacroCommand::MacroCommand( const QString &n, FormWindow *fw, + const QPtrList &cmds ) + : Command( n, fw ), commands( cmds ) +{ +} + +void MacroCommand::execute() +{ + for ( Command *c = commands.first(); c; c = commands.next() ) + c->execute(); +} + +void MacroCommand::unexecute() +{ + for ( Command *c = commands.last(); c; c = commands.prev() ) + c->unexecute(); +} + +// ------------------------------------------------------------ + +AddTabPageCommand::AddTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, const QString &label ) + : Command( n, fw ), tabWidget( tw ), tabLabel( label ) +{ + tabPage = new QDesignerWidget( formWindow(), tabWidget, "TabPage" ); + tabPage->hide(); + index = -1; + MetaDataBase::addEntry( tabPage ); +} + +void AddTabPageCommand::execute() +{ + if ( index == -1 ) + index = ( (QDesignerTabWidget*)tabWidget )->count(); + tabWidget->insertTab( tabPage, tabLabel, index ); + tabWidget->showPage( tabPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +void AddTabPageCommand::unexecute() +{ + tabWidget->removePage( tabPage ); + tabPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +// ------------------------------------------------------------ + +MoveTabPageCommand::MoveTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, QWidget* page, const QString& label, int nIndex, int oIndex ) + : Command( n, fw ), tabWidget( tw ), tabPage( page ), tabLabel( label ) +{ + newIndex = nIndex; + oldIndex = oIndex; +} + +void MoveTabPageCommand::execute() +{ + ((QDesignerTabWidget*)tabWidget )->removePage( tabPage ); + ((QDesignerTabWidget*)tabWidget )->insertTab( tabPage, tabLabel, newIndex ); + ((QDesignerTabWidget*)tabWidget )->showPage( tabPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +void MoveTabPageCommand::unexecute() +{ + ((QDesignerTabWidget*)tabWidget )->removePage( tabPage ); + ((QDesignerTabWidget*)tabWidget )->insertTab( tabPage, tabLabel, oldIndex ); + ((QDesignerTabWidget*)tabWidget )->showPage( tabPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +// ------------------------------------------------------------ + +DeleteTabPageCommand::DeleteTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, QWidget *page ) + : Command( n, fw ), tabWidget( tw ), tabPage( page ) +{ + tabLabel = ( (QDesignerTabWidget*)tabWidget )->pageTitle(); + index = ( (QDesignerTabWidget*)tabWidget )->currentPage(); +} + +void DeleteTabPageCommand::execute() +{ + tabWidget->removePage( tabPage ); + tabPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +void DeleteTabPageCommand::unexecute() +{ + tabWidget->insertTab( tabPage, tabLabel, index ); + tabWidget->showPage( tabPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( tabWidget ); +} + +// ------------------------------------------------------------ + +AddWidgetStackPageCommand::AddWidgetStackPageCommand( const QString &n, FormWindow *fw, + QDesignerWidgetStack *ws ) + : Command( n, fw ), widgetStack( ws ) +{ + stackPage = new QDesignerWidget( formWindow(), widgetStack, "WStackPage" ); + stackPage->hide(); + index = -1; + MetaDataBase::addEntry( stackPage ); +} + +void AddWidgetStackPageCommand::execute() +{ + index = widgetStack->insertPage( stackPage, index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( 0 ); +} + +void AddWidgetStackPageCommand::unexecute() +{ + index = widgetStack->removePage( stackPage ); + stackPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->tabsChanged( 0 ); +} + +DeleteWidgetStackPageCommand::DeleteWidgetStackPageCommand( const QString &n, FormWindow *fw, + QDesignerWidgetStack *ws, QWidget *page ) + : Command( n, fw), widgetStack( ws ), stackPage( page ) +{ + index = -1; +} + +void DeleteWidgetStackPageCommand::execute() +{ + index = widgetStack->removePage( stackPage ); + stackPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( stackPage ); +} + +void DeleteWidgetStackPageCommand::unexecute() +{ + index = widgetStack->insertPage( stackPage, index ); + widgetStack->raiseWidget( stackPage ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( stackPage ); +} + +// ------------------------------------------------------------ + +AddWizardPageCommand::AddWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, const QString &label, int i, bool s ) + : Command( n, fw ), wizard( w ), pageLabel( label ) +{ + page = new QDesignerWidget( formWindow(), wizard, "WizardPage" ); + page->hide(); + index = i; + show = s; + MetaDataBase::addEntry( page ); +} + +void AddWizardPageCommand::execute() +{ + if ( index == -1 ) + index = wizard->pageCount(); + wizard->insertPage( page, pageLabel, index ); + if ( show ) + ( (QDesignerWizard*)wizard )->setCurrentPage( ( (QDesignerWizard*)wizard )->pageNum( page ) ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +void AddWizardPageCommand::unexecute() +{ + wizard->removePage( page ); + page->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +// ------------------------------------------------------------ + +DeleteWizardPageCommand::DeleteWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int i, bool s ) + : Command( n, fw ), wizard( w ), index( i ) +{ + show = s; +} + +void DeleteWizardPageCommand::execute() +{ + page = wizard->page( index ); + pageLabel = wizard->title( page ); + wizard->removePage( page ); + page->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +void DeleteWizardPageCommand::unexecute() +{ + wizard->insertPage( page, pageLabel, index ); + if ( show ) + ( (QDesignerWizard*)wizard )->setCurrentPage( ( (QDesignerWizard*)wizard )->pageNum( page ) ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +// ------------------------------------------------------------ + +RenameWizardPageCommand::RenameWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int i, const QString& name ) + : Command( n, fw ), wizard( w ), index( i ), label( name ) +{ + +} + +void RenameWizardPageCommand::execute() +{ + page = wizard->page( index ); + QString oldLabel = wizard->title( page ); + + wizard->setTitle( page, label ); + label = oldLabel; + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); +} + +void RenameWizardPageCommand::unexecute() +{ + execute(); +} + +// ------------------------------------------------------------ + +SwapWizardPagesCommand::SwapWizardPagesCommand( const QString &n, FormWindow *fw, QWizard *w, int i1, int i2 ) + : Command( n, fw ), wizard( w ), index1( i1 ), index2( i2 ) +{ +} + +void SwapWizardPagesCommand::execute() +{ + QWidget *page1 = wizard->page( index1 ); + QWidget *page2 = wizard->page( index2 ); + QString page1Label = wizard->title( page1 ); + QString page2Label = wizard->title( page2 ); + wizard->removePage( page1 ); + wizard->removePage( page2 ); + wizard->insertPage( page1, page1Label, index2 ); + wizard->insertPage( page2, page2Label, index1 ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +void SwapWizardPagesCommand::unexecute() +{ + execute(); +} + +// ------------------------------------------------------------ + +MoveWizardPageCommand::MoveWizardPageCommand( const QString &n, FormWindow *fw, QWizard *w, int i1, int i2 ) + : Command( n, fw ), wizard( w ), index1( i1 ), index2( i2 ) +{ +} + +void MoveWizardPageCommand::execute() +{ + QWidget *page = wizard->page( index1 ); + QString pageLabel = wizard->title( page ); + wizard->removePage( page ); + wizard->insertPage( page, pageLabel, index2 ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +void MoveWizardPageCommand::unexecute() +{ + // ###FIX: index1 may be the wrong place + QWidget *page = wizard->page( index2 ); + QString pageLabel = wizard->title( page ); + wizard->removePage( page ); + wizard->insertPage( page, pageLabel, index1 ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->pagesChanged( wizard ); +} + +// ------------------------------------------------------------ + +AddConnectionCommand::AddConnectionCommand( const QString &name, FormWindow *fw, + MetaDataBase::Connection c ) + : Command( name, fw ), connection( c ) +{ +} + +void AddConnectionCommand::execute() +{ + MetaDataBase::addConnection( formWindow(), connection.sender, + connection.signal, connection.receiver, connection.slot ); + if ( connection.receiver == formWindow()->mainContainer() ) + formWindow()->mainWindow()->propertyeditor()->eventList()->setup(); +} + +void AddConnectionCommand::unexecute() +{ + MetaDataBase::removeConnection( formWindow(), connection.sender, + connection.signal, connection.receiver, connection.slot ); + if ( connection.receiver == formWindow()->mainContainer() ) + formWindow()->mainWindow()->propertyeditor()->eventList()->setup(); +} + +// ------------------------------------------------------------ + +RemoveConnectionCommand::RemoveConnectionCommand( const QString &name, FormWindow *fw, + MetaDataBase::Connection c ) + : Command( name, fw ), connection( c ) +{ +} + +void RemoveConnectionCommand::execute() +{ + MetaDataBase::removeConnection( formWindow(), connection.sender, + connection.signal, connection.receiver, connection.slot ); + if ( connection.receiver == formWindow()->mainContainer() ) + formWindow()->mainWindow()->propertyeditor()->eventList()->setup(); +} + +void RemoveConnectionCommand::unexecute() +{ + MetaDataBase::addConnection( formWindow(), connection.sender, + connection.signal, connection.receiver, connection.slot ); + if ( connection.receiver == formWindow()->mainContainer() ) + formWindow()->mainWindow()->propertyeditor()->eventList()->setup(); +} + +// ------------------------------------------------------------ + +AddFunctionCommand::AddFunctionCommand( const QString &name, FormWindow *fw, const QCString &f, + const QString& spec, const QString &a, const QString &t, + const QString &l, const QString &rt ) + : Command( name, fw ), function( f ), specifier( spec ), access( a ), functionType( t ), language( l ), + returnType( rt ) +{ +} + +void AddFunctionCommand::execute() +{ + MetaDataBase::addFunction( formWindow(), function, specifier, access, functionType, language, returnType ); + formWindow()->mainWindow()->functionsChanged(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void AddFunctionCommand::unexecute() +{ + MetaDataBase::removeFunction( formWindow(), function, specifier, access, functionType, language, returnType ); + formWindow()->mainWindow()->functionsChanged(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +ChangeFunctionAttribCommand::ChangeFunctionAttribCommand( const QString &name, FormWindow *fw, MetaDataBase::Function f, + const QString &on, const QString &os, + const QString &oa, const QString &ot, const QString &ol, + const QString &ort ) + : Command( name, fw ), oldName( on ), oldSpec( os ), oldAccess( oa ), + oldType( ot ), oldLang( ol ), oldReturnType( ort ) +{ + newName = f.function; + newSpec = f.specifier; + newAccess = f.access; + newType = f.type; + newLang = f.language; + newReturnType = f.returnType; +} + +void ChangeFunctionAttribCommand::execute() +{ + MetaDataBase::changeFunctionAttributes( formWindow(), oldName, newName, newSpec, newAccess, + newType, newLang, newReturnType ); + formWindow()->formFile()->functionNameChanged( oldName, newName ); + formWindow()->formFile()->functionRetTypeChanged( newName, oldReturnType, newReturnType ); + formWindow()->mainWindow()->functionsChanged(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void ChangeFunctionAttribCommand::unexecute() +{ + MetaDataBase::changeFunctionAttributes( formWindow(), newName, oldName, oldSpec, oldAccess, + oldType, oldLang, oldReturnType ); + formWindow()->formFile()->functionNameChanged( newName, oldName ); + formWindow()->formFile()->functionRetTypeChanged( oldName, newReturnType, oldReturnType ); + formWindow()->mainWindow()->functionsChanged(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +RemoveFunctionCommand::RemoveFunctionCommand( const QString &name, FormWindow *fw, const QCString &f, + const QString& spec, const QString &a, const QString &t, + const QString &l, const QString &rt ) + : Command( name, fw ), function( f ), specifier( spec ), access( a ), functionType( t ), language( l ), + returnType( rt ) +{ + if ( spec.isNull() ) { + QValueList lst = MetaDataBase::functionList( fw ); + for ( QValueList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + if ( MetaDataBase::normalizeFunction( (*it).function ) == + MetaDataBase::normalizeFunction( function ) ) { + specifier = (*it).specifier; + access = (*it).access; + functionType = (*it).type; + returnType = (*it).returnType; + language = (*it).language; + break; + } + } + } +} + +void RemoveFunctionCommand::execute() +{ + MetaDataBase::removeFunction( formWindow(), function, specifier, access, functionType, language, returnType ); + formWindow()->mainWindow()->functionsChanged(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void RemoveFunctionCommand::unexecute() +{ + if ( MetaDataBase::hasFunction( formWindow(), function ) ) + return; + MetaDataBase::addFunction( formWindow(), function, specifier, access, functionType, language, returnType ); + formWindow()->mainWindow()->functionsChanged(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +AddVariableCommand::AddVariableCommand( const QString &name, FormWindow *fw, const QString &vn, const QString &a ) + : Command( name, fw ), varName( vn ), access( a ) +{ +} + +void AddVariableCommand::execute() +{ + MetaDataBase::addVariable( formWindow(), varName, access ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void AddVariableCommand::unexecute() +{ + MetaDataBase::removeVariable( formWindow(), varName ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +SetVariablesCommand::SetVariablesCommand( const QString &name, FormWindow *fw, + QValueList lst ) + : Command( name, fw ), newList( lst ) +{ + oldList = MetaDataBase::variables( formWindow() ); +} + +void SetVariablesCommand::execute() +{ + MetaDataBase::setVariables( formWindow(), newList ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void SetVariablesCommand::unexecute() +{ + MetaDataBase::setVariables( formWindow(), oldList ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +RemoveVariableCommand::RemoveVariableCommand( const QString &name, FormWindow *fw, const QString &vn ) + : Command( name, fw ), varName( vn ) +{ + QValueList lst = MetaDataBase::variables( fw ); + for ( QValueList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + if ( (*it).varName == varName ) { + access = (*it).varAccess; + break; + } + } +} + +void RemoveVariableCommand::execute() +{ + MetaDataBase::removeVariable( formWindow(), varName ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void RemoveVariableCommand::unexecute() +{ + MetaDataBase::addVariable( formWindow(), varName, access ); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +EditDefinitionsCommand::EditDefinitionsCommand( const QString &name, FormWindow *fw, LanguageInterface *lf, + const QString &n, const QStringList &nl ) + : Command( name, fw ), lIface( lf ), defName( n ), newList( nl ) +{ + oldList = lIface->definitionEntries( defName, formWindow()->mainWindow()->designerInterface() ); +} + +void EditDefinitionsCommand::execute() +{ + lIface->setDefinitionEntries( defName, newList, formWindow()->mainWindow()->designerInterface() ); + lIface->release(); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +void EditDefinitionsCommand::unexecute() +{ + lIface->setDefinitionEntries( defName, oldList, formWindow()->mainWindow()->designerInterface() ); + lIface->release(); + formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + if ( formWindow()->formFile() ) + formWindow()->formFile()->setModified( TRUE ); +} + +// ------------------------------------------------------------ + +LowerCommand::LowerCommand( const QString &name, FormWindow *fw, const QWidgetList &w ) + : Command( name, fw ), widgets( w ) +{ +} + +void LowerCommand::execute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->lower(); + formWindow()->raiseSelection( w ); + } + +} + +void LowerCommand::unexecute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->raise(); + formWindow()->raiseSelection( w ); + } +} + +// ------------------------------------------------------------ + +RaiseCommand::RaiseCommand( const QString &name, FormWindow *fw, const QWidgetList &w ) + : Command( name, fw ), widgets( w ) +{ +} + +void RaiseCommand::execute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->raise(); + formWindow()->raiseSelection( w ); + } + +} + +void RaiseCommand::unexecute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->lower(); + formWindow()->raiseSelection( w ); + } +} + +// ------------------------------------------------------------ + +PasteCommand::PasteCommand( const QString &n, FormWindow *fw, + const QWidgetList &w ) + : Command( n, fw ), widgets( w ) +{ +} + +void PasteCommand::execute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->show(); + formWindow()->selectWidget( w ); + formWindow()->widgets()->insert( w, w ); + formWindow()->mainWindow()->objectHierarchy()->widgetInserted( w ); + } +} + +void PasteCommand::unexecute() +{ + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + w->hide(); + formWindow()->selectWidget( w, FALSE ); + formWindow()->widgets()->remove( w ); + formWindow()->mainWindow()->objectHierarchy()->widgetRemoved( w ); + } + } + +// ------------------------------------------------------------ + +TabOrderCommand::TabOrderCommand( const QString &n, FormWindow *fw, + const QWidgetList &ol, const QWidgetList &nl ) + : Command( n, fw ), oldOrder( ol ), newOrder( nl ) +{ +} + +void TabOrderCommand::merge( Command *c ) +{ + TabOrderCommand *cmd = (TabOrderCommand*)c; + newOrder = cmd->newOrder; +} + +bool TabOrderCommand::canMerge( Command * ) +{ + return TRUE; +} + +void TabOrderCommand::execute() +{ + MetaDataBase::setTabOrder( formWindow(), newOrder ); +} + +void TabOrderCommand::unexecute() +{ + MetaDataBase::setTabOrder( formWindow(), oldOrder ); +} + +// ------------------------------------------------------------ + +PopulateListBoxCommand::PopulateListBoxCommand( const QString &n, FormWindow *fw, + QListBox *lb, const QValueList &items ) + : Command( n, fw ), newItems( items ), listbox( lb ) +{ + QListBoxItem *i = 0; + for ( i = listbox->firstItem(); i; i = i->next() ) { + Item item; + if ( i->pixmap() ) + item.pix = *i->pixmap(); + item.text = i->text(); + oldItems.append( item ); + } +} + +void PopulateListBoxCommand::execute() +{ + listbox->clear(); + for ( QValueList::Iterator it = newItems.begin(); it != newItems.end(); ++it ) { + Item i = *it; + if ( !i.pix.isNull() ) + (void)new QListBoxPixmap( listbox, i.pix, i.text ); + else + (void)new QListBoxText( listbox, i.text ); + } + formWindow()->mainWindow()->propertyeditor()->refetchData(); +} + +void PopulateListBoxCommand::unexecute() +{ + listbox->clear(); + for ( QValueList::Iterator it = oldItems.begin(); it != oldItems.end(); ++it ) { + Item i = *it; + if ( !i.pix.isNull() ) + (void)new QListBoxPixmap( listbox, i.pix, i.text ); + else + (void)new QListBoxText( listbox, i.text ); + } + formWindow()->mainWindow()->propertyeditor()->refetchData(); +} + +// ------------------------------------------------------------ + +PopulateIconViewCommand::PopulateIconViewCommand( const QString &n, FormWindow *fw, + QIconView *iv, const QValueList &items ) + : Command( n, fw ), newItems( items ), iconview( iv ) +{ +#ifndef QT_NO_ICONVIEW + QIconViewItem *i = 0; + for ( i = iconview->firstItem(); i; i = i->nextItem() ) { + Item item; + if ( i->pixmap() ) + item.pix = *i->pixmap(); + item.text = i->text(); + oldItems.append( item ); + } +#endif +} + +void PopulateIconViewCommand::execute() +{ +#ifndef QT_NO_ICONVIEW + iconview->clear(); + for ( QValueList::Iterator it = newItems.begin(); it != newItems.end(); ++it ) { + Item i = *it; + (void)new QIconViewItem( iconview, i.text, i.pix ); + } +#endif +} + +void PopulateIconViewCommand::unexecute() +{ +#ifndef QT_NO_ICONVIEW + iconview->clear(); + for ( QValueList::Iterator it = oldItems.begin(); it != oldItems.end(); ++it ) { + Item i = *it; + (void)new QIconViewItem( iconview, i.text, i.pix ); + } +#endif +} + +// ------------------------------------------------------------ + +PopulateListViewCommand::PopulateListViewCommand( const QString &n, FormWindow *fw, + QListView *lv, QListView *from ) + : Command( n, fw ), listview( lv ) +{ + newItems = new QListView(); + newItems->hide(); + transferItems( from, newItems ); + oldItems = new QListView(); + oldItems->hide(); + transferItems( listview, oldItems ); +} + +void PopulateListViewCommand::execute() +{ + listview->clear(); + transferItems( newItems, listview ); +} + +void PopulateListViewCommand::unexecute() +{ + listview->clear(); + transferItems( oldItems, listview ); +} + +void PopulateListViewCommand::transferItems( QListView *from, QListView *to ) +{ + QHeader *header = to->header(); + while ( header->count() ) + to->removeColumn( 0 ); + QHeader *h2 = from->header(); + for ( int i = 0; i < h2->count(); ++i ) { + to->addColumn( h2->label( i ) ); + if ( h2->iconSet( i ) && !h2->iconSet( i )->pixmap().isNull() ) + header->setLabel( i, *h2->iconSet( i ), h2->label( i ) ); + header->setResizeEnabled( h2->isResizeEnabled( i ), i ); + header->setClickEnabled( h2->isClickEnabled( i ), i ); + } + + QListViewItemIterator it( from ); + QPtrStack fromParents, toParents; + fromParents.push( 0 ); + toParents.push( 0 ); + QPtrStack toLasts; + QListViewItem *fromLast = 0; + toLasts.push( 0 ); + int cols = from->columns(); + to->setSorting( -1 ); + from->setSorting( -1 ); + for ( ; it.current(); ++it ) { + QListViewItem *i = it.current(); + if ( i->parent() == fromParents.top() ) { + QListViewItem *pi = toParents.top(); + QListViewItem *ni = 0; + if ( pi ) + ni = new QListViewItem( pi, toLasts.top() ); + else + ni = new QListViewItem( to, toLasts.top() ); + for ( int c = 0; c < cols; ++c ) { + ni->setText( c, i->text( c ) ); + if ( i->pixmap( c ) ) + ni->setPixmap( c, *i->pixmap( c ) ); + } + toLasts.pop(); + toLasts.push( ni ); + if ( pi ) + pi->setOpen( TRUE ); + } else { + if ( i->parent() == fromLast ) { + fromParents.push( fromLast ); + toParents.push( toLasts.top() ); + toLasts.push( 0 ); + QListViewItem *pi = toParents.top(); + QListViewItem *ni = 0; + if ( pi ) + ni = new QListViewItem( pi ); + else + ni = new QListViewItem( to ); + for ( int c = 0; c < cols; ++c ) { + ni->setText( c, i->text( c ) ); + if ( i->pixmap( c ) ) + ni->setPixmap( c, *i->pixmap( c ) ); + } + toLasts.pop(); + toLasts.push( ni ); + if ( pi ) + pi->setOpen( TRUE ); + } else { + while ( fromParents.top() != i->parent() ) { + fromParents.pop(); + toParents.pop(); + toLasts.pop(); + } + + QListViewItem *pi = toParents.top(); + QListViewItem *ni = 0; + if ( pi ) + ni = new QListViewItem( pi, toLasts.top() ); + else + ni = new QListViewItem( to, toLasts.top() ); + for ( int c = 0; c < cols; ++c ) { + ni->setText( c, i->text( c ) ); + if ( i->pixmap( c ) ) + ni->setPixmap( c, *i->pixmap( c ) ); + } + if ( pi ) + pi->setOpen( TRUE ); + toLasts.pop(); + toLasts.push( ni ); + } + } + fromLast = i; + } +} + + + +// ------------------------------------------------------------ + +PopulateMultiLineEditCommand::PopulateMultiLineEditCommand( const QString &n, FormWindow *fw, + QTextEdit *mle, const QString &txt ) + : Command( n, fw ), newText( txt ), mlined( mle ) +{ + oldText = mlined->text(); + wasChanged = MetaDataBase::isPropertyChanged( mlined, "text" ); +} + +void PopulateMultiLineEditCommand::execute() +{ + mlined->setText( newText ); + MetaDataBase::setPropertyChanged( mlined, "text", TRUE ); + formWindow()->emitUpdateProperties( mlined ); +} + +void PopulateMultiLineEditCommand::unexecute() +{ + mlined->setText( oldText ); + MetaDataBase::setPropertyChanged( mlined, "text", wasChanged ); + formWindow()->emitUpdateProperties( mlined ); +} + +// ------------------------------------------------------------ + +PopulateTableCommand::PopulateTableCommand( const QString &n, FormWindow *fw, QTable *t, + const QValueList &rows, + const QValueList &columns ) + : Command( n, fw ), newRows( rows ), newColumns( columns ), table( t ) +{ +#ifndef QT_NO_TABLE + int i = 0; + QMap columnFields = MetaDataBase::columnFields( table ); + for ( i = 0; i < table->horizontalHeader()->count(); ++i ) { + PopulateTableCommand::Column col; + col.text = table->horizontalHeader()->label( i ); + if ( table->horizontalHeader()->iconSet( i ) ) + col.pix = table->horizontalHeader()->iconSet( i )->pixmap(); + col.field = *columnFields.find( col.text ); + oldColumns.append( col ); + } + for ( i = 0; i < table->verticalHeader()->count(); ++i ) { + PopulateTableCommand::Row row; + row.text = table->verticalHeader()->label( i ); + if ( table->verticalHeader()->iconSet( i ) ) + row.pix = table->verticalHeader()->iconSet( i )->pixmap(); + oldRows.append( row ); + } +#endif +} + +void PopulateTableCommand::execute() +{ +#ifndef QT_NO_TABLE + QMap columnFields; + table->setNumCols( (int)newColumns.count() ); + int i = 0; + for ( QValueList::Iterator cit = newColumns.begin(); cit != newColumns.end(); ++cit, ++i ) { + table->horizontalHeader()->setLabel( i, (*cit).pix, (*cit).text ); + if ( !(*cit).field.isEmpty() ) + columnFields.insert( (*cit).text, (*cit).field ); + } + MetaDataBase::setColumnFields( table, columnFields ); + table->setNumRows( (int)newRows.count() ); + i = 0; + for ( QValueList::Iterator rit = newRows.begin(); rit != newRows.end(); ++rit, ++i ) + table->verticalHeader()->setLabel( i, (*rit).pix, (*rit).text ); +#endif +} + +void PopulateTableCommand::unexecute() +{ +#ifndef QT_NO_TABLE + QMap columnFields; + table->setNumCols( (int)oldColumns.count() ); + int i = 0; + for ( QValueList::Iterator cit = oldColumns.begin(); cit != oldColumns.end(); ++cit, ++i ) { + table->horizontalHeader()->setLabel( i, (*cit).pix, (*cit).text ); + if ( !(*cit).field.isEmpty() ) + columnFields.insert( (*cit).text, (*cit).field ); + } + MetaDataBase::setColumnFields( table, columnFields ); + table->setNumRows( (int)oldRows.count() ); + i = 0; + for ( QValueList::Iterator rit = oldRows.begin(); rit != oldRows.end(); ++rit, ++i ) + table->verticalHeader()->setLabel( i, (*rit).pix, (*rit).text ); +#endif +} + +// ------------------------------------------------------------ + +AddActionToToolBarCommand::AddActionToToolBarCommand( const QString &n, FormWindow *fw, + QAction *a, QDesignerToolBar *tb, int idx ) + : Command( n, fw ), action( a ), toolBar( tb ), index( idx ) +{ +} + +void AddActionToToolBarCommand::execute() +{ + action->addTo( toolBar ); + + if ( ::qt_cast(action) ) { + QString s = ( (QDesignerAction*)action )->widget()->name(); + if ( s.startsWith( "qt_dead_widget_" ) ) { + s.remove( 0, QString( "qt_dead_widget_" ).length() ); + ( (QDesignerAction*)action )->widget()->setName( s ); + } + toolBar->insertAction( ( (QDesignerAction*)action )->widget(), action ); + ( (QDesignerAction*)action )->widget()->installEventFilter( toolBar ); + } else if ( ::qt_cast(action) ) { + if ( ( (QDesignerActionGroup*)action )->usesDropDown() ) { + toolBar->insertAction( ( (QDesignerActionGroup*)action )->widget(), action ); + ( (QDesignerActionGroup*)action )->widget()->installEventFilter( toolBar ); + } + } else if ( ::qt_cast(action) ) { + toolBar->insertAction( ( (QSeparatorAction*)action )->widget(), action ); + ( (QSeparatorAction*)action )->widget()->installEventFilter( toolBar ); + } + if ( !::qt_cast(action) || ( (QActionGroup*)action )->usesDropDown()) { + if ( index == -1 ) + toolBar->appendAction( action ); + else + toolBar->insertAction( index, action ); + toolBar->reInsert(); + QObject::connect( action, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + } else { + if ( action->children() ) { + QObjectListIt it( *action->children() ); + int i = 0; + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast(o) ) + continue; + // ### fix it for nested actiongroups + if ( ::qt_cast(o) ) { + QDesignerAction *ac = (QDesignerAction*)o; + toolBar->insertAction( ac->widget(), ac ); + ac->widget()->installEventFilter( toolBar ); + if ( index == -1 ) + toolBar->appendAction( ac ); + else + toolBar->insertAction( index + (i++), ac ); + } + QObject::connect( o, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + } + } + toolBar->reInsert(); + QObject::connect( action, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + } + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddActionToToolBarCommand::unexecute() +{ + if ( ::qt_cast(action) ) { + QString s = ( (QDesignerAction*)action )->widget()->name(); + s.prepend( "qt_dead_widget_" ); + ( (QDesignerAction*)action )->widget()->setName( s ); + } + + toolBar->removeAction( action ); + action->removeFrom( toolBar ); + QObject::disconnect( action, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + if ( !::qt_cast(action) || ( (QActionGroup*)action )->usesDropDown()) { + action->removeEventFilter( toolBar ); + } else { + if ( action->children() ) { + QObjectListIt it( *action->children() ); + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast(o) ) + continue; + if ( ::qt_cast(o) ) { + o->removeEventFilter( toolBar ); + toolBar->removeAction( (QAction*)o ); + } + QObject::disconnect( o, SIGNAL( destroyed() ), toolBar, SLOT( actionRemoved() ) ); + } + } + } + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +AddToolBarCommand::AddToolBarCommand( const QString &n, FormWindow *fw, QMainWindow *mw ) + : Command( n, fw ), toolBar( 0 ), mainWindow( mw ) +{ +} + +void AddToolBarCommand::execute() +{ + if ( !toolBar ) { + toolBar = new QDesignerToolBar( mainWindow ); + QString n = "Toolbar"; + formWindow()->unify( toolBar, n, TRUE ); + toolBar->setName( n ); + mainWindow->addToolBar( toolBar, n ); + } else { + toolBar->show(); + QString s = toolBar->name(); + s.remove( 0, QString( "qt_dead_widget_" ).length() ); + toolBar->setName( s ); + } + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddToolBarCommand::unexecute() +{ + toolBar->hide(); + QString s = toolBar->name(); + s.prepend( "qt_dead_widget_" ); + toolBar->setName( s ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +#ifdef QT_CONTAINER_CUSTOM_WIDGETS +AddContainerPageCommand::AddContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *c, const QString &label ) + : Command( n, fw ), container( c ), index( -1 ), pageLabel( label ), page( 0 ) +{ + WidgetInterface *iface = 0; + widgetManager()->queryInterface( WidgetFactory::classNameOf( container ), &iface ); + if ( !iface ) + return; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&wiface ); + if ( !wiface ) + return; + wClassName = WidgetFactory::classNameOf( container ); +} + +AddContainerPageCommand::~AddContainerPageCommand() +{ + if ( wiface ) + wiface->release(); +} + +void AddContainerPageCommand::execute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + if ( index == -1 ) + index = wiface->count( wClassName, container ); + if ( !page ) + page = wiface->addPage( wClassName, container, pageLabel, index ); + else + wiface->insertPage( wClassName, container, pageLabel, index, page ); + + MetaDataBase::addEntry( page ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +void AddContainerPageCommand::unexecute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + wiface->removePage( wClassName, container, index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +// ------------------------------------------------------------ + +DeleteContainerPageCommand::DeleteContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *c, int idx ) + : Command( n, fw ), container( c ), index( idx ) +{ + WidgetInterface *iface = 0; + widgetManager()->queryInterface( WidgetFactory::classNameOf( container ), &iface ); + if ( !iface ) + return; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&wiface ); + if ( !wiface ) + return; + wClassName = WidgetFactory::classNameOf( container ); + page = wiface->page( wClassName, container, index ); + pageLabel = wiface->pageLabel( wClassName, container, index ); +} + +DeleteContainerPageCommand::~DeleteContainerPageCommand() +{ + if ( wiface ) + wiface->release(); +} + +void DeleteContainerPageCommand::execute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + + wiface->removePage( wClassName, container, index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +void DeleteContainerPageCommand::unexecute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + if ( index == -1 ) + index = wiface->count( wClassName, container ); + + wiface->insertPage( wClassName, container, pageLabel, index, page ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +// ------------------------------------------------------------ + +RenameContainerPageCommand::RenameContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *c, int idx, + const QString &label ) + : Command( n, fw ), container( c ), index( idx ), newLabel( label ) +{ + WidgetInterface *iface = 0; + widgetManager()->queryInterface( WidgetFactory::classNameOf( container ), &iface ); + if ( !iface ) + return; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&wiface ); + if ( !wiface ) + return; + wClassName = WidgetFactory::classNameOf( container ); + oldLabel = wiface->pageLabel( wClassName, container, index ); +} + +RenameContainerPageCommand::~RenameContainerPageCommand() +{ + if ( wiface ) + wiface->release(); +} + +void RenameContainerPageCommand::execute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + wiface->renamePage( wClassName, container, index, newLabel ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} + +void RenameContainerPageCommand::unexecute() +{ + if ( !wiface || !wiface->supportsPages( wClassName ) ) + return; + wiface->renamePage( wClassName, container, index, oldLabel ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + // #### show and update pages in object hierarchy view +} +#endif // QT_CONTAINER_CUSTOM_WIDGETS +// ------------------------------------------------------------ + +AddActionToPopupCommand::AddActionToPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + PopupMenuEditorItem *i, + int idx ) + : Command( n, fw ), menu( m ), item( i ), index( idx ) +{ } + +void AddActionToPopupCommand::execute() +{ + menu->insert( item, index ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddActionToPopupCommand::unexecute() +{ + item->hideMenu(); + int i = menu->find( item->action() ); + menu->remove( i ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +RemoveActionFromPopupCommand::RemoveActionFromPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int idx ) + : AddActionToPopupCommand( n, fw, m, 0, idx ) +{ + item = menu->at( index ); +} + +void RemoveActionFromPopupCommand::execute() +{ + AddActionToPopupCommand::unexecute(); +} + +void RemoveActionFromPopupCommand::unexecute() +{ + AddActionToPopupCommand::execute(); +} + +// ------------------------------------------------------------ + +ExchangeActionInPopupCommand::ExchangeActionInPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int a, + int b ) + : Command( n, fw ), menu( m ), c( a ), d( b ) +{ } + +void ExchangeActionInPopupCommand::execute() +{ + menu->exchange( c, d ); +} + +void ExchangeActionInPopupCommand::unexecute() +{ + execute(); +} + +// ------------------------------------------------------------ + +ActionEditor *ActionCommand::actionEditor() +{ + // FIXME: handle multiple action editors + return (ActionEditor *) formWindow()->mainWindow()->child( 0, "ActionEditor" ); +} + +// ------------------------------------------------------------ + +RenameActionCommand::RenameActionCommand( const QString &n, + FormWindow *fw, + QAction *a, + PopupMenuEditor *m, + QString nm ) + : ActionCommand( n, fw, a ), menu( m ), newName( nm ) +{ + oldName = action->menuText(); +} + +void RenameActionCommand::execute() +{ + QString actionText = newName; + actionText.replace("&&", "&"); + QString menuText = newName; + action->setText( actionText ); + action->setMenuText( menuText ); + + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void RenameActionCommand::unexecute() +{ + action->setMenuText( oldName ); + action->setText( oldName ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +SetActionIconsCommand::SetActionIconsCommand( const QString &n, + FormWindow *fw, + QAction *a, + PopupMenuEditor *m, + QIconSet &icons ) + : ActionCommand( n, fw, a ), menu( m ), newIcons( icons ) +{ + oldIcons = a->iconSet(); +} + +void SetActionIconsCommand::execute() +{ + action->setIconSet( newIcons ); + ActionEditor *ae = actionEditor(); + if ( ae ) + ae->updateActionIcon( action ); + MetaDataBase::setPropertyChanged( action, "iconSet", TRUE ); +} + +void SetActionIconsCommand::unexecute() +{ + action->setIconSet( oldIcons ); + ActionEditor *ae = actionEditor(); + if ( ae ) + ae->updateActionIcon( action ); + MetaDataBase::setPropertyChanged( action, "iconSet", TRUE ); +} + +// ------------------------------------------------------------ + +AddMenuCommand::AddMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + MenuBarEditorItem *i, + int idx ) + : Command( n, fw ), mb( b ), item( i ), name( 0 ), index( idx ) +{ } + +AddMenuCommand::AddMenuCommand( const QString &n, + FormWindow *fw, + QMainWindow *mw, + const QString &nm ) + : Command( n, fw ), mb( 0 ), item( 0 ), name( nm ), index( -1 ) +{ + if ( mw ) + mb = (MenuBarEditor *)mw->child( 0, "MenuBarEditor" ); +} + +void AddMenuCommand::execute() +{ + QString n; + QMainWindow *mw = (QMainWindow*)formWindow()->mainContainer(); + if ( !mb ) { + mb = new MenuBarEditor( formWindow(), mw ); + mb->setName( "MenuBarEditor" ); + formWindow()->insertWidget( mb, TRUE ); + } + if ( !item ) { + PopupMenuEditor *popup = new PopupMenuEditor( formWindow(), mw ); + popup->setName( "PopupMenuEditor" ); + formWindow()->insertWidget( popup, TRUE ); + mb->insertItem( name, popup, index ); + index = mb->findItem( popup ); + item = mb->item( index ); + } else { + PopupMenuEditor *popup = item->menu(); + popup->setName( item->menuText() ); + formWindow()->insertWidget( popup, TRUE ); + mb->insertItem( item, index ); + } + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddMenuCommand::unexecute() +{ + if ( !item ) { + qWarning( "The AddMenuCommand was created without a menu item." ); + return; + } + item->menu()->hide(); + int i = mb->findItem( item ); + formWindow()->removeWidget( item->menu() ); + mb->removeItemAt( i ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +RemoveMenuCommand::RemoveMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int idx ) + : AddMenuCommand( n, fw, b, 0, idx ) +{ + item = mb->item( index ); +} + +void RemoveMenuCommand::execute() +{ + mb->hideItem( index ); + AddMenuCommand::unexecute(); +} + +void RemoveMenuCommand::unexecute() +{ + AddMenuCommand::execute(); +} + +// ------------------------------------------------------------ + +ExchangeMenuCommand::ExchangeMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int i, + int j ) + : Command( n, fw ), bar( b ), k( i ), l( j ) +{ } + +void ExchangeMenuCommand::execute() +{ + bar->exchange( k, l ); +} + +void ExchangeMenuCommand::unexecute() +{ + execute(); +} + +// ------------------------------------------------------------ + +MoveMenuCommand::MoveMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int i, + int j ) + : Command( n, fw ), bar( b ), from( i ), to( j ) +{ } + +void MoveMenuCommand::execute() +{ + bar->hideItem( from ); + MenuBarEditorItem * i = bar->item( from ); + bar->removeItemAt( from ); + int t = ( from > to ? to : to - 1 ); + bar->insertItem( i, t ); +} + +void MoveMenuCommand::unexecute() +{ + bar->hideItem( to ); + int t = ( from > to ? to : to - 1 ); + MenuBarEditorItem * i = bar->item( t ); + bar->removeItemAt( t ); + bar->insertItem( i, from ); +} + +// ------------------------------------------------------------ + +RenameMenuCommand::RenameMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + QString nm, + MenuBarEditorItem *i ) + : Command( n, fw ), bar( b ), item( i ), newName( nm ) +{ + oldName = item->menu()->name(); +} + +QString RenameMenuCommand::makeLegal( const QString &str ) +{ + // remove illegal characters + QString d; + char c = 0, i = 0; + while ( !str.at(i).isNull() ) { + c = str.at(i).latin1(); + if ( c == '-' || c == ' ' ) + d += '_'; + else if ( ( c >= '0' && c <= '9') || ( c >= 'A' && c <= 'Z' ) + || c == '_' || ( c >= 'a' && c <= 'z' ) ) + d += c; + ++i; + } + return d; +} + +void RenameMenuCommand::execute() +{ + PopupMenuEditor *popup = item->menu(); + item->setMenuText( newName ); + QString legal = makeLegal( newName ); + formWindow()->unify( popup, legal, TRUE ); + popup->setName( legal ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void RenameMenuCommand::unexecute() +{ + PopupMenuEditor *popup = item->menu(); + item->setMenuText( oldName ); + popup->setName( oldName ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +AddToolBoxPageCommand::AddToolBoxPageCommand( const QString &n, FormWindow *fw, + QToolBox *tw, const QString &label ) + : Command( n, fw ), toolBox( tw ), toolBoxLabel( label ) +{ + toolBoxPage = new QDesignerWidget( formWindow(), toolBox, "page" ); + toolBoxPage->hide(); + index = -1; + MetaDataBase::addEntry( toolBoxPage ); +} + +void AddToolBoxPageCommand::execute() +{ + index = toolBox->insertItem( index, toolBoxPage, toolBoxLabel); + toolBox->setCurrentIndex( index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void AddToolBoxPageCommand::unexecute() +{ + toolBox->removeItem( toolBoxPage ); + toolBoxPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +// ------------------------------------------------------------ + +DeleteToolBoxPageCommand::DeleteToolBoxPageCommand( const QString &n, FormWindow *fw, + QToolBox *tw, QWidget *page ) + : Command( n, fw ), toolBox( tw ), toolBoxPage( page ) +{ + toolBoxLabel = toolBox->itemLabel( toolBox->currentIndex() ); + index = toolBox->currentIndex(); +} + +void DeleteToolBoxPageCommand::execute() +{ + toolBox->removeItem( toolBoxPage ); + toolBoxPage->hide(); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} + +void DeleteToolBoxPageCommand::unexecute() +{ + index = toolBox->insertItem( index, toolBoxPage, toolBoxLabel ); + toolBox->setCurrentIndex( index ); + formWindow()->emitUpdateProperties( formWindow()->currentWidget() ); + formWindow()->mainWindow()->objectHierarchy()->rebuild(); +} diff --git a/tools/designer/designer/command.h b/tools/designer/designer/command.h new file mode 100644 index 0000000..a1f5620 --- /dev/null +++ b/tools/designer/designer/command.h @@ -0,0 +1,1266 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef COMMAND_H +#define COMMAND_H + +#include "metadatabase.h" +#include "layout.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QWizard; +class QTabWidget; +class Command; +class QWidget; +class FormWindow; +class PropertyEditor; +class QListBox; +class QIconView; +class QTable; +class QAction; +class QDesignerToolBar; +class QMainWindow; +class QTextEdit; +struct LanguageInterface; +class QToolBox; + +class MenuBarEditor; +class MenuBarEditorItem; +class PopupMenuEditor; +class PopupMenuEditorItem; +class ActionEditor; + +class Command : public Qt +{ +public: + Command( const QString &n, FormWindow *fw ); + virtual ~Command(); + + enum Type { + Resize, + Insert, + Move, + Delete, + SetProperty, + LayoutHorizontal, + LayoutVertical, + LayoutHorizontalSplitter, + LayoutVerticalSplitter, + LayoutGrid, + BreakLayout, + Macro, + AddTabPage, + DeleteTabPage, + MoveTabPage, + AddWidgetStackPage, + DeleteWidgetStackPage, + AddWizardPage, + DeleteWizardPage, + SwapWizardPages, + MoveWizardPage, + RenameWizardPage, + AddConnection, + RemoveConnection, + Lower, + Raise, + Paste, + TabOrder, + PopulateListBox, + PopulateIconView, + PopulateListView, + PopulateMultiLineEdit, + PopulateTable, + AddActionToToolBar, + RemoveActionFromToolBar, + AddToolBar, + RemoveToolBar, + AddFunction, + ChangeFunctionAttrib, + RemoveFunction, + AddVariable, + SetVariables, + RemoveVariable, + EditDefinitions, + AddContainerPage, + DeleteContainerPage, + RenameContainerPage, + AddActionToPopup, + RemoveActionFromPopup, + ExchangeActionInPopup, + //MoveActionInPopup, + RenameAction, + SetActionIcons, + AddMenu, + RemoveMenu, + ExchangeMenu, + MoveMenu, + RenameMenu, + AddToolBoxPage, + DeleteToolBoxPage + }; + + QString name() const; + + virtual void execute() = 0; + virtual void unexecute() = 0; + virtual Type type() const = 0; + virtual void merge( Command *c ); + virtual bool canMerge( Command *c ); + + FormWindow *formWindow() const; + +private: + QString cmdName; + FormWindow *formWin; + +}; + +class CommandHistory : public QObject +{ + Q_OBJECT + +public: + CommandHistory( int s ); + + void addCommand( Command *cmd, bool tryCompress = FALSE ); + void undo(); + void redo(); + + void emitUndoRedo(); + + void setModified( bool m ); + bool isModified() const; + +public slots: + void checkCompressedCommand(); + +signals: + void undoRedoChanged( bool undoAvailable, bool redoAvailable, + const QString &undoCmd, const QString &redoCmd ); + void modificationChanged( bool m ); + +private: + QPtrList history; + int current, steps; + bool modified; + int savedAt; + Command *compressedCommand; + +}; + +class ResizeCommand : public Command +{ +public: + ResizeCommand( const QString &n, FormWindow *fw, + QWidget *w, const QRect &oldr, const QRect &nr ); + + void execute(); + void unexecute(); + Type type() const { return Resize; } + +private: + QWidget *widget; + QRect oldRect, newRect; + +}; + +class InsertCommand : public Command +{ +public: + InsertCommand( const QString &n, FormWindow *fw, QWidget *w, const QRect &g ); + + void execute(); + void unexecute(); + Type type() const { return Insert; } + +private: + QWidget *widget; + QRect geometry; + +}; + +class MoveCommand : public Command +{ +public: + MoveCommand( const QString &n, FormWindow *fw, + const QWidgetList &w, + const QValueList op, + const QValueList np, + QWidget *opr, QWidget *npr ); + void execute(); + void unexecute(); + Type type() const { return Move; } + void merge( Command *c ); + bool canMerge( Command *c ); + +private: + QWidgetList widgets; + QValueList oldPos, newPos; + QWidget *oldParent, *newParent; + +}; + +class DeleteCommand : public Command +{ +public: + DeleteCommand( const QString &n, FormWindow *fw, + const QWidgetList &w ); + void execute(); + void unexecute(); + Type type() const { return Delete; } + +private: + QWidgetList widgets; + QMap< QWidget*, QValueList > connections; + +}; + +class SetPropertyCommand : public Command +{ +public: + SetPropertyCommand( const QString &n, FormWindow *fw, + QObject *w, PropertyEditor *e, + const QString &pn, const QVariant &ov, + const QVariant &nv, const QString &ncut, + const QString &ocut, + bool reset = FALSE ); + + void execute(); + void unexecute(); + Type type() const { return SetProperty; } + void merge( Command *c ); + bool canMerge( Command *c ); + bool checkProperty(); + +private: + void setProperty( const QVariant &v, const QString ¤tItemText, bool select = TRUE ); + + QGuardedPtr widget; + PropertyEditor *editor; + QString propName; + QVariant oldValue, newValue; + QString oldCurrentItemText, newCurrentItemText; + bool wasChanged; + bool isResetCommand; + +}; + +class LayoutHorizontalCommand : public Command +{ +public: + LayoutHorizontalCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return LayoutHorizontal; } + +private: + HorizontalLayout layout; + +}; + +class LayoutHorizontalSplitCommand : public Command +{ +public: + LayoutHorizontalSplitCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return LayoutHorizontalSplitter; } + +private: + HorizontalLayout layout; + +}; + +class LayoutVerticalCommand : public Command +{ +public: + LayoutVerticalCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return LayoutVertical; } + +private: + VerticalLayout layout; + +}; + +class LayoutVerticalSplitCommand : public Command +{ +public: + LayoutVerticalSplitCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return LayoutVerticalSplitter; } + +private: + VerticalLayout layout; + +}; + +class LayoutGridCommand : public Command +{ +public: + LayoutGridCommand( const QString &n, FormWindow *fw, + QWidget *parent, QWidget *layoutBase, + const QWidgetList &wl, int xres, int yres ); + + void execute(); + void unexecute(); + Type type() const { return LayoutGrid; } + +private: + GridLayout layout; + +}; + +class BreakLayoutCommand : public Command +{ +public: + BreakLayoutCommand( const QString &n, FormWindow *fw, + QWidget *layoutBase, const QWidgetList &wl ); + + void execute(); + void unexecute(); + Type type() const { return BreakLayout; } + +private: + Layout *layout; + int spacing; + int margin; + QWidget *lb; + QWidgetList widgets; + +}; + +class MacroCommand : public Command +{ +public: + MacroCommand( const QString &n, FormWindow *fw, + const QPtrList &cmds ); + + void execute(); + void unexecute(); + Type type() const { return Macro; } + +private: + QPtrList commands; + +}; + +class AddTabPageCommand : public Command +{ +public: + AddTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, const QString &label ); + + void execute(); + void unexecute(); + Type type() const { return AddTabPage; } + +private: + QTabWidget *tabWidget; + int index; + QWidget *tabPage; + QString tabLabel; + +}; + +class DeleteTabPageCommand : public Command +{ +public: + DeleteTabPageCommand( const QString &n, FormWindow *fw, + QTabWidget *tw, QWidget *page ); + + void execute(); + void unexecute(); + Type type() const { return DeleteTabPage; } + +private: + QTabWidget *tabWidget; + int index; + QWidget *tabPage; + QString tabLabel; + +}; + +class MoveTabPageCommand : public Command +{ +public: + MoveTabPageCommand(const QString &n, FormWindow *fw, + QTabWidget *tw, QWidget *page, const QString& label, int nIndex, int oIndex ); + + void execute(); + void unexecute(); + Type type() const { return MoveTabPage; } + +private: + QTabWidget *tabWidget; + int newIndex, oldIndex; + QWidget *tabPage; + QString tabLabel; + +}; +class QDesignerWidgetStack; +class AddWidgetStackPageCommand : public Command +{ +public: + AddWidgetStackPageCommand( const QString &n, FormWindow *fw, + QDesignerWidgetStack *ws ); + + void execute(); + void unexecute(); + Type type() const { return AddWidgetStackPage; } + +private: + QDesignerWidgetStack *widgetStack; + int index; + QWidget *stackPage; +}; + +class DeleteWidgetStackPageCommand : public Command +{ +public: + DeleteWidgetStackPageCommand( const QString &n, FormWindow *fw, + QDesignerWidgetStack *ws, QWidget *page ); + + void execute(); + void unexecute(); + Type type() const { return DeleteWidgetStackPage; } + +private: + QDesignerWidgetStack *widgetStack; + int index; + QWidget *stackPage; +}; + + + +class AddWizardPageCommand : public Command +{ +public: + AddWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, const QString &label, int index = -1, bool show = TRUE ); + + void execute(); + void unexecute(); + Type type() const { return AddWizardPage; } + +private: + QWizard *wizard; + int index; + bool show; + QWidget *page; + QString pageLabel; + +}; + +class DeleteWizardPageCommand : public Command +{ +public: + DeleteWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int index, bool show = TRUE ); + + void execute(); + void unexecute(); + Type type() const { return DeleteWizardPage; } + +private: + QWizard *wizard; + int index; + bool show; + QWidget *page; + QString pageLabel; + +}; + +class RenameWizardPageCommand : public Command +{ +public: + RenameWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int index, const QString& name ); + + void execute(); + void unexecute(); + Type type() const { return RenameWizardPage; } + +private: + QWizard *wizard; + int index; + QWidget *page; + QString label; + +}; + +class SwapWizardPagesCommand : public Command +{ +public: + SwapWizardPagesCommand( const QString &n, FormWindow *fw, + QWizard *w, int index1, int index2 ); + + void execute(); + void unexecute(); + Type type() const { return SwapWizardPages; } + +private: + QWizard *wizard; + int index1, index2; + +}; + +class MoveWizardPageCommand : public Command +{ +public: + MoveWizardPageCommand( const QString &n, FormWindow *fw, + QWizard *w, int index1, int index2 ); + + void execute(); + void unexecute(); + Type type() const { return MoveWizardPage; } + +private: + QWizard *wizard; + int index1, index2; + +}; + +class AddConnectionCommand : public Command +{ +public: + AddConnectionCommand( const QString &name, FormWindow *fw, + MetaDataBase::Connection c ); + + void execute(); + void unexecute(); + Type type() const { return AddConnection; } + +private: + MetaDataBase::Connection connection; + +}; + +class RemoveConnectionCommand : public Command +{ +public: + RemoveConnectionCommand( const QString &name, FormWindow *fw, + MetaDataBase::Connection c ); + + void execute(); + void unexecute(); + Type type() const { return RemoveConnection; } + +private: + MetaDataBase::Connection connection; + +}; + + +class AddFunctionCommand : public Command +{ +public: + AddFunctionCommand( const QString &name, FormWindow *fw, const QCString &f, const QString& spec, + const QString &a, const QString &t, const QString &l, const QString &rt ); + + void execute(); + void unexecute(); + Type type() const { return AddFunction; } + +private: + QCString function; + QString specifier; + QString access; + QString functionType; + QString language; + QString returnType; +}; + +class ChangeFunctionAttribCommand : public Command +{ +public: + ChangeFunctionAttribCommand( const QString &name, FormWindow *fw, MetaDataBase::Function f, + const QString &on, const QString &os, const QString &oa, + const QString &ot, const QString &ol, const QString &ort ); + + void execute(); + void unexecute(); + Type type() const { return ChangeFunctionAttrib; } + +private: + QString oldName, newName; + QString oldSpec, newSpec; + QString oldAccess, newAccess; + QString oldType, newType; + QString oldLang, newLang; + QString oldReturnType, newReturnType; +}; + +class RemoveFunctionCommand : public Command +{ +public: + RemoveFunctionCommand( const QString &name, FormWindow *fw, const QCString &f, const QString& spec, + const QString &a, const QString &t, const QString &l, const QString &rt ); + + void execute(); + void unexecute(); + Type type() const { return RemoveFunction; } + +private: + QCString function; + QString specifier; + QString access; + QString functionType; + QString language; + QString returnType; +}; + +class AddVariableCommand : public Command +{ +public: + AddVariableCommand( const QString &name, FormWindow *fw, const QString &vn, const QString &a ); + void execute(); + void unexecute(); + Type type() const { return AddVariable; } + +private: + QString varName; + QString access; +}; + +class SetVariablesCommand : public Command +{ +public: + SetVariablesCommand( const QString &name, FormWindow *fw, QValueList lst ); + void execute(); + void unexecute(); + Type type() const { return SetVariables; } + +private: + QValueList oldList, newList; +}; + +class RemoveVariableCommand : public Command +{ +public: + RemoveVariableCommand( const QString &name, FormWindow *fw, const QString &vn ); + void execute(); + void unexecute(); + Type type() const { return RemoveVariable; } + +private: + QString varName; + QString access; +}; + +class EditDefinitionsCommand : public Command +{ +public: + EditDefinitionsCommand( const QString &name, FormWindow *fw, LanguageInterface *lf, + const QString &n, const QStringList &l ); + void execute(); + void unexecute(); + Type type() const { return EditDefinitions; } + +private: + LanguageInterface *lIface; + QString defName; + QStringList newList, oldList; +}; + +class LowerCommand : public Command +{ +public: + LowerCommand( const QString &name, FormWindow *fw, const QWidgetList &w ); + + void execute(); + void unexecute(); + Type type() const { return Lower; } + +private: + QWidgetList widgets; + +}; + +class RaiseCommand : public Command +{ +public: + RaiseCommand( const QString &name, FormWindow *fw, const QWidgetList &w ); + + void execute(); + void unexecute(); + Type type() const { return Raise; } + +private: + QWidgetList widgets; + +}; + +class PasteCommand : public Command +{ +public: + PasteCommand( const QString &n, FormWindow *fw, const QWidgetList &w ); + + void execute(); + void unexecute(); + Type type() const { return Paste; } + +private: + QWidgetList widgets; + +}; + +class TabOrderCommand : public Command +{ +public: + TabOrderCommand( const QString &n, FormWindow *fw, const QWidgetList &ol, const QWidgetList &nl ); + + void execute(); + void unexecute(); + Type type() const { return TabOrder; } + void merge( Command *c ); + bool canMerge( Command *c ); + +private: + QWidgetList oldOrder, newOrder; + +}; + +class PopulateListBoxCommand : public Command +{ +public: + struct Item + { + QString text; + QPixmap pix; + Q_DUMMY_COMPARISON_OPERATOR( Item ) + }; + + PopulateListBoxCommand( const QString &n, FormWindow *fw, + QListBox *lb, const QValueList &items ); + void execute(); + void unexecute(); + Type type() const { return PopulateListBox; } + + bool operator==( const PopulateListBoxCommand & ) const; + +private: + QValueList oldItems, newItems; + QListBox *listbox; + +}; + +class PopulateIconViewCommand : public Command +{ +public: + struct Item + { + QString text; + QPixmap pix; + Q_DUMMY_COMPARISON_OPERATOR( Item ) + }; + + PopulateIconViewCommand( const QString &n, FormWindow *fw, + QIconView *iv, const QValueList &items ); + void execute(); + void unexecute(); + Type type() const { return PopulateIconView; } + + bool operator==( const PopulateIconViewCommand & ) const; + +private: + QValueList oldItems, newItems; + QIconView *iconview; + +}; + +class PopulateListViewCommand : public Command +{ +public: + PopulateListViewCommand( const QString &n, FormWindow *fw, + QListView *lv, QListView *from ); + void execute(); + void unexecute(); + Type type() const { return PopulateListView; } + static void transferItems( QListView *from, QListView *to ); + + bool operator==( const PopulateListViewCommand & ) const; + +private: + QListView *oldItems, *newItems; + QListView *listview; + +}; + +class PopulateMultiLineEditCommand : public Command +{ +public: + PopulateMultiLineEditCommand( const QString &n, FormWindow *fw, + QTextEdit *mle, const QString &txt ); + void execute(); + void unexecute(); + Type type() const { return PopulateMultiLineEdit; } + +private: + QString newText, oldText; + QTextEdit *mlined; + bool wasChanged; + +}; + +class PopulateTableCommand : public Command +{ +public: + struct Row + { + QString text; + QPixmap pix; + Q_DUMMY_COMPARISON_OPERATOR( Row ) + }; + + struct Column + { + QString text; + QPixmap pix; + QString field; + Q_DUMMY_COMPARISON_OPERATOR( Column ) + }; + + PopulateTableCommand( const QString &n, FormWindow *fw, QTable *t, + const QValueList &rows, + const QValueList &columns ); + + void execute(); + void unexecute(); + Type type() const { return PopulateTable; } + +private: + QValueList oldRows, newRows; + QValueList oldColumns, newColumns; + QTable *table; + +}; + +class AddActionToToolBarCommand : public Command +{ +public: + AddActionToToolBarCommand( const QString &n, FormWindow *fw, + QAction *a, QDesignerToolBar *tb, int idx ); + + void execute(); + void unexecute(); + Type type() const { return AddActionToToolBar; } + +private: + QAction *action; + QDesignerToolBar *toolBar; + int index; + +}; + +class RemoveActionFromToolBarCommand : public AddActionToToolBarCommand +{ +public: + RemoveActionFromToolBarCommand( const QString &n, FormWindow *fw, + QAction *a, QDesignerToolBar *tb, int idx ) + : AddActionToToolBarCommand( n, fw, a, tb, idx ) {} + + void execute() { AddActionToToolBarCommand::unexecute(); } + void unexecute() { AddActionToToolBarCommand::execute(); } + Type type() const { return RemoveActionFromToolBar; } + +}; + +// MenuCommands + +class AddToolBarCommand : public Command +{ +public: + AddToolBarCommand( const QString &n, FormWindow *fw, QMainWindow *mw ); + + void execute(); + void unexecute(); + Type type() const { return AddToolBar; } + +protected: + QDesignerToolBar *toolBar; + QMainWindow *mainWindow; + +}; + +class RemoveToolBarCommand : public AddToolBarCommand +{ +public: + RemoveToolBarCommand( const QString &n, FormWindow *fw, QMainWindow *mw, QDesignerToolBar *tb ) + : AddToolBarCommand( n, fw, mw ) { toolBar = tb; } + + void execute() { AddToolBarCommand::unexecute(); } + void unexecute() { AddToolBarCommand::execute(); } + Type type() const { return RemoveToolBar; } + +}; + +struct QWidgetContainerInterfacePrivate; + +class AddContainerPageCommand : public Command +{ +public: + AddContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *c, const QString &label ); + + ~AddContainerPageCommand(); + + void execute(); + void unexecute(); + Type type() const { return AddContainerPage; } + +private: + QString wClassName; + QWidget *container; + int index; + QString pageLabel; + QWidget *page; + QWidgetContainerInterfacePrivate *wiface; + +}; + +class DeleteContainerPageCommand : public Command +{ +public: + DeleteContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *container, int index ); + ~DeleteContainerPageCommand(); + + void execute(); + void unexecute(); + Type type() const { return DeleteContainerPage; } + +private: + QString wClassName; + QWidget *container; + int index; + QString pageLabel; + QWidget *page; + QWidgetContainerInterfacePrivate *wiface; + +}; + +class RenameContainerPageCommand : public Command +{ +public: + RenameContainerPageCommand( const QString &n, FormWindow *fw, + QWidget *container, int index, + const QString &label ); + ~RenameContainerPageCommand(); + + void execute(); + void unexecute(); + Type type() const { return RenameContainerPage; } + +private: + QString wClassName; + QWidget *container; + int index; + QString oldLabel, newLabel; + QWidgetContainerInterfacePrivate *wiface; + +}; + +class AddActionToPopupCommand : public Command +{ +public: + AddActionToPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + PopupMenuEditorItem *i, + int idx = -1 ); + void execute(); + void unexecute(); + Type type() const { return AddActionToPopup; } +protected: + QString constructName() const; + PopupMenuEditor *menu; + PopupMenuEditorItem *item; + int index; +private: +}; + +class RemoveActionFromPopupCommand : public AddActionToPopupCommand +{ +public: + RemoveActionFromPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int idx ); + void execute(); + void unexecute(); + Type type() const { return RemoveActionFromPopup; } +protected: +private: +}; + +class ExchangeActionInPopupCommand : public Command +{ +public: + ExchangeActionInPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int a, + int b ); + void execute(); + void unexecute(); + Type type() const { return ExchangeActionInPopup; } +protected: +private: + PopupMenuEditor *menu; + int c; + int d; +}; +/* +class MoveActionInPopupCommand : public Command +{ +public: + MoveActionInPopupCommand( const QString &n, + FormWindow *fw, + PopupMenuEditor *m, + int a, + int b ); + void execute(); + void unexecute(); + Type type() const { return MoveActionInPopup; } +protected: +private: + PopupMenuEditor *menu; + int from; + int to; +}; +*/ +class ActionCommand : public Command +{ +public: + ActionCommand( const QString &n, + FormWindow *fw, + QAction *a ) + : Command( n, fw ), action( a ) { } + virtual Type type() const = 0; +protected: + ActionEditor *actionEditor(); + QAction *action; +}; + +class RenameActionCommand : public ActionCommand +{ +public: + RenameActionCommand( const QString &n, + FormWindow *fw, + QAction *a, + PopupMenuEditor *m, + QString nm ); + void execute(); + void unexecute(); + Type type() const { return RenameAction; } +private: + PopupMenuEditor *menu; + QString newName; + QString oldName; +}; + +class SetActionIconsCommand : public ActionCommand +{ +public: + SetActionIconsCommand( const QString &n, + FormWindow *fw, + QAction *a, + PopupMenuEditor *m, + QIconSet &icons ); + void execute(); + void unexecute(); + Type type() const { return SetActionIcons; } +protected: + void updateActionEditorItem(); +private: + PopupMenuEditor *menu; + QIconSet newIcons; + QIconSet oldIcons; +}; + +class AddMenuCommand : public Command +{ +public: + AddMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + MenuBarEditorItem *i, + int idx = -1 ); + + AddMenuCommand( const QString &n, + FormWindow *fw, + QMainWindow *mw, + const QString &nm = "Menu" ); + + void execute(); + void unexecute(); + Type type() const { return AddMenu; } +protected: + MenuBarEditor *mb; + MenuBarEditorItem *item; + QString name; + int index; +private: +}; + +class RemoveMenuCommand : public AddMenuCommand +{ +public: + RemoveMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int idx ); + void execute(); + void unexecute(); + Type type() const { return RemoveMenu; } +protected: +private: +}; + +class ExchangeMenuCommand : public Command +{ +public: + ExchangeMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int i, + int j ); + void execute(); + void unexecute(); + Type type() const { return ExchangeMenu; } +protected: +private: + MenuBarEditor *bar; + int k; + int l; +}; + + +class MoveMenuCommand : public Command +{ +public: + MoveMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *b, + int i, + int j ); + void execute(); + void unexecute(); + Type type() const { return MoveMenu; } +protected: +private: + MenuBarEditor *bar; + int from; + int to; +}; + +class RenameMenuCommand : public Command +{ +public: + RenameMenuCommand( const QString &n, + FormWindow *fw, + MenuBarEditor *m, + QString nm, + MenuBarEditorItem *i ); + void execute(); + void unexecute(); + Type type() const { return RenameMenu; } + static QString makeLegal( const QString &str ); +private: + MenuBarEditor *bar; + MenuBarEditorItem *item; + QString newName; + QString oldName; +}; + +class AddToolBoxPageCommand : public Command +{ +public: + AddToolBoxPageCommand( const QString &n, FormWindow *fw, + QToolBox *tw, const QString &label ); + + void execute(); + void unexecute(); + Type type() const { return AddToolBoxPage; } + +private: + QToolBox *toolBox; + int index; + QWidget *toolBoxPage; + QString toolBoxLabel; + +}; + +class DeleteToolBoxPageCommand : public Command +{ +public: + DeleteToolBoxPageCommand( const QString &n, FormWindow *fw, + QToolBox *tw, QWidget *page ); + + void execute(); + void unexecute(); + Type type() const { return DeleteToolBoxPage; } + +private: + QToolBox *toolBox; + int index; + QWidget *toolBoxPage; + QString toolBoxLabel; + +}; + +#endif diff --git a/tools/designer/designer/configtoolboxdialog.ui b/tools/designer/designer/configtoolboxdialog.ui new file mode 100644 index 0000000..98a5893 --- /dev/null +++ b/tools/designer/designer/configtoolboxdialog.ui @@ -0,0 +1,329 @@ + +ConfigToolboxDialog +********************************************************************* +** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + ConfigToolboxDialog + + + + 0 + 0 + 403 + 467 + + + + Configure Toolbox + + + + unnamed + + + + Layout2 + + + + unnamed + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 342 + 0 + + + + + + PushButton3 + + + OK + + + true + + + + + PushButton4 + + + Cancel + + + + + + + Layout4 + + + + unnamed + + + + buttonAdd + + + false + + + &Add + + + + + Spacer3 + + + Horizontal + + + Expanding + + + + 111 + 0 + + + + + + + Available Tools + + + true + + + true + + + + listViewTools + + + Extended + + + LastColumn + + + + + + + Layout5 + + + + unnamed + + + + buttonRemove + + + false + + + &Remove + + + + + + Common Widgets Page + + + true + + + true + + + + listViewCommon + + + Extended + + + LastColumn + + + + + buttonDown + + + false + + + + + + designer_s_down.png + + + + + Spacer4 + + + Horizontal + + + Expanding + + + + 41 + 0 + + + + + + buttonUp + + + false + + + + + + designer_s_up.png + + + + + + + + + buttonAdd + clicked() + ConfigToolboxDialog + addTool() + + + buttonRemove + clicked() + ConfigToolboxDialog + removeTool() + + + buttonUp + clicked() + ConfigToolboxDialog + moveToolUp() + + + buttonDown + clicked() + ConfigToolboxDialog + moveToolDown() + + + listViewTools + clicked(QListViewItem*) + ConfigToolboxDialog + currentToolChanged(QListViewItem*) + + + listViewCommon + clicked(QListViewItem*) + ConfigToolboxDialog + currentCommonToolChanged(QListViewItem*) + + + PushButton3 + clicked() + ConfigToolboxDialog + accept() + + + PushButton4 + clicked() + ConfigToolboxDialog + reject() + + + PushButton3 + clicked() + ConfigToolboxDialog + ok() + + + listViewTools + doubleClicked(QListViewItem*) + ConfigToolboxDialog + addTool() + + + + configtoolboxdialog.ui.h + + + addTool() + removeTool() + moveToolUp() + moveToolDown() + currentToolChanged( QListViewItem * i ) + currentCommonToolChanged( QListViewItem * i ) + ok() + + + init() + + + + diff --git a/tools/designer/designer/configtoolboxdialog.ui.h b/tools/designer/designer/configtoolboxdialog.ui.h new file mode 100644 index 0000000..a98f0ee --- /dev/null +++ b/tools/designer/designer/configtoolboxdialog.ui.h @@ -0,0 +1,222 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "mainwindow.h" +#include "widgetaction.h" +#include "listviewdnd.h" +#include + +void ConfigToolboxDialog::init() +{ + listViewTools->setSorting( -1 ); + listViewCommon->setSorting( -1 ); + + ListViewDnd *toolsDnd = new ListViewDnd( listViewTools ); + toolsDnd->setDragMode( ListViewDnd::External | ListViewDnd::NullDrop | ListViewDnd::Flat ); + + ListViewDnd *commonDnd = new ListViewDnd( listViewCommon ); + commonDnd->setDragMode( ListViewDnd::Both | ListViewDnd::Move | ListViewDnd::Flat ); + + QObject::connect( toolsDnd, SIGNAL( dropped( QListViewItem * ) ), + commonDnd, SLOT( confirmDrop( QListViewItem * ) ) ); + QObject::connect( commonDnd, SIGNAL( dropped( QListViewItem * ) ), + commonDnd, SLOT( confirmDrop( QListViewItem * ) ) ); + + QDict groups; + QAction *a; + for ( a = MainWindow::self->toolActions.last(); + a; + a = MainWindow::self->toolActions.prev() ) { + QString grp = ( (WidgetAction*)a )->group(); + QListViewItem *parent = groups.find( grp ); + if ( !parent ) { + parent = new QListViewItem( listViewTools ); + parent->setText( 0, grp ); + parent->setOpen( TRUE ); + groups.insert( grp, parent ); + } + QListViewItem *i = new QListViewItem( parent ); + i->setText( 0, a->text() ); + i->setPixmap( 0, a->iconSet().pixmap() ); + } + for ( a = MainWindow::self->commonWidgetsPage.last(); a; + a = MainWindow::self->commonWidgetsPage.prev() ) { + QListViewItem *i = new QListViewItem( listViewCommon ); + i->setText( 0, a->text() ); + i->setPixmap( 0, a->iconSet().pixmap() ); + } + +} + + +void ConfigToolboxDialog::addTool() +{ + QListView *src = listViewTools; + + bool addKids = FALSE; + QListViewItem *nextSibling = 0; + QListViewItem *nextParent = 0; + QListViewItemIterator it = src->firstChild(); + for ( ; *it; it++ ) { + // Hit the nextSibling, turn of child processing + if ( (*it) == nextSibling ) + addKids = FALSE; + + if ( (*it)->isSelected() ) { + if ( (*it)->childCount() == 0 ) { + // Selected, no children + QListViewItem *i = new QListViewItem( listViewCommon, listViewCommon->lastItem() ); + i->setText( 0, (*it)->text(0) ); + i->setPixmap( 0, *((*it)->pixmap(0)) ); + listViewCommon->setCurrentItem( i ); + listViewCommon->ensureItemVisible( i ); + } else if ( !addKids ) { + // Children processing not set, so set it + // Also find the item were we shall quit + // processing children...if any such item + addKids = TRUE; + nextSibling = (*it)->nextSibling(); + nextParent = (*it)->parent(); + while ( nextParent && !nextSibling ) { + nextSibling = nextParent->nextSibling(); + nextParent = nextParent->parent(); + } + } + } else if ( ((*it)->childCount() == 0) && addKids ) { + // Leaf node, and we _do_ process children + QListViewItem *i = new QListViewItem( listViewCommon, listViewCommon->lastItem() ); + i->setText( 0, (*it)->text(0) ); + i->setPixmap( 0, *((*it)->pixmap(0)) ); + listViewCommon->setCurrentItem( i ); + listViewCommon->ensureItemVisible( i ); + } + } +} + + +void ConfigToolboxDialog::removeTool() +{ + QListViewItemIterator it = listViewCommon->firstChild(); + while ( *it ) { + if ( (*it)->isSelected() ) + delete (*it); + else + it++; + } +} + + +void ConfigToolboxDialog::moveToolUp() +{ + QListViewItem *next = 0; + QListViewItem *item = listViewCommon->firstChild(); + for ( int i = 0; i < listViewCommon->childCount(); ++i ) { + next = item->itemBelow(); + if ( item->isSelected() && (i > 0) && !item->itemAbove()->isSelected() ) + item->itemAbove()->moveItem( item ); + item = next; + } +} + + +void ConfigToolboxDialog::moveToolDown() +{ + int count = listViewCommon->childCount(); + QListViewItem *next = 0; + QListViewItem *item = listViewCommon->lastItem(); + for ( int i = 0; i < count; ++i ) { + next = item->itemAbove(); + if ( item->isSelected() && (i > 0) && !item->itemBelow()->isSelected() ) + item->moveItem( item->itemBelow() ); + item = next; + } + + // QListViewItem *item = listViewCommon->firstChild(); + // for ( int i = 0; i < listViewCommon->childCount(); ++i ) { + //if ( item == listViewCommon->currentItem() ) { + // item->moveItem( item->itemBelow() ); + // currentCommonToolChanged( item ); + // break; + //} + //item = item->itemBelow(); + // } +} + + +void ConfigToolboxDialog::currentToolChanged( QListViewItem *i ) +{ + bool canAdd = FALSE; + QListViewItemIterator it = listViewTools->firstChild(); + for ( ; *it; it++ ) { + if ( (*it)->isSelected() ) { + canAdd = TRUE; + break; + } + } + buttonAdd->setEnabled( canAdd || ( i && i->isSelected() ) ); +} + + +void ConfigToolboxDialog::currentCommonToolChanged( QListViewItem *i ) +{ + buttonUp->setEnabled( (bool) (i && i->itemAbove()) ); + buttonDown->setEnabled( (bool) (i && i->itemBelow()) ); + + bool canRemove = FALSE; + QListViewItemIterator it = listViewCommon->firstChild(); + for ( ; *it; it++ ) { + if ( (*it)->isSelected() ) { + canRemove = TRUE; + break; + } + } + buttonRemove->setEnabled( canRemove || ( i && i->isSelected() ) ); +} + + +void ConfigToolboxDialog::ok() +{ + MainWindow::self->commonWidgetsPage.clear(); + QListViewItem *item = listViewCommon->firstChild(); + for ( int j = 0; j < listViewCommon->childCount(); item = item->itemBelow(), ++j ) { + QAction *a = 0; + for ( a = MainWindow::self->toolActions.last(); + a; + a = MainWindow::self->toolActions.prev() ) { + if ( a->text() == item->text( 0 ) ) + break; + } + if ( a ) + MainWindow::self->commonWidgetsPage.insert( j, a ); + } +} diff --git a/tools/designer/designer/connectiondialog.ui b/tools/designer/designer/connectiondialog.ui new file mode 100644 index 0000000..be1bba4 --- /dev/null +++ b/tools/designer/designer/connectiondialog.ui @@ -0,0 +1,226 @@ + +ConnectionDialog +********************************************************************* +** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + ConnectionDialog + + + + 0 + 0 + 600 + 365 + + + + View and Edit Connections + + + + unnamed + + + 11 + + + 6 + + + + PushButton1 + + + &New + + + + + TextLabel1 + + + + 5 + 4 + 0 + 0 + + + + &Connections: + + + connectionsTable + + + + + PushButton2 + + + &Delete + + + + + PushButton3 + + + &Cancel + + + + + PushButton7 + + + &OK + + + true + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonEditSlots + + + &Edit Slots... + + + + + connectionsTable + + + + + + + ConnectionTable +
connectiontable.h
+ + 50 + 50 + + 0 + + 7 + 7 + 0 + 0 + + image0 +
+
+ + + 789c9597c972e3480e40eff5158ec2ada203cd3549c6c41cbcc9b6bccabbddd1078014bdcb9b6449ee987f9f240072caac9e4357d6c1cf5812890490f4ef3f562e8ff6577efcfeed7d4ad3bb72a5bca5b7951fd5ece969f9c79ffffeebdbf7285a69fec7f14af4fdb76fdf47d39572e5e079326e00c10304f24ff8b9c7d463ee71d9e3aac7e31ed70d67dc2ce1cb9e7cd0e3c957863eaff778d4b3bfe8c97be781a71eaff5f8e82bf37ecfff4dc314364b58fdb966096ff6ecf77af6b70d1771b3841f1b8ef366099ff7ec17bdf8faf7970847cd12f9b2e344f8b563890f5e3a96fda0ea98c45fdc71299c765c354c67c249bb1fcd3a56ff271d8b3d9d1b271a0f1d742c725874acfe9d70eef3a9f65bc2e47fa3f16a7d55411d6a3e4e1b0e03bf349e8171144a7e49ceeb295239cb79c3384ccdff76c7b23f14c269e8ccdfa9716ef6b5b18f407857d88585e57bbf65b39f18971a0fc8fd7b6fc624f723e524f9e3d2b8d4f391d49ba74ae5bed585a3c8e49b1d6b7c929f701ca5e65feac10b9dd967c2519485a9dcaf33ce952110cea3caec23e53830f9863045b5ca79ae1c8741263cec58eb59ed390ecd3e378e8d651e44651c85527f20f51cd55eae5c1b27a1f823b9bf388c0b65b831a6b090fd24be384bc24098a6d65fb5ca29ed58fd5f35eccbaf34ff320f922819ab3e487e93d4b3d6eb9b711d4abda0f44352a685d5f39d709db2ca296c380dd2c238366ee5605c1acb3c96f2d3feff148ed25aeb0d1e955d60fd22f94a63178632df79d5d8fa95971d8b9cee5b8e647ec1d038567b40e1a4d567a9d73475b1f14ecb5a7f2cf94a9d4b343eba304e357e3814ce5c6afd22f33b2d5c6ee7295bb6fc4abda4e40af3f7d972a4f52df79bb223ebff79cb2a2736e650ce470fc2652b67b9cfb4726dff5d195776bead96adbf1e3bd67a9779928ebbfdc898357f34346ee7c3a0658d07359eba5922d7fbaebd3fdd6f6e3c567d96f9e4c22cb4780a63eb7f90f7c525596cf11c1a2791ce9bd8d869bd93e4dba55eaeefc781b1dd17ee1b9b3e4b3e9dcbfcc4107f9fc671a4ef9dcc139765763fa4f6943965947a7355b3c45eceebc65965fb851deb79655e662ecfcddf93716172999759966791f67f689ceb79e9a363951f1b9b3d1e76acf36fcf98544e529fdebc954b3f67d42ce1eb86f3465df3fb2e5c14a5d53b2b53a0f316773ad6f922f32c2fa9cd9fdc6f5e79d6f8768d13ebc79d96559fe47dcd6b8a63cdcfbb71126bfcd21f45e0f5f57dbb357691c63f342e2cbea063d597f7b808c9e6151e1993c573d1b2de0fc8fd1711151a1fdf187324f393671debfe92df22a134d67e93fb2a1cd93c05630ef4fe48f25d641c683de2b171a8f399ef3a56f989b1bd273c6dd9f697f7bcc85b7dca8da348be4f41fabf2838b1f7e9cc38d5f715e4fd2888439b9f53639ba72cf55a701b3f0c8cad3ff9de38b57c4bfd15a5678d6f646cfd87857166ef95f46b51f9fdf57c609cda7b756edcbee7ceb850a671c7faf7809e7fccb9d63b6c1b93d5f7ac63d5d7fcd41c245a8fabc685e68f1f8c49ef93e5bda4c0fbd7f9b16b4c5a9ff060ccf63e4b3d52c889c6433bc685da33195bbfc2bd31dbfc947aa5982bf37fddb1c623f39c7cbbda7c94f889cac4ea4df24f55c9367fe43da47159da3c907ea39ac74ebfdfe5fe39e0dac9f71f4abed87fb02993d42b475562effb5dcb36ff243fec3f3f327d4fd1384db5ffd68c9db1bc579cb6faf8619cdafe321f39f39f33721fb46bec4cfe699c19cf3bd6f3ad1ae7c6f2de71ce2549fe71a9dcc917c685324b7eb8aac6767ff27dc763cf92afd1b4590848c8586285e3deaafc6fd94b61346df5b1c61bbcc53bbcff9bf5808ff884136ff5acfadef70dbee02bbee13b4e71861f38c7052ef1d3af555cc375dcc04d1c6069fae47dbfe2166ee30e0e7117f7701f0ff0108f7084c77882a77886e7788197a6cf3e922baf7d8d018618618c895f293acc30c702478000403831fdd247f90e8c019450610c63a8e1066efd4f15dcc13d3cc0a3d77f8256bff2fa531cc233bcc02bbcc13b4c61061f3087052ce11356c5ff1aac9bfed8ebcf701736bc741306b005dbb00343d8853def611f0ee0d0eb1fc1e827fd0f38861338f5becfe01c2ee0d26b5ec13504de4708d12ffa7388bd2481141c64907bed020f0909604944fc8bfe924a4ca8a231d5e2fb956ee896eee8deeb3fd0e32ffa0b7ac29426f041fed4f442afdee28dde694a33faa0f9aff1d0829618d327add21aadd3066dfafd06b445dbb443c3be3eedd21eed7bfd033aa4231ad1319dd0299dd1395dd0255dfd8dff6b0a28c4042af27fcc907fafc879ed73ff199053f145bfc207463c666062e6d2dfd9d2db2db9a20b1e73cd377cfbe5be4a5fb1eb7cc7f7fcc08ffcc4137ee6177ee5377ee729cff883e7bcf8a91ed8d7f7069ef1923f7995d7789d37789307bc4557bccd3b3ce45ddefba9defc4fbebecfe1fffce305eff1fe4ff50c3ea2015e00f93dd7fcb9beae35ff5bf2da5dbf788b676f71891398c03a8c7a6b1d267effcbfff5e33fe8f7fffcebdb7f01520e2ea3 + + + + + PushButton1 + clicked() + ConnectionDialog + addConnection() + + + PushButton7 + clicked() + ConnectionDialog + okClicked() + + + PushButton3 + clicked() + ConnectionDialog + cancelClicked() + + + PushButton2 + clicked() + ConnectionDialog + deleteClicked() + + + buttonEditSlots + clicked() + ConnectionDialog + editSlots() + + + + qptrlist.h + connectionitems.h + connectiondialog.ui.h + + + QPtrList<ConnectionContainer> connections; + QObject *defaultSender; + QObject *defaultReceiver; + + + init() + addConnection() + addConnection( QObject * sender, QObject * receiver, const QString & signal, const QString & slot ) + updateConnectionState( ConnectionContainer * c ) + okClicked() + cancelClicked() + deleteClicked() + editSlots() + setDefault( QObject * sender, QObject * receiver ) + updateEditSlotsButton() + updateConnectionContainers() + ensureConnectionVisible() + + +
diff --git a/tools/designer/designer/connectiondialog.ui.h b/tools/designer/designer/connectiondialog.ui.h new file mode 100644 index 0000000..add7ffd --- /dev/null +++ b/tools/designer/designer/connectiondialog.ui.h @@ -0,0 +1,318 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +#include "mainwindow.h" +#include "formwindow.h" +#include "editfunctionsimpl.h" + +static const char *valid_connection[] = { + "16 14 7 1", + ". c none", + "# c #00c000", + "a c #008000", + "b c #004000", + "c c #000000", + "d c #c0fcc0", + "e c #400000", + "...............d", + "..............d#", + ".............d#a", + "............d#ab", + "...........d#abc", + "..da......d#abc.", + ".d##a....d#abe..", + "cba##a..d#abc...", + ".cba##ad#abe....", + "..eba###abe.....", + "...cba#abc......", + "....cbabc.......", + ".....cec........", + "................" +}; + +static const char * invalid_connection[] = { + "17 18 7 1", + " c None", + ". c #000000", + "+ c #C3C3C3", + "@ c #FFFFFF", + "# c #C00000", + "$ c #FFC0C0", + "% c #FF0000", + " ", + " . ", + " ... ", + " .+.. ", + " ...+@+.. ", + "..+@@@+#.. ", + ".@@@@$#%#.. ", + ".@@$$#%##.. ", + " .$%%%##.... ", + " .%%%##. .. ", + " .%#.. .. ", + " .. .. ", + " .. ", + " .. ", + " .. ", + " .. ", + " ", + " " +}; + +static QPixmap *invalidConnection = 0; +static QPixmap *validConnection = 0; + +void ConnectionDialog::init() +{ + connect( connectionsTable, SIGNAL( currentChanged( int, int ) ), + this, SLOT( updateEditSlotsButton() ) ); + connect( connectionsTable, SIGNAL( resorted() ), + this, SLOT( updateConnectionContainers() ) ); + buttonEditSlots->setEnabled( FALSE ); + + if ( !invalidConnection ) { + invalidConnection = new QPixmap( invalid_connection ); + validConnection = new QPixmap( valid_connection ); + } + + QValueList conns = + MetaDataBase::connections( MainWindow::self->formWindow() ); + for ( QValueList::Iterator it = conns.begin(); + it != conns.end(); ++it ) { + ConnectionContainer *c = addConnection( (*it).sender, (*it).receiver, + (*it).signal, (*it).slot ); + c->setModified( FALSE ); + updateConnectionState( c ); + } + + defaultSender = defaultReceiver = 0; + connectionsTable->setCurrentCell( 0, 0 ); +} + +void ConnectionDialog::addConnection() +{ + addConnection( defaultSender, defaultReceiver, QString::null, QString::null ); + ensureConnectionVisible(); +} + +ConnectionContainer *ConnectionDialog::addConnection( QObject *sender, QObject *receiver, + const QString &signal, + const QString &slot ) +{ + connectionsTable->insertRows( connectionsTable->numRows() ); + + int row = connectionsTable->numRows() - 1; + SenderItem *se; + SignalItem *si; + ReceiverItem *re; + SlotItem *sl; + connectionsTable->setItem( row, 0, + ( se = new SenderItem( connectionsTable, + MainWindow::self->formWindow() ) ) ); + connectionsTable->setItem( row, 1, + ( si = new SignalItem( connectionsTable, + MainWindow::self->formWindow() ) ) ); + connectionsTable->setItem( row, 2, + ( re = new ReceiverItem( connectionsTable, + MainWindow::self->formWindow() ) ) ); + connectionsTable->setItem( row, 3, + ( sl = new SlotItem( connectionsTable, + MainWindow::self->formWindow() ) ) ); + + si->setSender( se ); + re->setSender( se ); + sl->setSender( se ); + se->setSender( se ); + + se->setSignal( si ); + re->setSignal( si ); + sl->setSignal( si ); + si->setSignal( si ); + + se->setReceiver( re ); + si->setReceiver( re ); + sl->setReceiver( re ); + re->setReceiver( re ); + + se->setSlot( sl ); + si->setSlot( sl ); + re->setSlot( sl ); + sl->setSlot( sl ); + + connect( re, SIGNAL( currentReceiverChanged( QObject * ) ), + this, SLOT( updateEditSlotsButton() ) ); + + ConnectionContainer *c = new ConnectionContainer( this, se, si, re, sl, row ); + connections.append( c ); + connect( c, SIGNAL( changed( ConnectionContainer * ) ), + this, SLOT( updateConnectionState( ConnectionContainer * ) ) ); + + connectionsTable->setCurrentCell( row, 0 ); + + connectionsTable->verticalHeader()->setLabel( row, *invalidConnection, QString::null ); + + if ( sender ) + se->setSenderEx( sender ); + defaultSender = sender; + if ( receiver ) + re->setReceiverEx( receiver ); + defaultReceiver = receiver; + + if ( !signal.isEmpty() && !slot.isEmpty() ) { + si->setCurrentItem( signal ); + sl->signalChanged( signal ); + sl->setCurrentItem( slot ); + } + + c->setModified( TRUE ); + return c; +} + +void ConnectionDialog::updateConnectionState( ConnectionContainer *c ) +{ + c->repaint(); + if ( c->isValid() ) + connectionsTable->verticalHeader()->setLabel( c->row(), + *validConnection, QString::null ); + else + connectionsTable->verticalHeader()->setLabel( c->row(), + *invalidConnection, QString::null ); +} + + +void ConnectionDialog::okClicked() +{ + QValueList oldConnections = + MetaDataBase::connections( MainWindow::self->formWindow() ); + QPtrList newConnectionCmds; + QPtrList oldConnectionCmds; + for ( ConnectionContainer *c = connections.first(); c; c = connections.next() ) { + MetaDataBase::Connection conn; + + // find sender widget + conn.sender = MainWindow::self->formWindow()->child( c->senderItem()->currentText() ); + if ( !conn.sender ) // if no sender widget, find sender action + conn.sender = MainWindow::self->formWindow()->findAction( c->senderItem()->currentText() ); + + // find receiver widget + conn.receiver = MainWindow::self->formWindow()->child( c->receiverItem()->currentText() ); + if ( !conn.receiver ) // if no receiver widget, find receiver action + conn.receiver = MainWindow::self->formWindow()->findAction( c->receiverItem()->currentText() ); + + conn.signal = c->signalItem()->currentText(); + conn.slot = c->slotItem()->currentText(); + AddConnectionCommand *cmd = new AddConnectionCommand( tr( "Add Signal/Slot " + "Connection" ), + MainWindow::self->formWindow(), + conn ); + newConnectionCmds.append( cmd ); + } + + + QValueList conns = + MetaDataBase::connections( MainWindow::self->formWindow() ); + for ( QValueList::Iterator it = conns.begin(); + it != conns.end(); ++it ) { + RemoveConnectionCommand *cmd = new RemoveConnectionCommand( tr( "Remove Signal/Slot " + "Connection" ), + MainWindow::self-> + formWindow(), *it ); + oldConnectionCmds.append( cmd ); + } + + MacroCommand *cmd1 = new MacroCommand( tr( "Add Signal/Slot Connections" ), + MainWindow::self->formWindow(), + newConnectionCmds ); + MacroCommand *cmd2 = new MacroCommand( tr( "Remove Signal/Slot Connections" ), + MainWindow::self->formWindow(), + oldConnectionCmds ); + QPtrList cmds; + cmds.append( cmd2 ); + cmds.append( cmd1 ); + MacroCommand *cmd = new MacroCommand( tr( "Edit Signal/Slot Connections" ), + MainWindow::self->formWindow(), + cmds ); + MainWindow::self->formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + + accept(); +} + + +void ConnectionDialog::cancelClicked() +{ + reject(); +} + + +void ConnectionDialog::deleteClicked() +{ + int cr = connectionsTable->currentRow(); + connections.remove( cr ); + connectionsTable->removeRow( cr ); + int i = 0; + for ( ConnectionContainer *c = connections.first(); c; c = connections.next() ) + c->setRow( i++ ); +} + + +void ConnectionDialog::editSlots() +{ + EditFunctions dlg( this, MainWindow::self->formWindow(), TRUE ); + dlg.exec(); + int currentCol = connectionsTable->currentColumn(); + connectionsTable->setCurrentCell( connectionsTable->currentRow(), 0 ); + for ( ConnectionContainer *c = connections.first(); c; c = connections.next() ) { + if ( c->receiverItem()->currentText() != + QString( MainWindow::self->formWindow()->mainContainer()->name() ) ) + continue; + c->slotItem()->customSlotsChanged(); + } + connectionsTable->setCurrentCell( connectionsTable->currentRow(), currentCol ); +} + +void ConnectionDialog::setDefault( QObject *sender, QObject *receiver ) +{ + defaultSender = sender; + defaultReceiver = receiver; +} + +void ConnectionDialog::updateEditSlotsButton() +{ + if ( connectionsTable->currentRow() < 0 || + connectionsTable->currentRow() > (int)connections.count() - 1 ) + return; + ConnectionContainer *c = connections.at( connectionsTable->currentRow() ); + if ( !c || !c->receiverItem() ) + return; + buttonEditSlots->setEnabled( c->receiverItem()->currentText() == + QString( MainWindow::self->formWindow()-> + mainContainer()->name() ) ); +} + +void ConnectionDialog::updateConnectionContainers() +{ + QPtrList newContainers; + for ( int i = 0; i < connectionsTable->numRows(); ++i ) { + for ( ConnectionContainer *c = connections.first(); c; c = connections.next() ) { + if ( c->senderItem() == connectionsTable->item( i, 0 ) ) { + newContainers.append( c ); + c->setRow( i ); + updateConnectionState(c); + break; + } + } + } + connections = newContainers; + updateEditSlotsButton(); +} + +void ConnectionDialog::ensureConnectionVisible() +{ + connectionsTable->ensureCellVisible( connectionsTable->numRows() - 1, 0 ); +} diff --git a/tools/designer/designer/connectionitems.cpp b/tools/designer/designer/connectionitems.cpp new file mode 100644 index 0000000..da903bd --- /dev/null +++ b/tools/designer/designer/connectionitems.cpp @@ -0,0 +1,524 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "connectionitems.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "widgetfactory.h" +#include "project.h" +#include +#include +#include +#include +#include +#include +#include + +static const char* const ignore_slots[] = { + "destroyed()", + "setCaption(const QString&)", + "setIcon(const QPixmap&)", + "setIconText(const QString&)", + "setMouseTracking(bool)", + "clearFocus()", + "setUpdatesEnabled(bool)", + "update()", + "update(int,int,int,int)", + "update(const QRect&)", + "repaint()", + "repaint(bool)", + "repaint(int,int,int,int,bool)", + "repaint(const QRect&,bool)", + "repaint(const QRegion&,bool)", + "show()", + "hide()", + "iconify()", + "showMinimized()", + "showMaximized()", + "showFullScreen()", + "showNormal()", + "polish()", + "constPolish()", + "raise()", + "lower()", + "stackUnder(QWidget*)", + "move(int,int)", + "move(const QPoint&)", + "resize(int,int)", + "resize(const QSize&)", + "setGeometry(int,int,int,int)", + "setGeometry(const QRect&)", + "focusProxyDestroyed()", + "showExtension(bool)", + "setUpLayout()", + "showDockMenu(const QPoint&)", + "init()", + "destroy()", + "deleteLater()", + 0 +}; + +ConnectionItem::ConnectionItem( QTable *table, FormWindow *fw ) + : QComboTableItem( table, QStringList(), FALSE ), formWindow( fw ), conn( 0 ) +{ + setReplaceable( FALSE ); +} + +void ConnectionItem::senderChanged( QObject * ) +{ + emit changed(); + QWidget *w = table()->cellWidget( row(), col() ); + if ( w ) + setContentFromEditor( w ); +} + +void ConnectionItem::receiverChanged( QObject * ) +{ + emit changed(); + QWidget *w = table()->cellWidget( row(), col() ); + if ( w ) + setContentFromEditor( w ); +} + +void ConnectionItem::signalChanged( const QString & ) +{ + emit changed(); + QWidget *w = table()->cellWidget( row(), col() ); + if ( w ) + setContentFromEditor( w ); +} + +void ConnectionItem::slotChanged( const QString & ) +{ + emit changed(); + QWidget *w = table()->cellWidget( row(), col() ); + if ( w ) + setContentFromEditor( w ); +} + +void ConnectionItem::setSender( SenderItem *i ) +{ + connect( i, SIGNAL( currentSenderChanged( QObject * ) ), + this, SLOT( senderChanged( QObject * ) ) ); +} + +void ConnectionItem::setReceiver( ReceiverItem *i ) +{ + connect( i, SIGNAL( currentReceiverChanged( QObject * ) ), + this, SLOT( receiverChanged( QObject * ) ) ); +} + +void ConnectionItem::setSignal( SignalItem *i ) +{ + connect( i, SIGNAL( currentSignalChanged( const QString & ) ), + this, SLOT( signalChanged( const QString & ) ) ); +} + +void ConnectionItem::setSlot( SlotItem *i ) +{ + connect( i, SIGNAL( currentSlotChanged( const QString & ) ), + this, SLOT( slotChanged( const QString & ) ) ); +} + +void ConnectionItem::paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ) +{ + p->fillRect( 0, 0, cr.width(), cr.height(), + selected ? cg.brush( QColorGroup::Highlight ) + : cg.brush( QColorGroup::Base ) ); + + int w = cr.width(); + int h = cr.height(); + + int x = 0; + + if ( currentText()[0] == '<' ) + p->setPen( QObject::red ); + else if ( selected ) + p->setPen( cg.highlightedText() ); + else + p->setPen( cg.text() ); + + QFont f( p->font() ); + QFont oldf( p->font() ); + if ( conn && conn->isModified() ) { + f.setBold( TRUE ); + p->setFont( f ); + } + + p->drawText( x + 2, 0, w - x - 4, h, alignment(), currentText() ); + p->setFont( oldf ); +} + +void ConnectionItem::setConnection( ConnectionContainer *c ) +{ + conn = c; +} + +// ------------------------------------------------------------------ + +static void appendChildActions( QAction *action, QStringList &lst ) +{ + QObjectListIt it( *action->children() ); + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast(o) ) + continue; + lst << o->name(); + if ( o->children() && ::qt_cast(o) ) + appendChildActions( (QAction*)o, lst ); + } +} + +static QStringList flatActions( const QPtrList &l ) +{ + QStringList lst; + + QPtrListIterator it( l ); + while ( it.current() ) { + QAction *action = it.current(); + lst << action->name(); + if ( action->children() && ::qt_cast(action) ) + appendChildActions( action, lst ); + ++it; + } + + return lst; +} + +// ------------------------------------------------------------------ + +SenderItem::SenderItem( QTable *table, FormWindow *fw ) + : ConnectionItem( table, fw ) +{ + QStringList lst; + + QPtrDictIterator it( *formWindow->widgets() ); + while ( it.current() ) { + if ( lst.find( it.current()->name() ) != lst.end() ) { + ++it; + continue; + } + if ( !QString( it.current()->name() ).startsWith( "qt_dead_widget_" ) && + !::qt_cast(it.current()) && + !::qt_cast(it.current()) && + !::qt_cast(it.current()) && + qstrcmp( it.current()->name(), "central widget" ) != 0 ) { + lst << it.current()->name(); + } + ++it; + } + + lst += flatActions( formWindow->actionList() ); + + lst.prepend( "" ); + lst.sort(); + setStringList( lst ); +} + +QWidget *SenderItem::createEditor() const +{ + QComboBox *cb = (QComboBox*)ConnectionItem::createEditor(); + cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) ); + connect( cb, SIGNAL( activated( const QString & ) ), + this, SLOT( senderChanged( const QString & ) ) ); + return cb; +} + +void SenderItem::setSenderEx( QObject *sender ) +{ + setCurrentItem( sender->name() ); + emit currentSenderChanged( sender ); +} + +void SenderItem::senderChanged( const QString &sender ) +{ + QObject *o = formWindow->child( sender, "QObject" ); + if ( !o ) + o = formWindow->findAction( sender ); + if ( !o ) + return; + emit currentSenderChanged( o ); +} + + + +// ------------------------------------------------------------------ + +ReceiverItem::ReceiverItem( QTable *table, FormWindow *fw ) + : ConnectionItem( table, fw ) +{ + QStringList lst; + + QPtrDictIterator it( *formWindow->widgets() ); + while ( it.current() ) { + if ( lst.find( it.current()->name() ) != lst.end() ) { + ++it; + continue; + } + if ( !QString( it.current()->name() ).startsWith( "qt_dead_widget_" ) && + !::qt_cast(it.current()) && + !::qt_cast(it.current()) && + !::qt_cast(it.current()) && + qstrcmp( it.current()->name(), "central widget" ) != 0 ) { + lst << it.current()->name(); + } + ++it; + } + + lst += flatActions( formWindow->actionList() ); + + lst.prepend( "" ); + lst.sort(); + setStringList( lst ); +} + +QWidget *ReceiverItem::createEditor() const +{ + QComboBox *cb = (QComboBox*)ConnectionItem::createEditor(); + cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) ); + connect( cb, SIGNAL( activated( const QString & ) ), + this, SLOT( receiverChanged( const QString & ) ) ); + return cb; +} + +void ReceiverItem::setReceiverEx( QObject *receiver ) +{ + setCurrentItem( receiver->name() ); + emit currentReceiverChanged( receiver ); +} + +void ReceiverItem::receiverChanged( const QString &receiver ) +{ + QObject *o = formWindow->child( receiver, "QObject" ); + if ( !o ) + o = formWindow->findAction( receiver ); + if ( !o ) + return; + emit currentReceiverChanged( o ); +} + + + +// ------------------------------------------------------------------ + +SignalItem::SignalItem( QTable *table, FormWindow *fw ) + : ConnectionItem( table, fw ) +{ + QStringList lst; + lst << ""; + lst.sort(); + setStringList( lst ); +} + +void SignalItem::senderChanged( QObject *sender ) +{ + QStrList sigs = sender->metaObject()->signalNames( TRUE ); + sigs.remove( "destroyed()" ); + sigs.remove( "destroyed(QObject*)" ); + sigs.remove( "accessibilityChanged(int)" ); + sigs.remove( "accessibilityChanged(int,int)" ); + + QStringList lst = QStringList::fromStrList( sigs ); + + if ( ::qt_cast(sender) ) { + MetaDataBase::CustomWidget *w = ( (CustomWidget*)sender )->customWidget(); + for ( QValueList::Iterator it = w->lstSignals.begin(); + it != w->lstSignals.end(); ++it ) + lst << MetaDataBase::normalizeFunction( *it ); + } + + if ( sender == formWindow->mainContainer() ) { + QStringList extra = MetaDataBase::signalList( formWindow ); + if ( !extra.isEmpty() ) + lst += extra; + } + + lst.prepend( "" ); + + lst.sort(); + setStringList( lst ); + + ConnectionItem::senderChanged( sender ); +} + +QWidget *SignalItem::createEditor() const +{ + QComboBox *cb = (QComboBox*)ConnectionItem::createEditor(); + cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) ); + connect( cb, SIGNAL( activated( const QString & ) ), + this, SIGNAL( currentSignalChanged( const QString & ) ) ); + return cb; +} + +// ------------------------------------------------------------------ + +SlotItem::SlotItem( QTable *table, FormWindow *fw ) + : ConnectionItem( table, fw ) +{ + QStringList lst; + lst << ""; + lst.sort(); + setStringList( lst ); + + lastReceiver = 0; + lastSignal = ""; +} + +void SlotItem::receiverChanged( QObject *receiver ) +{ + lastReceiver = receiver; + updateSlotList(); + ConnectionItem::receiverChanged( receiver ); +} + +void SlotItem::signalChanged( const QString &signal ) +{ + lastSignal = signal; + updateSlotList(); + ConnectionItem::signalChanged( signal ); +} + +bool SlotItem::ignoreSlot( const char* slot ) const +{ +#ifndef QT_NO_SQL + if ( qstrcmp( slot, "update()" ) == 0 && + ::qt_cast(lastReceiver) ) + return FALSE; +#endif + + for ( int i = 0; ignore_slots[i]; i++ ) { + if ( qstrcmp( slot, ignore_slots[i] ) == 0 ) + return TRUE; + } + + if ( !formWindow->isMainContainer( (QWidget*)lastReceiver ) ) { + if ( qstrcmp( slot, "close()" ) == 0 ) + return TRUE; + } + + if ( qstrcmp( slot, "setFocus()" ) == 0 ) + if ( lastReceiver->isWidgetType() && + ( (QWidget*)lastReceiver )->focusPolicy() == QWidget::NoFocus ) + return TRUE; + + return FALSE; +} + +void SlotItem::updateSlotList() +{ + QStringList lst; + if ( !lastReceiver || lastSignal == "" ) { + lst << ""; + lst.sort(); + setStringList( lst ); + return; + } + + QString signal = MetaDataBase::normalizeFunction( lastSignal ); + int n = lastReceiver->metaObject()->numSlots( TRUE ); + QStringList slts; + + for( int i = 0; i < n; ++i ) { + // accept only public slots. For the form window, also accept protected slots + const QMetaData* md = lastReceiver->metaObject()->slot( i, TRUE ); + if ( ( (lastReceiver->metaObject()->slot( i, TRUE )->access == QMetaData::Public) || + (formWindow->isMainContainer( (QWidget*)lastReceiver ) && + lastReceiver->metaObject()->slot(i, TRUE)->access == + QMetaData::Protected) ) && + !ignoreSlot( md->name ) && + checkConnectArgs( signal.latin1(), lastReceiver, md->name ) ) + if ( lst.find( md->name ) == lst.end() ) + lst << MetaDataBase::normalizeFunction( md->name ); + } + + LanguageInterface *iface = + MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( !iface || iface->supports( LanguageInterface::ConnectionsToCustomSlots ) ) { + if ( formWindow->isMainContainer( (QWidget*)lastReceiver ) ) { + QValueList moreSlots = MetaDataBase::slotList( formWindow ); + if ( !moreSlots.isEmpty() ) { + for ( QValueList::Iterator it = moreSlots.begin(); + it != moreSlots.end(); ++it ) { + QCString s = (*it).function; + if ( !s.data() ) + continue; + s = MetaDataBase::normalizeFunction( s ); + if ( checkConnectArgs( signal.latin1(), lastReceiver, s ) ) { + if ( lst.find( (*it).function ) == lst.end() ) + lst << s; + } + } + } + } + } + + if ( ::qt_cast(lastReceiver) ) { + MetaDataBase::CustomWidget *w = ( (CustomWidget*)lastReceiver )->customWidget(); + for ( QValueList::Iterator it = w->lstSlots.begin(); + it != w->lstSlots.end(); ++it ) { + QCString s = (*it).function; + if ( !s.data() ) + continue; + s = MetaDataBase::normalizeFunction( s ); + if ( checkConnectArgs( signal.latin1(), lastReceiver, s ) ) { + if ( lst.find( (*it).function ) == lst.end() ) + lst << s; + } + } + } + + lst.prepend( "" ); + lst.sort(); + setStringList( lst ); +} + +QWidget *SlotItem::createEditor() const +{ + QComboBox *cb = (QComboBox*)ConnectionItem::createEditor(); + cb->listBox()->setMinimumWidth( cb->fontMetrics().width( "01234567890123456789012345678901234567890123456789" ) ); + connect( cb, SIGNAL( activated( const QString & ) ), + this, SIGNAL( currentSlotChanged( const QString & ) ) ); + return cb; +} + +void SlotItem::customSlotsChanged() +{ + QString currSlot = currentText(); + updateSlotList(); + setCurrentItem( "" ); + setCurrentItem( currSlot ); + emit currentSlotChanged( currentText() ); +} diff --git a/tools/designer/designer/connectionitems.h b/tools/designer/designer/connectionitems.h new file mode 100644 index 0000000..f60ef2c --- /dev/null +++ b/tools/designer/designer/connectionitems.h @@ -0,0 +1,227 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CONNECTIONITEMS_H +#define CONNECTIONITEMS_H + +class FormWindow; + +#include + +class SenderItem; +class ReceiverItem; +class SignalItem; +class SlotItem; +class ConnectionContainer; + + +class ConnectionItem : public QObject, + public QComboTableItem +{ + Q_OBJECT + +public: + ConnectionItem( QTable *table, FormWindow *fw ); + + void paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ); + + void setSender( SenderItem *i ); + void setReceiver( ReceiverItem *i ); + void setSignal( SignalItem *i ); + void setSlot( SlotItem *i ); + void setConnection( ConnectionContainer *c ); + +public slots: + virtual void senderChanged( QObject *sender ); + virtual void receiverChanged( QObject *receiver ); + virtual void signalChanged( const QString &sig ); + virtual void slotChanged( const QString &slot ); + +signals: + void changed(); + +protected: + FormWindow *formWindow; + +private: + ConnectionContainer *conn; + +}; + +// ------------------------------------------------------------------ + +class SenderItem : public ConnectionItem +{ + Q_OBJECT + +public: + SenderItem( QTable *table, FormWindow *fw ); + QWidget *createEditor() const; + void setSenderEx( QObject *sender ); + +signals: + void currentSenderChanged( QObject *sender ); + +private slots: + void senderChanged( const QString &sender ); + +}; + +// ------------------------------------------------------------------ + +class ReceiverItem : public ConnectionItem +{ + Q_OBJECT + +public: + ReceiverItem( QTable *table, FormWindow *fw ); + QWidget *createEditor() const; + void setReceiverEx( QObject *receiver ); + +signals: + void currentReceiverChanged( QObject *receiver ); + +private slots: + void receiverChanged( const QString &receiver ); + +}; + +// ------------------------------------------------------------------ + +class SignalItem : public ConnectionItem +{ + Q_OBJECT + +public: + SignalItem( QTable *table, FormWindow *fw ); + + void senderChanged( QObject *sender ); + QWidget *createEditor() const; + +signals: + void currentSignalChanged( const QString & ); + +}; + +// ------------------------------------------------------------------ + +class SlotItem : public ConnectionItem +{ + Q_OBJECT + +public: + SlotItem( QTable *table, FormWindow *fw ); + + void receiverChanged( QObject *receiver ); + void signalChanged( const QString &signal ); + QWidget *createEditor() const; + + void customSlotsChanged(); + +signals: + void currentSlotChanged( const QString & ); + +private: + void updateSlotList(); + bool ignoreSlot( const char* slot ) const; + +private: + QObject *lastReceiver; + QString lastSignal; + +}; + +// ------------------------------------------------------------------ + +class ConnectionContainer : public QObject +{ + Q_OBJECT + +public: + ConnectionContainer( QObject *parent, SenderItem *i1, SignalItem *i2, + ReceiverItem *i3, SlotItem *i4, int r ) + : QObject( parent ), mod( FALSE ), se( i1 ), si( i2 ), + re( i3 ), sl( i4 ), rw ( r ) { + i1->setConnection( this ); + i2->setConnection( this ); + i3->setConnection( this ); + i4->setConnection( this ); + connect( i1, SIGNAL( changed() ), this, SLOT( somethingChanged() ) ); + connect( i2, SIGNAL( changed() ), this, SLOT( somethingChanged() ) ); + connect( i3, SIGNAL( changed() ), this, SLOT( somethingChanged() ) ); + connect( i4, SIGNAL( changed() ), this, SLOT( somethingChanged() ) ); + } + + bool isModified() const { return mod; } + void setModified( bool b ) { mod = b; repaint(); } + bool isValid() const { + return se->currentText()[0] != '<' && + si->currentText()[0] != '<' && + re->currentText()[0] != '<' && + sl->currentText()[0] != '<'; + } + + void repaint() { + se->table()->updateCell( se->row(), se->col() ); + si->table()->updateCell( si->row(), si->col() ); + re->table()->updateCell( re->row(), re->col() ); + sl->table()->updateCell( sl->row(), sl->col() ); + } + + int row() const { return rw; } + void setRow( int r ) { rw = r; } + + SenderItem *senderItem() const { return se; } + SignalItem *signalItem() const { return si; } + ReceiverItem *receiverItem() const { return re; } + SlotItem *slotItem() const { return sl; } + +public slots: + void somethingChanged() { mod = TRUE; emit changed( this ); } + +signals: + void changed( ConnectionContainer *c ); + +private: + bool mod; + SenderItem *se; + SignalItem *si; + ReceiverItem *re; + SlotItem *sl; + int rw; + +}; + + +#endif diff --git a/tools/designer/designer/connectiontable.cpp b/tools/designer/designer/connectiontable.cpp new file mode 100644 index 0000000..e262f7f --- /dev/null +++ b/tools/designer/designer/connectiontable.cpp @@ -0,0 +1,61 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "connectiontable.h" + +ConnectionTable::ConnectionTable( QWidget *parent, const char *name ) + : QTable( 0, 4, parent, name ) +{ + setSorting( TRUE ); + setShowGrid( FALSE ); + setFocusStyle( FollowStyle ); + setSelectionMode( SingleRow ); + horizontalHeader()->setLabel( 0, tr( "Sender" ) ); + horizontalHeader()->setLabel( 1, tr( "Signal" ) ); + horizontalHeader()->setLabel( 2, tr( "Receiver" ) ); + horizontalHeader()->setLabel( 3, tr( "Slot" ) ); + setColumnStretchable( 0, TRUE ); + setColumnStretchable( 1, TRUE ); + setColumnStretchable( 2, TRUE ); + setColumnStretchable( 3, TRUE ); +} + +void ConnectionTable::sortColumn( int col, bool ascending, bool ) +{ + horizontalHeader()->setSortIndicator( col, ascending ); + if ( isEditing() ) + endEdit( currEditRow(), currEditCol(), FALSE, FALSE ); + QTable::sortColumn( col, ascending, TRUE ); + setCurrentCell( 0, 0 ); + emit resorted(); +} diff --git a/tools/designer/designer/connectiontable.h b/tools/designer/designer/connectiontable.h new file mode 100644 index 0000000..4d0c50e --- /dev/null +++ b/tools/designer/designer/connectiontable.h @@ -0,0 +1,53 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CONNECTIONTABLE_H +#define CONNECTIONTABLE_H + +#include + +class ConnectionTable : public QTable +{ + Q_OBJECT + +public: + ConnectionTable( QWidget *parent, const char *name ); + + void sortColumn( int col, bool ascending, bool wholeRows ); + +signals: + void resorted(); + +}; + +#endif diff --git a/tools/designer/designer/createtemplate.ui b/tools/designer/designer/createtemplate.ui new file mode 100644 index 0000000..110cfc8 --- /dev/null +++ b/tools/designer/designer/createtemplate.ui @@ -0,0 +1,236 @@ + +CreateTemplate +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + QDialog + + name + CreateTemplate + + + geometry + + 0 + 0 + 347 + 248 + + + + caption + Create Template + + + sizeGripEnabled + true + + + + margin + 11 + + + spacing + 6 + + + QLabel + + name + TextLabel1 + + + text + Template &Name: + + + buddy + editName + + + + QLineEdit + + name + editName + + + toolTip + Name of the new template + + + whatsThis + Enter the name of the new template + + + + QListBox + + name + listClass + + + toolTip + Class of the new template + + + whatsThis + Enter the name of the class which should be used as the template's base class + + + + QLayoutWidget + + name + Layout1 + + + + margin + 0 + + + spacing + 6 + + + + name + Spacer1 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + QPushButton + + name + buttonCreate + + + text + C&reate + + + default + true + + + whatsThis + Creates the new template + + + + QPushButton + + name + PushButton1 + + + text + &Cancel + + + whatsThis + Closes the Dialog + + + + + + QLabel + + name + TextLabel2 + + + text + &Baseclass for Template: + + + buddy + listClass + + + + + name + Spacer2 + + + orientation + Vertical + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + + + + buttonCreate + clicked() + CreateTemplate + accept() + + + PushButton1 + clicked() + CreateTemplate + reject() + + + diff --git a/tools/designer/designer/customwidgeteditor.ui b/tools/designer/designer/customwidgeteditor.ui new file mode 100644 index 0000000..6f025fc --- /dev/null +++ b/tools/designer/designer/customwidgeteditor.ui @@ -0,0 +1,1385 @@ + +CustomWidgetEditorBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + CustomWidgetEditorBase + + + + 0 + 0 + 712 + 386 + + + + Edit Custom Widgets + + + true + + + <b>Edit Custom Widgets</b><p>Add or delete custom widgets from <i>Qt Designer</i>'s database, and edit the properties of existing widgets.</p> + + + + unnamed + + + 11 + + + 6 + + + + boxWidgets + + + The list of all custom widgets known to Qt Designer. + + + + + buttonNewWidget + + + &New Widget + + + Add new custom widget. + + + <b>Create an empty custom widget and add it to the list.</b><p>New custom widgets have a default name and header file, which must both be changed to appropriate values.</p> + + + + + buttonDeleteWidget + + + &Delete Widget + + + Delete custom widget + + + <b>Delete the selected custom widget.</b><p>You can only delete widgets that are not used in any open form.</p> + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + helpButton + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonCancel + + + &Close + + + true + + + Closes the Dialog. + + + + + + + Vertical Spacing1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonLoad + + + &Load Descriptions... + + + Loads widget description file + + + <b>Load Descriptions</b><p>Loads a file which contains descriptions of custom widgets, so that these custom widgets can be used in the Qt Designer.</p> +<p>Since it is a lot of work to type in all the information for custom widgets, you should consider using the createcw tool which is in $QTDIR/tools/designer/tools/createcw. Using createcw you can create custom widget description files for your custom widgets without the need to type in all the information manually. For more information about the README file in the createcw directory</p> + + + + + buttonSave + + + &Save Descriptions... + + + Saves widget description file + + + <b>Save Descriptions</b><p>Saves all the descriptions of the shown custom widgets to a file which can then be used to import the custom widgets elsewhere. + + + + + TabWidget1 + + + Change the properties of the selected custom widget. + + + + Widget2 + + + De&finition + + + + unnamed + + + 11 + + + 6 + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + previewPixmap + + + + + + + + buttonChoosePixmap + + + + 30 + 22 + + + + ... + + + Select a Pixmap + + + <b>Select a pixmap file.</b><p>The pixmap will be used to represent the widget in forms.</b> + + + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + editHeader + + + Enter filename + + + <b>Change the header file's name for the selected custom widget.</b><p>The header file will be included by forms using the widget.</p> + + + + + buttonChooseHeader + + + + 30 + 22 + + + + ... + + + Choose headerfile + + + Look for the header file using a filedialog. + + + + + + Global + + + + + Local + + + + localGlobalCombo + + + Select access + + + <b>Change how the include file will be included.</b><p>Global include files will be included using &lt;&gt;-brackets, while local files will included using quotation marks.</p> + + + + + + + editClass + + + Change classname + + + <b>Enter the classname for the selected custom widget.</b><p>A class of that name must be defined in the header file.</p> + + + + + Label11 + + + Heade&rfile: + + + editHeader + + + + + Label10 + + + Cl&ass: + + + editClass + + + + + Label2 + + + Pixmap: + + + + + Label7 + + + Si&ze Hint: + + + spinWidth + + + + + TextLabel1_2 + + + Size P&olicy + + + sizeHor + + + + + + Fixed + + + + + Minimum + + + + + Maximum + + + + + Preferred + + + + + MinimumExpanding + + + + + Expanding + + + + sizeVer + + + Vertical Sizepolicy + + + Choose the Vertical size policy + + + + + spinWidth + + + 32767 + + + -1 + + + -1 + + + Size hint width + + + <b>Set the size hint for the selected widget.</b><p>The size hint provides the recommended size for the widget. Enter a sizehint of -1/-1 if no size is recommended.</p> + + + + + spinHeight + + + 32767 + + + -1 + + + -1 + + + Size hint height + + + <b>Set the size hint for the selected widget.</b><p>The size hint provides the recommended size for the widget. Enter a sizehint of -1/-1 if no size is recommended.</p> + + + + + + Fixed + + + + + Minimum + + + + + Maximum + + + + + Preferred + + + + + MinimumExpanding + + + + + Expanding + + + + sizeHor + + + Horizontal Sizepolicy + + + Choose the horizontal size policy for the widget + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + checkContainer + + + Con&tainer Widget + + + Container Widget + + + <p><b>Container Widget</b></p> +<p>If this custom widget is able to contain other widgets (children), check this checkbox.</p> + + + + + + + Widget3 + + + Si&gnals + + + + unnamed + + + 11 + + + 6 + + + + listSignals + + + The list of all the signals that the selected widget can emit. + + + + + Layout40 + + + + unnamed + + + 0 + + + 6 + + + + Spacer1_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonAddSignal + + + N&ew Signal + + + true + + + Add new signal + + + <b>Add a new signal for the current custom widget.</b><p>An argument list should be provided in the signal's name, and the name must be unique.</p> + + + + + buttonRemoveSignal + + + Dele&te Signal + + + true + + + Delete signal + + + <b>Delete the signal.</b><p>All connections using this signal will also be deleted.</p> + + + + + + + Layout38 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + S&ignal: + + + editSignal + + + + + editSignal + + + Change signal name + + + <b>Change the name of the selected slot.</b><p>An argument list should be provided in the signal's name, and the name must be unique.</p> + + + + + + + + + Widget4 + + + S&lots + + + + unnamed + + + 11 + + + 6 + + + + + Slot + + + true + + + true + + + + + Access + + + true + + + true + + + + listSlots + + + true + + + true + + + The list of all the custom widget's slots. + + + + + TextLabel2 + + + Sl&ot: + + + editSlot + + + + + editSlot + + + Change slot name + + + <b>Change the name of the selected slot.</b><p>An argument list should be provided in the signal's name, and the name must be unique.</p> + + + + + TextLabel3 + + + &Access: + + + comboAccess + + + + + + public + + + + + protected + + + + comboAccess + + + Change slot access + + + <b>Change the slot's access policy.</b><p>You can only connect to the widget's public slots.</p> + + + + + Layout7 + + + + unnamed + + + 0 + + + 6 + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonAddSlot + + + N&ew Slot + + + true + + + Add new slot + + + <b>Add a new slot to the current custom widget.</b><p>An argument list should be provided in the signal's name, and the name must be unique.</p> + + + + + buttonRemoveSlot + + + Dele&te Slot + + + true + + + Delete slot + + + <b>Delete the slot.</b><p>All connections using this slot will also be deleted.</p> + + + + + + + + + Widget5 + + + &Properties + + + + unnamed + + + 11 + + + 6 + + + + Layout7_2 + + + + unnamed + + + 0 + + + 6 + + + + Spacer2_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonAddProperty + + + N&ew Property + + + true + + + Add new property + + + <b>Add a new property to the current custom widget.</b><p>The properties must be implemented in the class using Qt's property system.</p> + + + + + buttonRemoveProperty + + + Dele&te Property + + + true + + + Delete property + + + Deletes the selected property. + + + + + + + + String + + + + + CString + + + + + StringList + + + + + Bool + + + + + Int + + + + + UInt + + + + + Font + + + + + Color + + + + + Rect + + + + + Point + + + + + Size + + + + + Pixmap + + + + + Palette + + + + + Cursor + + + + + SizePolicy + + + + comboType + + + Select property type + + + <b>Select the type of the property.</b><p>The propertiy must be implemented in the class using Qt's property system.</p><p>You can use integer types to support enumeration properties in the property editor.</p> + + + + + + Property + + + true + + + true + + + + + Type + + + true + + + true + + + + listProperties + + + true + + + true + + + <b>The list of the current widget's properties.</b><p>The properties of the custom widget can be changed in the property editor.</p> + + + + + editProperty + + + Change property name + + + <b>Enter a name for the property.</b><p>The properties must be implemented in the class using Qt's property system.</p> + + + + + TextLabel2_2 + + + P&roperty Name: + + + editProperty + + + + + TextLabel3_2 + + + T&ype: + + + comboType + + + + + + + + + + boxWidgets + selectionChanged(QListBoxItem*) + CustomWidgetEditorBase + currentWidgetChanged(QListBoxItem*) + + + boxWidgets + currentChanged(QListBoxItem*) + CustomWidgetEditorBase + currentWidgetChanged(QListBoxItem*) + + + buttonNewWidget + clicked() + CustomWidgetEditorBase + addWidgetClicked() + + + buttonDeleteWidget + clicked() + CustomWidgetEditorBase + deleteWidgetClicked() + + + editClass + textChanged(const QString&) + CustomWidgetEditorBase + classNameChanged(const QString&) + + + editHeader + textChanged(const QString&) + CustomWidgetEditorBase + headerFileChanged(const QString&) + + + spinWidth + valueChanged(int) + CustomWidgetEditorBase + widthChanged(int) + + + spinHeight + valueChanged(int) + CustomWidgetEditorBase + heightChanged(int) + + + buttonChoosePixmap + clicked() + CustomWidgetEditorBase + pixmapChoosen() + + + localGlobalCombo + highlighted(int) + CustomWidgetEditorBase + includePolicyChanged(int) + + + buttonChooseHeader + clicked() + CustomWidgetEditorBase + chooseHeader() + + + buttonCancel + clicked() + CustomWidgetEditorBase + closeClicked() + + + listSignals + currentChanged(QListBoxItem*) + CustomWidgetEditorBase + currentSignalChanged(QListBoxItem*) + + + listSignals + selectionChanged(QListBoxItem*) + CustomWidgetEditorBase + currentSignalChanged(QListBoxItem*) + + + buttonRemoveSignal + clicked() + CustomWidgetEditorBase + removeSignal() + + + editSignal + textChanged(const QString&) + CustomWidgetEditorBase + signalNameChanged(const QString&) + + + listSlots + currentChanged(QListViewItem*) + CustomWidgetEditorBase + currentSlotChanged(QListViewItem*) + + + listSlots + selectionChanged(QListViewItem*) + CustomWidgetEditorBase + currentSlotChanged(QListViewItem*) + + + buttonRemoveSlot + clicked() + CustomWidgetEditorBase + removeSlot() + + + editSlot + textChanged(const QString&) + CustomWidgetEditorBase + slotNameChanged(const QString&) + + + comboAccess + activated(const QString&) + CustomWidgetEditorBase + slotAccessChanged(const QString&) + + + listProperties + currentChanged(QListViewItem*) + CustomWidgetEditorBase + currentPropertyChanged(QListViewItem*) + + + listProperties + selectionChanged(QListViewItem*) + CustomWidgetEditorBase + currentPropertyChanged(QListViewItem*) + + + buttonRemoveProperty + clicked() + CustomWidgetEditorBase + removeProperty() + + + editProperty + textChanged(const QString&) + CustomWidgetEditorBase + propertyNameChanged(const QString&) + + + comboType + activated(const QString&) + CustomWidgetEditorBase + propertyTypeChanged(const QString&) + + + buttonLoad + clicked() + CustomWidgetEditorBase + loadDescription() + + + buttonSave + clicked() + CustomWidgetEditorBase + saveDescription() + + + sizeHor + activated(int) + CustomWidgetEditorBase + horDataChanged(int) + + + sizeVer + activated(int) + CustomWidgetEditorBase + verDataChanged(int) + + + buttonAddProperty + clicked() + CustomWidgetEditorBase + addProperty() + + + checkContainer + toggled(bool) + CustomWidgetEditorBase + widgetIsContainer(bool) + + + buttonAddSignal + clicked() + CustomWidgetEditorBase + addSignal() + + + buttonAddSlot + clicked() + CustomWidgetEditorBase + addSlot() + + init() + destroy() + addProperty() + addSignal() + addWidgetClicked() + chooseHeader() + classNameChanged( const QString & ) + closeClicked() + currentPropertyChanged( QListViewItem * ) + currentSignalChanged( QListBoxItem * ) + currentSlotChanged( QListViewItem * ) + currentWidgetChanged( QListBoxItem * ) + deleteWidgetClicked() + headerFileChanged( const QString & ) + heightChanged( int ) + horDataChanged(int) + includePolicyChanged( int ) + loadDescription() + addSlot() + pixmapChoosen() + propertyNameChanged( const QString & ) + propertyTypeChanged( const QString & ) + removeProperty() + removeSignal() + removeSlot() + saveDescription() + signalNameChanged( const QString & ) + slotAccessChanged( const QString & ) + slotNameChanged( const QString & ) + verDataChanged(int) + widgetIsContainer(bool) + widthChanged( int ) + + + buttonCancel + boxWidgets + buttonNewWidget + buttonDeleteWidget + buttonLoad + buttonSave + TabWidget1 + editClass + editHeader + buttonChooseHeader + localGlobalCombo + buttonChoosePixmap + spinWidth + spinHeight + sizeHor + sizeVer + checkContainer + helpButton + listSignals + buttonAddSignal + buttonRemoveSignal + editSignal + listSlots + buttonAddSlot + buttonRemoveSlot + editSlot + comboAccess + listProperties + buttonAddProperty + buttonRemoveProperty + editProperty + comboType + + diff --git a/tools/designer/designer/customwidgeteditorimpl.cpp b/tools/designer/designer/customwidgeteditorimpl.cpp new file mode 100644 index 0000000..412f50f --- /dev/null +++ b/tools/designer/designer/customwidgeteditorimpl.cpp @@ -0,0 +1,845 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "customwidgeteditorimpl.h" +#include "defs.h" +#include "pixmapchooser.h" +#include "mainwindow.h" +#include "asciivalidator.h" +#include "resource.h" +#include "widgetfactory.h" +#include "widgetdatabase.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CustomWidgetEditor::CustomWidgetEditor( QWidget *parent, MainWindow *mw ) + : CustomWidgetEditorBase( parent, 0, TRUE ), mainWindow( mw ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + checkTimer = new QTimer( this ); + connect( checkTimer, SIGNAL( timeout() ), + this, SLOT( checkWidgetName() ) ); + + editClass->setEnabled( FALSE ); + editHeader->setEnabled( FALSE ); + buttonChooseHeader->setEnabled( FALSE ); + buttonChoosePixmap->setEnabled( FALSE ); + spinWidth->setEnabled( FALSE ); + spinHeight->setEnabled( FALSE ); + sizeHor->setEnabled( FALSE ); + sizeVer->setEnabled( FALSE ); + checkContainer->setEnabled( FALSE ); + localGlobalCombo->setEnabled( FALSE ); + editClass->setValidator( new AsciiValidator( QString(":"), editClass ) ); + editSignal->setValidator( new AsciiValidator( TRUE, editSignal ) ); + editSlot->setValidator( new AsciiValidator( TRUE, editSignal ) ); + editProperty->setValidator( new AsciiValidator( editSignal ) ); + editSignal->setEnabled( FALSE ); + buttonRemoveSignal->setEnabled( FALSE ); + + setupDefinition(); + setupSignals(); + setupSlots(); + setupProperties(); +} + +void CustomWidgetEditor::setupDefinition() +{ + QPtrList *lst = MetaDataBase::customWidgets(); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + QListBoxItem *i; + if ( w->pixmap ) + i = new QListBoxPixmap( boxWidgets, *w->pixmap, w->className ); + else + i = new QListBoxText( boxWidgets, w->className ); + customWidgets.insert( i, w ); + } + + if ( boxWidgets->firstItem() ) { + boxWidgets->setCurrentItem( boxWidgets->firstItem() ); + boxWidgets->setSelected( boxWidgets->firstItem(), TRUE ); + } + oldItem = 0; +} + +void CustomWidgetEditor::setupSignals() +{ + editSignal->setEnabled( FALSE ); + buttonRemoveSignal->setEnabled( FALSE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w ) + return; + listSignals->clear(); + for ( QValueList::Iterator it = w->lstSignals.begin(); it != w->lstSignals.end(); ++it ) + listSignals->insertItem( QString( *it ) ); + if ( listSignals->firstItem() ) { + listSignals->setCurrentItem( listSignals->firstItem() ); + listSignals->setSelected( listSignals->firstItem(), TRUE ); + } +} + +void CustomWidgetEditor::setupSlots() +{ + editSlot->setEnabled( FALSE ); + comboAccess->setEnabled( FALSE ); + buttonRemoveSlot->setEnabled( FALSE ); + + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w ) + return; + listSlots->clear(); + for ( QValueList::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) + (void)new QListViewItem( listSlots, (*it).function, (*it).access ); + + if ( listSlots->firstChild() ) { + listSlots->setCurrentItem( listSlots->firstChild() ); + listSlots->setSelected( listSlots->firstChild(), TRUE ); + } +} + +void CustomWidgetEditor::setupProperties() +{ + editProperty->setEnabled( FALSE ); + comboType->setEnabled( FALSE ); + buttonRemoveProperty->setEnabled( FALSE ); + + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w ) + return; + listProperties->clear(); + for ( QValueList::Iterator it = w->lstProperties.begin(); it != w->lstProperties.end(); ++it ) + (void)new QListViewItem( listProperties, (*it).property, (*it).type ); + + if ( listProperties->firstChild() ) { + listProperties->setCurrentItem( listProperties->firstChild() ); + listProperties->setSelected( listProperties->firstChild(), TRUE ); + } +} + +void CustomWidgetEditor::currentWidgetChanged( QListBoxItem *i ) +{ + checkTimer->stop(); + checkWidgetName(); + + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) { + buttonChooseHeader->setEnabled( FALSE ); + editClass->setEnabled( FALSE ); + editHeader->setEnabled( FALSE ); + buttonChoosePixmap->setEnabled( FALSE ); + spinWidth->setEnabled( FALSE ); + spinHeight->setEnabled( FALSE ); + localGlobalCombo->setEnabled( FALSE ); + sizeHor->setEnabled( FALSE ); + sizeVer->setEnabled( FALSE ); + checkContainer->setEnabled( FALSE ); + return; + } + + buttonChooseHeader->setEnabled( TRUE ); + editClass->setEnabled( TRUE ); + editHeader->setEnabled( TRUE ); + buttonChoosePixmap->setEnabled( TRUE ); + spinWidth->setEnabled( TRUE ); + spinHeight->setEnabled( TRUE ); + localGlobalCombo->setEnabled( TRUE ); + sizeHor->setEnabled( TRUE ); + sizeVer->setEnabled( TRUE ); + checkContainer->setEnabled( TRUE ); + + editClass->blockSignals( TRUE ); + editClass->setText( w->className ); + editClass->blockSignals( FALSE ); + editHeader->setText( w->includeFile ); + localGlobalCombo->setCurrentItem( (int)w->includePolicy ); + if ( w->pixmap ) + previewPixmap->setPixmap( *w->pixmap ); + else + previewPixmap->setText( "" ); + spinWidth->setValue( w->sizeHint.width() ); + spinHeight->setValue( w->sizeHint.height() ); + sizeHor->setCurrentItem( size_type_to_int( w->sizePolicy.horData() ) ); + sizeVer->setCurrentItem( size_type_to_int( w->sizePolicy.verData() ) ); + checkContainer->setChecked( w->isContainer ); + + setupSignals(); + setupSlots(); + setupProperties(); +} + +void CustomWidgetEditor::addWidgetClicked() +{ + oldItem = 0; + checkTimer->stop(); + checkWidgetName(); + + MetaDataBase::CustomWidget *w = new MetaDataBase::CustomWidget; + QString s = w->className; + if ( !MetaDataBase::addCustomWidget( w ) ) { + QMessageBox::information( this, tr( "Adding a Custom Widget" ), + tr( "Custom widget names must be unique.\n" + "A custom widget called '%1' already exists, so it is not possible " + "to add another widget with this name." ).arg( s ) ); + return; + } + + QListBoxPixmap *i = new QListBoxPixmap( boxWidgets, *w->pixmap, w->className ); + customWidgets.insert( i, w ); + + boxWidgets->setCurrentItem( i ); + boxWidgets->setSelected( i, TRUE ); +} + +void CustomWidgetEditor::classNameChanged( const QString &s ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + WidgetDatabase::customWidgetClassNameChanged( w->className, s ); + + checkTimer->stop(); + boxWidgets->blockSignals( TRUE ); + oldName = w->className; + w->className = s; + QListBoxItem *old = i; + if ( w->pixmap ) + boxWidgets->changeItem( *w->pixmap, s, boxWidgets->currentItem() ); + else + boxWidgets->changeItem( s, boxWidgets->currentItem() ); + i = boxWidgets->item( boxWidgets->currentItem() ); + oldItem = i; + customWidgets.insert( i, w ); + customWidgets.remove( old ); + boxWidgets->blockSignals( FALSE ); + checkTimer->start( 1000, TRUE ); +} + +void CustomWidgetEditor::deleteWidgetClicked() +{ + oldItem = 0; + checkTimer->stop(); + checkWidgetName(); + + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + + if ( mainWindow->isCustomWidgetUsed( w ) ) { + QMessageBox::information( mainWindow, tr( "Removing Custom Widget" ), + tr( "The custom widget '%1' is in use, so it cannot be removed." ). + arg( w->className ) ); + return; + } + + if ( !i || !w ) + return; + + MetaDataBase::CustomWidget *cw = MetaDataBase::customWidget( mainWindow->currentTool() ); + if ( cw == w ) + mainWindow->resetTool(); + + MetaDataBase::removeCustomWidget( w ); + customWidgets.remove( i ); + delete i; + + i = boxWidgets->item( boxWidgets->currentItem() ); + if ( i ) { + boxWidgets->setCurrentItem( i ); + boxWidgets->setSelected( i, TRUE ); + } +} + +void CustomWidgetEditor::headerFileChanged( const QString &s ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->includeFile = s; +} + +void CustomWidgetEditor::heightChanged( int h ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->sizeHint.setHeight( h ); + updateCustomWidgetSizes(); +} + +void CustomWidgetEditor::includePolicyChanged( int p ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->includePolicy = (MetaDataBase::CustomWidget::IncludePolicy)p; +} + +void CustomWidgetEditor::pixmapChoosen() +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + QPixmap pix = qChoosePixmap( this ); + if ( pix.isNull() ) + return; + delete w->pixmap; + w->pixmap = new QPixmap( pix ); + + boxWidgets->blockSignals( TRUE ); + QListBoxItem *old = i; + boxWidgets->changeItem( *w->pixmap, w->className, boxWidgets->currentItem() ); + i = boxWidgets->item( boxWidgets->currentItem() ); + customWidgets.insert( i, w ); + customWidgets.remove( old ); + boxWidgets->blockSignals( FALSE ); + previewPixmap->setPixmap( *w->pixmap ); +} + +void CustomWidgetEditor::widthChanged( int wid ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->sizeHint.setWidth( wid ); + updateCustomWidgetSizes(); +} + +MetaDataBase::CustomWidget *CustomWidgetEditor::findWidget( QListBoxItem *i ) +{ + if ( !i ) + return 0; + + QMap::Iterator it = customWidgets.find( i ); + if ( it == customWidgets.end() ) + return 0; + return *it; +} + +void CustomWidgetEditor::chooseHeader() +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + QString h = QFileDialog::getOpenFileName( QString::null, tr( "Header Files (*.h *.h++ *.hxx *.hh)" ), this ); + if ( h.isEmpty() ) + return; + editHeader->setText( h ); + localGlobalCombo->setCurrentItem( (int)MetaDataBase::CustomWidget::Global ); +} + +void CustomWidgetEditor::checkWidgetName() +{ + QListBoxItem *i = oldItem ? oldItem : boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + oldItem = 0; + if ( !i || !w ) + return; + + if ( MetaDataBase::isWidgetNameUsed( w ) ) { + QString s = w->className; + w->className = oldName; + QMessageBox::information( this, tr( "Renaming a Custom Widget" ), + tr( "Custom widget names must be unique.\n" + "A custom widget called '%1' already exists, so it is not possible " + "to rename this widget with this name." ).arg( s ) ); + if ( i != boxWidgets->item( boxWidgets->currentItem() ) ) { + boxWidgets->setCurrentItem( i ); + qApp->processEvents(); + } + editClass->setText( w->className ); + classNameChanged( w->className ); + } +} + +void CustomWidgetEditor::closeClicked() +{ + oldItem = 0; + checkTimer->stop(); + checkWidgetName(); + accept(); +} + +void CustomWidgetEditor::currentSignalChanged( QListBoxItem *i ) +{ + editSignal->blockSignals( TRUE ); + editSignal->setText( "" ); + editSignal->blockSignals( FALSE ); + + if ( !i ) { + editSignal->setEnabled( FALSE ); + buttonRemoveSignal->setEnabled( FALSE ); + return; + } + + editSignal->blockSignals( TRUE ); + editSignal->setEnabled( TRUE ); + buttonRemoveSignal->setEnabled( TRUE ); + editSignal->setText( i->text() ); + editSignal->blockSignals( FALSE ); +} + +void CustomWidgetEditor::addSignal() +{ + QListBoxItem *i = new QListBoxText( listSignals, "signal()" ); + listSignals->setCurrentItem( i ); + listSignals->setSelected( i, TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w ) + w->lstSignals.append( i->text().latin1() ); +} + +void CustomWidgetEditor::removeSignal() +{ + QString s = listSignals->currentText(); + delete listSignals->item( listSignals->currentItem() ); + if ( listSignals->currentItem() != -1 ) + listSignals->setSelected( listSignals->currentItem(), TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w ) + w->lstSignals.remove( s.latin1() ); +} + +void CustomWidgetEditor::signalNameChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || listSignals->currentItem() == -1 ) + return; + + QValueList::Iterator it = w->lstSignals.find( listSignals->currentText().latin1() ); + if ( it != w->lstSignals.end() ) + w->lstSignals.remove( it ); + listSignals->blockSignals( TRUE ); + listSignals->changeItem( s, listSignals->currentItem() ); + listSignals->blockSignals( FALSE ); + w->lstSignals.append( s.latin1() ); +} + +void CustomWidgetEditor::slotAccessChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || !listSlots->currentItem() ) + return; + + MetaDataBase::Function slot; + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + QValueList::Iterator it = w->lstSlots.find( slot ); + if ( it != w->lstSlots.end() ) + w->lstSlots.remove( it ); + listSlots->currentItem()->setText( 1, s ); + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + w->lstSlots.append( slot ); +} + +void CustomWidgetEditor::slotNameChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || !listSlots->currentItem() ) + return; + + MetaDataBase::Function slot; + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + slot.type = "slot"; + QValueList::Iterator it = w->lstSlots.find( slot ); + if ( it != w->lstSlots.end() ) + w->lstSlots.remove( it ); + listSlots->currentItem()->setText( 0, s ); + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + w->lstSlots.append( slot ); +} + +void CustomWidgetEditor::addSlot() +{ + QListViewItem *i = new QListViewItem( listSlots, "slot()", "public" ); + listSlots->setCurrentItem( i ); + listSlots->setSelected( i, TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w ) { + MetaDataBase::Function slot; + slot.function = "slot()"; + slot.access = "public"; + slot.type = "slot"; + w->lstSlots.append( slot ); + } +} + +void CustomWidgetEditor::removeSlot() +{ + MetaDataBase::Function slot; + slot.function = "1 2 3"; + if ( listSlots->currentItem() ) { + slot.function = listSlots->currentItem()->text( 0 ); + slot.access = listSlots->currentItem()->text( 1 ); + } + delete listSlots->currentItem(); + if ( listSlots->currentItem() ) + listSlots->setSelected( listSlots->currentItem(), TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w && slot.function != "1 2 3" ) + w->lstSlots.remove( slot ); +} + +void CustomWidgetEditor::currentSlotChanged( QListViewItem *i ) +{ + editSlot->blockSignals( TRUE ); + editSlot->setText( "" ); + editSignal->blockSignals( FALSE ); + + if ( !i ) { + editSlot->setEnabled( FALSE ); + comboAccess->setEnabled( FALSE ); + buttonRemoveSlot->setEnabled( FALSE ); + return; + } + + editSlot->setEnabled( TRUE ); + comboAccess->setEnabled( TRUE ); + buttonRemoveSlot->setEnabled( TRUE ); + editSlot->blockSignals( TRUE ); + comboAccess->blockSignals( TRUE ); + editSlot->setText( i->text( 0 ) ); + if ( i->text( 1 ) == tr( "protected" ) ) + comboAccess->setCurrentItem( 1 ); + else + comboAccess->setCurrentItem( 0 ); + editSlot->blockSignals( FALSE ); + comboAccess->blockSignals( FALSE ); +} + +void CustomWidgetEditor::propertyTypeChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || !listProperties->currentItem() ) + return; + + MetaDataBase::Property property; + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + QValueList::Iterator it = w->lstProperties.find( property ); + if ( it != w->lstProperties.end() ) + w->lstProperties.remove( it ); + listProperties->currentItem()->setText( 1, s ); + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + w->lstProperties.append( property ); +} + +void CustomWidgetEditor::propertyNameChanged( const QString &s ) +{ + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( !w || !listProperties->currentItem() ) + return; + + MetaDataBase::Property property; + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + QValueList::Iterator it = w->lstProperties.find( property ); + if ( it != w->lstProperties.end() ) + w->lstProperties.remove( it ); + listProperties->currentItem()->setText( 0, s ); + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + w->lstProperties.append( property ); +} + +void CustomWidgetEditor::addProperty() +{ + QListViewItem *i = new QListViewItem( listProperties, "property", "String" ); + listProperties->setCurrentItem( i ); + listProperties->setSelected( i, TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w ) { + MetaDataBase::Property prop; + prop.property = "property"; + prop.type = "String"; + w->lstProperties.append( prop ); + } +} + +void CustomWidgetEditor::removeProperty() +{ + MetaDataBase::Property property; + property.property = "1 2 3"; + if ( listProperties->currentItem() ) { + property.property = listProperties->currentItem()->text( 0 ); + property.type = listProperties->currentItem()->text( 1 ); + } + delete listProperties->currentItem(); + if ( listProperties->currentItem() ) + listProperties->setSelected( listProperties->currentItem(), TRUE ); + MetaDataBase::CustomWidget *w = findWidget( boxWidgets->item( boxWidgets->currentItem() ) ); + if ( w && property.property != "1 2 3" ) + w->lstProperties.remove( property ); +} + +void CustomWidgetEditor::currentPropertyChanged( QListViewItem *i ) +{ + editProperty->blockSignals( TRUE ); + editProperty->setText( "" ); + editSignal->blockSignals( FALSE ); + + if ( !i ) { + editProperty->setEnabled( FALSE ); + comboType->setEnabled( FALSE ); + buttonRemoveProperty->setEnabled( FALSE ); + return; + } + + editProperty->setEnabled( TRUE ); + comboType->setEnabled( TRUE ); + buttonRemoveProperty->setEnabled( TRUE ); + editProperty->blockSignals( TRUE ); + comboType->blockSignals( TRUE ); + editProperty->setText( i->text( 0 ) ); + + for ( int j = 0; j < comboType->count(); ++j ) { + if ( i->text( 1 ) == comboType->text( j ) ) { + comboType->setCurrentItem( j ); + break; + } + } + editProperty->blockSignals( FALSE ); + comboType->blockSignals( FALSE ); +} + +static QString makeIndent2( int indent ) +{ + QString s; + s.fill( ' ', indent * 4 ); + return s; +} + +static QString entitize2( const QString &s ) +{ + QString s2 = s; + s2 = s2.replace( "\"", """ ); + s2 = s2.replace( "&", "&" ); + s2 = s2.replace( ">", ">" ); + s2 = s2.replace( "<", "<" ); + s2 = s2.replace( "'", "'" ); + return s2; +} + +void CustomWidgetEditor::saveDescription() +{ + QString fn = QFileDialog::getSaveFileName( QString::null, tr( "Custom-Widget Description (*.cw);;All Files (*)" ), this ); + if ( fn.isEmpty() ) + return; + + if ( QFileInfo( fn ).extension() != "cw" ) + fn += ".cw"; + QFile f( fn ); + if ( !f.open( IO_WriteOnly ) ) + return; + + QTextStream ts( &f ); + ts.setCodec( QTextCodec::codecForName( "UTF-8" ) ); + int indent = 0; + + ts << "" << endl; + + ts << makeIndent2( indent ) << "" << endl; + indent++; + + QPtrList *lst = MetaDataBase::customWidgets(); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + ts << makeIndent2( indent ) << "" << endl; + indent++; + ts << makeIndent2( indent ) << "" << w->className << "" << endl; + ts << makeIndent2( indent ) << "
includePolicy == MetaDataBase::CustomWidget::Local ? "local" : "global" ) + << "\">" << w->includeFile << "
" << endl; + ts << makeIndent2( indent ) << "" << endl; + indent++; + ts << makeIndent2( indent ) << "" << w->sizeHint.width() << "" << endl; + ts << makeIndent2( indent ) << "" << w->sizeHint.height() << "" << endl; + indent--; + ts << makeIndent2( indent ) << "" << endl; + ts << makeIndent2( indent ) << "" << (int)w->isContainer << "" << endl; + ts << makeIndent2( indent ) << "" << endl; + indent++; + ts << makeIndent2( indent ) << "" << (int)w->sizePolicy.horData() << "" << endl; + ts << makeIndent2( indent ) << "" << (int)w->sizePolicy.verData() << "" << endl; + indent--; + ts << makeIndent2( indent ) << "" << endl; + ts << makeIndent2( indent ) << "" << endl; + indent++; + Resource::saveImageData( w->pixmap->convertToImage(), ts, indent ); + indent--; + ts << makeIndent2( indent ) << "" << endl; + if ( !w->lstSignals.isEmpty() ) { + for ( QValueList::Iterator it = w->lstSignals.begin(); it != w->lstSignals.end(); ++it ) + ts << makeIndent2( indent ) << "" << entitize2( *it ) << "" << endl; + } + if ( !w->lstSlots.isEmpty() ) { + for ( QValueList::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) + ts << makeIndent2( indent ) << "" << entitize2( (*it).function ) << "" << endl; + } + if ( !w->lstProperties.isEmpty() ) { + for ( QValueList::Iterator it = w->lstProperties.begin(); it != w->lstProperties.end(); ++it ) + ts << makeIndent2( indent ) << "" << entitize2( (*it).property ) << "" << endl; + } + indent--; + ts << makeIndent2( indent ) << "
" << endl; + } + + indent--; + ts << makeIndent2( indent ) << "
" << endl; + ts << "
" << endl; +} + +void CustomWidgetEditor::loadDescription() +{ + QString fn = QFileDialog::getOpenFileName( QString::null, tr( "Custom-Widget Description (*.cw);;All Files (*)" ), this ); + if ( fn.isEmpty() ) + return; + + QFile f( fn ); + if ( !f.open( IO_ReadOnly ) ) + return; + + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( &f, &errMsg, &errLine ) ) { + qDebug( QString("Parse error: ") + errMsg + QString(" in line %d"), errLine ); + return; + } + + QDomElement firstWidget = doc.firstChild().toElement().firstChild().toElement(); + + while ( firstWidget.tagName() != "customwidgets" ) + firstWidget = firstWidget.nextSibling().toElement(); + + Resource::loadCustomWidgets( firstWidget, 0 ); + boxWidgets->clear(); + setupDefinition(); + setupSignals(); + setupSlots(); + setupProperties(); +} + +void CustomWidgetEditor::updateCustomWidgetSizes() +{ + if ( cwLst.isEmpty() ) + cwLst = *mainWindow->queryList( "CustomWidget" ); + for ( QObject *o = cwLst.first(); o; o = cwLst.next() ) + ( (QWidget*)o )->updateGeometry(); +} + +void CustomWidgetEditor::horDataChanged( int a ) +{ + QSizePolicy::SizeType st = int_to_size_type( a ); + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + QSizePolicy osp = w->sizePolicy; + w->sizePolicy.setHorData( st ); + if ( cwLst.isEmpty() ) + cwLst = *mainWindow->queryList( "CustomWidget" ); + for ( QObject *o = cwLst.first(); o; o = cwLst.next() ) { + CustomWidget *cw = (CustomWidget*)o; + if ( cw->realClassName() == boxWidgets->currentText() ) { + if ( cw->sizePolicy() == osp ) + cw->setSizePolicy( w->sizePolicy ); + } + } +} + +void CustomWidgetEditor::verDataChanged( int a ) +{ + QSizePolicy::SizeType st = int_to_size_type( a ); + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + QSizePolicy osp = w->sizePolicy; + w->sizePolicy.setVerData( st ); + if ( cwLst.isEmpty() ) + cwLst = *mainWindow->queryList( "CustomWidget" ); + for ( QObject *o = cwLst.first(); o; o = cwLst.next() ) { + CustomWidget *cw = (CustomWidget*)o; + if ( cw->realClassName() == boxWidgets->currentText() ) { + if ( cw->sizePolicy() == osp ) + cw->setSizePolicy( w->sizePolicy ); + } + } +} + +void CustomWidgetEditor::widgetIsContainer( bool b ) +{ + QListBoxItem *i = boxWidgets->item( boxWidgets->currentItem() ); + MetaDataBase::CustomWidget *w = findWidget( i ); + if ( !i || !w ) + return; + + w->isContainer = b; + WidgetDatabaseRecord *r = WidgetDatabase::at( w->id ); + if ( r ) + r->isContainer = b; +} diff --git a/tools/designer/designer/customwidgeteditorimpl.h b/tools/designer/designer/customwidgeteditorimpl.h new file mode 100644 index 0000000..67e0141 --- /dev/null +++ b/tools/designer/designer/customwidgeteditorimpl.h @@ -0,0 +1,105 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CUSTOMWIDGETEDITORIMPL_H +#define CUSTOMWIDGETEDITORIMPL_H + +#include "customwidgeteditor.h" +#include "metadatabase.h" + +#include +#include + +class QTimer; +class QListBoxItem; +class MainWindow; + +class CustomWidgetEditor : public CustomWidgetEditorBase +{ + Q_OBJECT + +public: + CustomWidgetEditor( QWidget *parent , MainWindow *mw); + +protected slots: + void addWidgetClicked(); + void classNameChanged( const QString & ); + void currentWidgetChanged( QListBoxItem * ); + void deleteWidgetClicked(); + void headerFileChanged( const QString & ); + void heightChanged( int ); + void includePolicyChanged( int ); + void pixmapChoosen(); + void widthChanged( int ); + void chooseHeader(); + void checkWidgetName(); + void closeClicked(); + void currentSignalChanged( QListBoxItem *i ); + void addSignal(); + void removeSignal(); + void signalNameChanged( const QString &s ); + void slotAccessChanged( const QString & ); + void slotNameChanged( const QString & ); + void addSlot(); + void removeSlot(); + void currentSlotChanged( QListViewItem * ); + void propertyTypeChanged( const QString & ); + void propertyNameChanged( const QString & ); + void addProperty(); + void removeProperty(); + void currentPropertyChanged( QListViewItem * ); + void saveDescription(); + void loadDescription(); + void horDataChanged( int ); + void verDataChanged( int ); + void widgetIsContainer( bool ); + +private: + MetaDataBase::CustomWidget *findWidget( QListBoxItem *i ); + void setupDefinition(); + void setupSignals(); + void setupSlots(); + void setupProperties(); + void updateCustomWidgetSizes(); + +private: + QMap customWidgets; + QString oldName; + QTimer *checkTimer; + QListBoxItem *oldItem; + MainWindow *mainWindow; + QObjectList cwLst; + +}; + +#endif diff --git a/tools/designer/designer/database.cpp b/tools/designer/designer/database.cpp new file mode 100644 index 0000000..22c4f87 --- /dev/null +++ b/tools/designer/designer/database.cpp @@ -0,0 +1,129 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#if defined(DESIGNER) +#include "database.h" +#else +#include "database2.h" +#endif + +#ifndef QT_NO_SQL + +#if defined(DESIGNER) +#include "formwindow.h" +#include "mainwindow.h" +#endif + +#include +#include +#include +#include + +DatabaseSupport::DatabaseSupport() +{ + con = 0; + frm = 0; + parent = 0; +} + +void DatabaseSupport::initPreview( const QString &connection, const QString &table, QObject *o, + const QMap &databaseControls ) +{ + tbl = table; + dbControls = databaseControls; + parent = o; + + if ( connection != "(default)" ) + con = QSqlDatabase::database( connection ); + else + con = QSqlDatabase::database(); + frm = new QSqlForm( o, table ); + for ( QMap::Iterator it = dbControls.begin(); it != dbControls.end(); ++it ) { + QObject *chld = parent->child( it.key(), "QWidget" ); + if ( !chld ) + continue; + frm->insert( (QWidget*)chld, *it ); + } +} + +QDesignerDataBrowser::QDesignerDataBrowser( QWidget *parent, const char *name ) + : QDataBrowser( parent, name ) +{ +} + +bool QDesignerDataBrowser::event( QEvent* e ) +{ + bool b = QDataBrowser::event( e ); +#if defined(DESIGNER) + if ( MainWindow::self->isPreviewing() ) { +#endif + if ( e->type() == QEvent::Show ) { + if ( con ) { + QSqlCursor* cursor = new QSqlCursor( tbl, TRUE, con ); + setSqlCursor( cursor, TRUE ); + setForm( frm ); + refresh(); + first(); + } + return TRUE; + } +#if defined(DESIGNER) + } +#endif + return b; +} + +QDesignerDataView::QDesignerDataView( QWidget *parent, const char *name ) + : QDataView( parent, name ) +{ +} + +bool QDesignerDataView::event( QEvent* e ) +{ + bool b = QDataView::event( e ); +#if defined(DESIGNER) + if ( MainWindow::self->isPreviewing() ) { +#endif + if ( e->type() == QEvent::Show ) { + setForm( frm ); + readFields(); + return TRUE; + } +#if defined(DESIGNER) + } +#endif + return b; +} + + +#endif diff --git a/tools/designer/designer/database.h b/tools/designer/designer/database.h new file mode 100644 index 0000000..7643c10 --- /dev/null +++ b/tools/designer/designer/database.h @@ -0,0 +1,90 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DATABASE_H +#define DATABASE_H + +#include "qfeatures.h" + +#ifndef QT_NO_SQL +#include +#include +#include +#include + +class QSqlDatabase; +class QSqlForm; + +class DatabaseSupport +{ +public: + DatabaseSupport(); + virtual ~DatabaseSupport() {} + + void initPreview( const QString &connection, const QString &table, QObject *o, + const QMap &databaseControls ); + +protected: + QSqlDatabase* con; + QSqlForm* frm; + QString tbl; + QMap dbControls; + QObject *parent; + +}; + +class QDesignerDataBrowser : public QDataBrowser, public DatabaseSupport +{ + Q_OBJECT + +public: + QDesignerDataBrowser( QWidget *parent, const char *name ); + +protected: + bool event( QEvent* e ); +}; + +class QDesignerDataView : public QDataView, public DatabaseSupport +{ + Q_OBJECT + +public: + QDesignerDataView( QWidget *parent, const char *name ); + +protected: + bool event( QEvent* e ); + +}; +#endif + +#endif diff --git a/tools/designer/designer/database2.h b/tools/designer/designer/database2.h new file mode 100644 index 0000000..5830b45 --- /dev/null +++ b/tools/designer/designer/database2.h @@ -0,0 +1,95 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DATABASE2_H +#define DATABASE2_H + +#include "qfeatures.h" + +#ifndef QT_NO_SQL +#include +#include +#include +#include + +class QSqlDatabase; +class QSqlForm; + +class DatabaseSupport2 +{ +public: + DatabaseSupport2(); + virtual ~DatabaseSupport2() {} + + void initPreview( const QString &connection, const QString &table, QObject *o, + const QMap &databaseControls ); + +protected: + QSqlDatabase* con; + QSqlForm* frm; + QString tbl; + QMap dbControls; + QObject *parent; + +}; + +class QDesignerDataBrowser2 : public QDataBrowser, public DatabaseSupport2 +{ + Q_OBJECT + +public: + QDesignerDataBrowser2( QWidget *parent, const char *name ); + +protected: + bool event( QEvent* e ); +}; + +class QDesignerDataView2 : public QDataView, public DatabaseSupport2 +{ + Q_OBJECT + +public: + QDesignerDataView2( QWidget *parent, const char *name ); + +protected: + bool event( QEvent* e ); + +}; + +#define DatabaseSupport DatabaseSupport2 +#define QDesignerDataBrowser QDesignerDataBrowser2 +#define QDesignerDataView QDesignerDataView2 + +#endif + +#endif diff --git a/tools/designer/designer/dbconnection.ui b/tools/designer/designer/dbconnection.ui new file mode 100644 index 0000000..b81f005 --- /dev/null +++ b/tools/designer/designer/dbconnection.ui @@ -0,0 +1,229 @@ + +DatabaseConnectionWidget +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + DatabaseConnectionWidget + + + + 0 + 0 + 199 + 185 + + + + Edit Database Connection + + + + unnamed + + + 0 + + + 6 + + + + TextLabel3 + + + &Database Name: + + + editDatabase + + + + + TextLabel4 + + + &Username: + + + editUsername + + + + + TextLabel4_2 + + + &Password: + + + editPassword + + + + + TextLabel2 + + + D&river + + + comboDriver + + + + + editName + + + false + + + + + TextLabel5 + + + &Hostname: + + + editHostname + + + + + comboDriver + + + false + + + true + + + + + TextLabel1 + + + &Name: + + + editName + + + + + editHostname + + + false + + + + + TextLabel1_2 + + + P&ort + + + editPort + + + + + editUsername + + + false + + + + + editPassword + + + false + + + Password + + + + + editDatabase + + + false + + + + + editPort + + + false + + + Default + + + 65535 + + + -1 + + + -1 + + + + + + + + editName + comboDriver + editDatabase + editUsername + editPassword + editHostname + editPort + + + init() + destroy() + + + diff --git a/tools/designer/designer/dbconnectioneditor.ui b/tools/designer/designer/dbconnectioneditor.ui new file mode 100644 index 0000000..9707293 --- /dev/null +++ b/tools/designer/designer/dbconnectioneditor.ui @@ -0,0 +1,154 @@ + +DatabaseConnectionEditorBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + DatabaseConnectionEditorBase + + + + 0 + 0 + 393 + 286 + + + + Connect + + + + unnamed + + + 11 + + + 6 + + + + PushButton2 + + + &Cancel + + + + + PushButton1 + + + &OK + + + true + + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + grp + + + Connection Details + + + + unnamed + + + 11 + + + 6 + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + PushButton2 + clicked() + DatabaseConnectionEditorBase + reject() + + + PushButton1 + clicked() + DatabaseConnectionEditorBase + accept() + + init() + destroy() + + + PushButton1 + PushButton2 + + diff --git a/tools/designer/designer/dbconnectionimpl.cpp b/tools/designer/designer/dbconnectionimpl.cpp new file mode 100644 index 0000000..b3a70ef --- /dev/null +++ b/tools/designer/designer/dbconnectionimpl.cpp @@ -0,0 +1,87 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "dbconnectionimpl.h" +#include "dbconnection.h" +#include "project.h" +#include "asciivalidator.h" +#include +#include +#include +#include +#include +#include + +DatabaseConnectionEditor::DatabaseConnectionEditor( DatabaseConnection* connection, QWidget* parent, + const char* name, bool modal, WFlags fl ) + : DatabaseConnectionEditorBase( parent, name, modal, fl ), conn( connection ) +{ + connectionWidget = new DatabaseConnectionWidget( grp ); + grpLayout->addWidget( connectionWidget, 0, 0 ); + init(); +} + +DatabaseConnectionEditor::~DatabaseConnectionEditor() +{ +} + +void DatabaseConnectionEditor::accept() +{ +#ifndef QT_NO_SQL + conn->setUsername( connectionWidget->editUsername->text() ); + conn->setPassword( connectionWidget->editPassword->text() ); + conn->setHostname( connectionWidget->editHostname->text() ); +#endif + DatabaseConnectionEditorBase::accept(); +} + +void DatabaseConnectionEditor::init() +{ + connectionWidget->editName->setEnabled( FALSE ); + connectionWidget->editName->setValidator( new AsciiValidator( connectionWidget->editName ) ); + connectionWidget->editName->setText( conn->name() ); + connectionWidget->comboDriver->setEnabled( FALSE ); + connectionWidget->comboDriver->lineEdit()->setText( conn->driver() ); + connectionWidget->editDatabase->setEnabled( FALSE ); + connectionWidget->editDatabase->setText( conn->database() ); + connectionWidget->editUsername->setEnabled( TRUE ); + connectionWidget->editUsername->setText( conn->username() ); + connectionWidget->editPassword->setEnabled( TRUE ); + connectionWidget->editPassword->setText( "" ); + connectionWidget->editHostname->setEnabled( TRUE ); + connectionWidget->editHostname->setText( conn->hostname() ); + connectionWidget->editPort->setEnabled( TRUE ); + connectionWidget->editPort->setValue( conn->port() ); + connectionWidget->editUsername->setFocus(); + connectionWidget->editUsername->selectAll(); +} diff --git a/tools/designer/designer/dbconnectionimpl.h b/tools/designer/designer/dbconnectionimpl.h new file mode 100644 index 0000000..7e5a9cf --- /dev/null +++ b/tools/designer/designer/dbconnectionimpl.h @@ -0,0 +1,64 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DBCONNECTIONIMPL_H +#define DBCONNECTIONIMPL_H + +#include "dbconnectioneditor.h" + +class DatabaseConnection; +class DatabaseConnectionWidget; +class QGridLayout; + +class DatabaseConnectionEditor : public DatabaseConnectionEditorBase +{ + Q_OBJECT + +public: + DatabaseConnectionEditor( DatabaseConnection* connection, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~DatabaseConnectionEditor(); + +public slots: + void accept(); +private: + void init(); + +private: + DatabaseConnection *conn; + QGridLayout* lay; + DatabaseConnectionWidget* connectionWidget; + +}; + +#endif // DBCONNECTIONIMPL_H diff --git a/tools/designer/designer/dbconnections.ui b/tools/designer/designer/dbconnections.ui new file mode 100644 index 0000000..9d1fdff --- /dev/null +++ b/tools/designer/designer/dbconnections.ui @@ -0,0 +1,328 @@ + +DatabaseConnectionBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + DatabaseConnectionBase + + + + 0 + 0 + 512 + 309 + + + + Edit Database Connections + + + true + + + + unnamed + + + 11 + + + 6 + + + + buttonNew + + + &New Connection + + + + + listConnections + + + + + buttonDelete + + + &Delete Connection + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonClose + + + &Close + + + true + + + Close the dialog and discard any changes. + + + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + grp + + + Connection + + + + unnamed + + + 11 + + + 6 + + + + Spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + Spacer4 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonConnect + + + false + + + Connec&t + + + + + Spacer5 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + Spacer6 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + buttonClose + clicked() + DatabaseConnectionBase + accept() + + + buttonNew + clicked() + DatabaseConnectionBase + newConnection() + + + buttonDelete + clicked() + DatabaseConnectionBase + deleteConnection() + + + buttonConnect + clicked() + DatabaseConnectionBase + doConnect() + + + listConnections + highlighted(const QString&) + DatabaseConnectionBase + currentConnectionChanged(const QString&) + + + listConnections + selected(const QString&) + DatabaseConnectionBase + currentConnectionChanged(const QString&) + + init() + destroy() + currentConnectionChanged( const QString & ) + deleteConnection() + newConnection() + connectionNameChanged( const QString & ) + doConnect() + + + buttonClose + listConnections + buttonNew + buttonDelete + buttonConnect + buttonHelp + + diff --git a/tools/designer/designer/dbconnectionsimpl.cpp b/tools/designer/designer/dbconnectionsimpl.cpp new file mode 100644 index 0000000..8980977 --- /dev/null +++ b/tools/designer/designer/dbconnectionsimpl.cpp @@ -0,0 +1,201 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "dbconnectionsimpl.h" +#include +#include +#include +#include "project.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "mainwindow.h" +#include "asciivalidator.h" + +static bool blockChanges = FALSE; + +/* + * Constructs a DatabaseConnectionsEditor which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +DatabaseConnectionsEditor::DatabaseConnectionsEditor( Project *pro, QWidget* parent, const char* name, bool modal, WFlags fl ) + : DatabaseConnectionBase( parent, name, modal, fl ), project( pro ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + connectionWidget = new DatabaseConnectionWidget( grp ); + grpLayout->addWidget( connectionWidget, 0, 0 ); +#ifndef QT_NO_SQL + QPtrList lst = project->databaseConnections(); + for ( DatabaseConnection *conn = lst.first(); conn; conn = lst.next() ) + listConnections->insertItem( conn->name() ); + connectionWidget->comboDriver->insertStringList( QSqlDatabase::drivers() ); +#endif + connectionWidget->editName->setValidator( new AsciiValidator( connectionWidget->editName ) ); + enableAll( FALSE ); +} + +DatabaseConnectionsEditor::~DatabaseConnectionsEditor() +{ +} + +void DatabaseConnectionsEditor::deleteConnection() +{ + if ( listConnections->currentItem() == -1 ) + return; + project->removeDatabaseConnection( listConnections->currentText() ); + delete listConnections->item( listConnections->currentItem() ); + if ( listConnections->count() ) { + listConnections->setCurrentItem( 0 ); + currentConnectionChanged( listConnections->currentText() ); + } else { + enableAll( FALSE ); + } + project->saveConnections(); +} + +void DatabaseConnectionsEditor::newConnection() +{ + blockChanges = TRUE; + enableAll( TRUE ); + QString n( "(default)" ); + if ( project->databaseConnection( n ) ) { + n = "connection"; + int i = 2; + while ( project->databaseConnection( n + QString::number( i ) ) ) + ++i; + n = n + QString::number( i ); + } + connectionWidget->editName->setText( n ); + listConnections->clearSelection(); + buttonConnect->setDefault( TRUE ); + connectionWidget->editName->setFocus(); + blockChanges = FALSE; +} + +void DatabaseConnectionsEditor::doConnect() +{ +#ifndef QT_NO_SQL + if ( listConnections->currentItem() == -1 || + !listConnections->item( listConnections->currentItem() )->isSelected() ) { // new connection + // ### do error checking for duplicated connection names + DatabaseConnection *conn = new DatabaseConnection( project ); + conn->setName( connectionWidget->editName->text() ); + conn->setDriver( connectionWidget->comboDriver->lineEdit()->text() ); + conn->setDatabase( connectionWidget->editDatabase->text() ); + conn->setUsername( connectionWidget->editUsername->text() ); + conn->setPassword( connectionWidget->editPassword->text() ); + conn->setHostname( connectionWidget->editHostname->text() ); + conn->setPort( connectionWidget->editPort->value() ); + if ( conn->refreshCatalog() ) { + project->addDatabaseConnection( conn ); + listConnections->insertItem( conn->name() ); + listConnections->setCurrentItem( listConnections->count() - 1 ); + project->saveConnections(); + } else { + QMessageBox::warning( MainWindow::self, QApplication::tr( "Connection" ), + QApplication::tr( "Could not connect to the database.\n" + "Please ensure that the database server is running " + "and that all the connection information is correct.\n" + "[ " + conn->lastError() + " ]" ) ); + delete conn; + } + } else { // sync // ### should this do something else? right now it just overwrites all info about the connection... + DatabaseConnection *conn = project->databaseConnection( listConnections->currentText() ); + conn->setName( connectionWidget->editName->text() ); + conn->setDriver( connectionWidget->comboDriver->lineEdit()->text() ); + conn->setDatabase( connectionWidget->editDatabase->text() ); + conn->setUsername( connectionWidget->editUsername->text() ); + conn->setPassword( connectionWidget->editPassword->text() ); + conn->setHostname( connectionWidget->editHostname->text() ); + conn->setPort( connectionWidget->editPort->value() ); + conn->refreshCatalog(); + project->saveConnections(); + } +#endif +} + +void DatabaseConnectionsEditor::currentConnectionChanged( const QString &s ) +{ +#ifndef QT_NO_SQL + DatabaseConnection *conn = project->databaseConnection( s ); + blockChanges = TRUE; + enableAll( conn != 0 ); + connectionWidget->editName->setEnabled( FALSE ); + blockChanges = FALSE; + if ( !conn ) + return; + blockChanges = TRUE; + connectionWidget->editName->setText( conn->name() ); + blockChanges = FALSE; + connectionWidget->comboDriver->lineEdit()->setText( conn->driver() ); + connectionWidget->editDatabase->setText( conn->database() ); + connectionWidget->editUsername->setText( conn->username() ); + connectionWidget->editPassword->setText( conn->password() ); + connectionWidget->editHostname->setText( conn->hostname() ); + connectionWidget->editPort->setValue( conn->port() ); +#endif +} + +void DatabaseConnectionsEditor::connectionNameChanged( const QString &s ) +{ + if ( listConnections->currentItem() == 0 || blockChanges ) + return; + listConnections->changeItem( s, listConnections->currentItem() ); +} + +void DatabaseConnectionsEditor::enableAll( bool b ) +{ + connectionWidget->editName->setEnabled( b ); + connectionWidget->editName->setText( "" ); + connectionWidget->comboDriver->setEnabled( b ); + connectionWidget->comboDriver->lineEdit()->setText( "" ); + connectionWidget->editDatabase->setEnabled( b ); + connectionWidget->editDatabase->setText( "" ); + connectionWidget->editUsername->setEnabled( b ); + connectionWidget->editUsername->setText( "" ); + connectionWidget->editPassword->setEnabled( b ); + connectionWidget->editPassword->setText( "" ); + connectionWidget->editHostname->setEnabled( b ); + connectionWidget->editHostname->setText( "" ); + connectionWidget->editPort->setEnabled( b ); + connectionWidget->editPort->setValue( -1 ); + buttonConnect->setEnabled( b ); +} diff --git a/tools/designer/designer/dbconnectionsimpl.h b/tools/designer/designer/dbconnectionsimpl.h new file mode 100644 index 0000000..d1916fa --- /dev/null +++ b/tools/designer/designer/dbconnectionsimpl.h @@ -0,0 +1,67 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DBCONNECTIONSIMPL_H +#define DBCONNECTIONSIMPL_H + +#include "dbconnections.h" +#include "dbconnection.h" + +class Project; + +class DatabaseConnectionsEditor : public DatabaseConnectionBase +{ + Q_OBJECT + +public: + DatabaseConnectionsEditor( Project *pro, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~DatabaseConnectionsEditor(); + +protected slots: + void deleteConnection(); + void newConnection(); + void doConnect(); + void currentConnectionChanged( const QString & ); + void connectionNameChanged( const QString &s ); + +private: + void enableAll( bool b ); + +private: + Project *project; + DatabaseConnectionWidget* connectionWidget; + +}; + +#endif // DBCONNECTIONSIMPL_H diff --git a/tools/designer/designer/defs.cpp b/tools/designer/designer/defs.cpp new file mode 100644 index 0000000..ebb610e --- /dev/null +++ b/tools/designer/designer/defs.cpp @@ -0,0 +1,91 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "defs.h" + +int size_type_to_int( QSizePolicy::SizeType t ) +{ + if ( t == QSizePolicy::Fixed ) + return 0; + if ( t == QSizePolicy::Minimum ) + return 1; + if ( t == QSizePolicy::Maximum ) + return 2; + if ( t == QSizePolicy::Preferred ) + return 3; + if ( t == QSizePolicy::MinimumExpanding ) + return 4; + if ( t == QSizePolicy::Expanding ) + return 5; + if ( t == QSizePolicy::Ignored ) + return 6; + return 0; +} + +QString size_type_to_string( QSizePolicy::SizeType t ) +{ + if ( t == QSizePolicy::Fixed ) + return "Fixed"; + if ( t == QSizePolicy::Minimum ) + return "Minimum"; + if ( t == QSizePolicy::Maximum ) + return "Maximum"; + if ( t == QSizePolicy::Preferred ) + return "Preferred"; + if ( t == QSizePolicy::MinimumExpanding ) + return "MinimumExpanding"; + if ( t == QSizePolicy::Expanding ) + return "Expanding"; + if ( t == QSizePolicy::Ignored ) + return "Ignored"; + return QString(); +} + +QSizePolicy::SizeType int_to_size_type( int i ) +{ + if ( i == 0 ) + return QSizePolicy::Fixed; + if ( i == 1 ) + return QSizePolicy::Minimum; + if ( i == 2 ) + return QSizePolicy::Maximum; + if ( i == 3 ) + return QSizePolicy::Preferred; + if ( i == 4 ) + return QSizePolicy::MinimumExpanding; + if ( i == 5 ) + return QSizePolicy::Expanding; + if ( i == 6 ) + return QSizePolicy::Ignored; + return QSizePolicy::Preferred; +} diff --git a/tools/designer/designer/defs.h b/tools/designer/designer/defs.h new file mode 100644 index 0000000..a8b5ac5 --- /dev/null +++ b/tools/designer/designer/defs.h @@ -0,0 +1,49 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DEFS_H +#define DEFS_H + +#include +#include + +#define POINTER_TOOL 32000 +#define CONNECT_TOOL 32001 +#define ORDER_TOOL 32002 +#define BUDDY_TOOL 32004 + +int size_type_to_int( QSizePolicy::SizeType t ); +QString size_type_to_string( QSizePolicy::SizeType t ); +QSizePolicy::SizeType int_to_size_type( int i ); + +#endif diff --git a/tools/designer/designer/designer.pro b/tools/designer/designer/designer.pro new file mode 100644 index 0000000..95f58da --- /dev/null +++ b/tools/designer/designer/designer.pro @@ -0,0 +1,443 @@ +TEMPLATE = lib + +CONFIG += qt warn_on staticlib qmake_cache +CONFIG -= dll +!force_static:!win32:contains(QT_PRODUCT,qt-internal) { + CONFIG -= staticlib + CONFIG += dll +} + +TARGET = designercore + +DEFINES += DESIGNER +DEFINES += QT_INTERNAL_XML +DEFINES += QT_INTERNAL_WORKSPACE +DEFINES += QT_INTERNAL_ICONVIEW +DEFINES += QT_INTERNAL_TABLE +table:win32-msvc:DEFINES+=QM_TEMPLATE_EXTERN_TABLE=extern + +unix { + QMAKE_CFLAGS += $$QMAKE_CFLAGS_SHLIB + QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SHLIB +} + +include( ../../../src/qt_professional.pri ) + +SOURCES += command.cpp \ + formwindow.cpp \ + defs.cpp \ + layout.cpp \ + mainwindow.cpp \ + mainwindowactions.cpp \ + metadatabase.cpp \ + pixmapchooser.cpp \ + propertyeditor.cpp \ + resource.cpp \ + sizehandle.cpp \ + orderindicator.cpp \ + widgetfactory.cpp \ + hierarchyview.cpp \ + listboxeditorimpl.cpp \ + newformimpl.cpp \ + workspace.cpp \ + listvieweditorimpl.cpp \ + customwidgeteditorimpl.cpp \ + paletteeditorimpl.cpp \ + styledbutton.cpp \ + iconvieweditorimpl.cpp \ + multilineeditorimpl.cpp \ + formsettingsimpl.cpp \ + asciivalidator.cpp \ + designerapp.cpp \ + designerappiface.cpp \ + actioneditorimpl.cpp \ + actionlistview.cpp \ + actiondnd.cpp \ + project.cpp \ + projectsettingsimpl.cpp \ + sourceeditor.cpp \ + outputwindow.cpp \ + ../shared/widgetdatabase.cpp \ + ../shared/parser.cpp \ + pixmapcollection.cpp \ + previewframe.cpp \ + previewwidgetimpl.cpp \ + paletteeditoradvancedimpl.cpp \ + sourcefile.cpp \ + wizardeditorimpl.cpp \ + qcompletionedit.cpp \ + timestamp.cpp \ + formfile.cpp \ + widgetaction.cpp \ + propertyobject.cpp \ + startdialogimpl.cpp \ + syntaxhighlighter_html.cpp \ + connectionitems.cpp \ + editfunctionsimpl.cpp \ + variabledialogimpl.cpp \ + listviewdnd.cpp \ + listboxdnd.cpp \ + listdnd.cpp \ + listboxrename.cpp \ + connectiontable.cpp \ + popupmenueditor.cpp \ + menubareditor.cpp + +HEADERS += command.h \ + defs.h \ + formwindow.h \ + layout.h \ + mainwindow.h \ + metadatabase.h \ + pixmapchooser.h \ + propertyeditor.h \ + resource.h \ + sizehandle.h \ + orderindicator.h \ + widgetfactory.h \ + hierarchyview.h \ + listboxeditorimpl.h \ + newformimpl.h \ + workspace.h \ + listvieweditorimpl.h \ + customwidgeteditorimpl.h \ + paletteeditorimpl.h \ + styledbutton.h \ + iconvieweditorimpl.h \ + multilineeditorimpl.h \ + formsettingsimpl.h \ + asciivalidator.h \ + ../interfaces/widgetinterface.h \ + ../interfaces/actioninterface.h \ + ../interfaces/filterinterface.h \ + ../interfaces/designerinterface.h \ + designerapp.h \ + designerappiface.h \ + actioneditorimpl.h \ + actionlistview.h \ + actiondnd.h \ + project.h \ + projectsettingsimpl.h \ + sourceeditor.h \ + outputwindow.h \ + ../shared/widgetdatabase.h \ + ../shared/parser.h \ + previewframe.h \ + previewwidgetimpl.h \ + paletteeditoradvancedimpl.h \ + pixmapcollection.h \ + sourcefile.h \ + wizardeditorimpl.h \ + qcompletionedit.h \ + timestamp.h \ + formfile.h \ + widgetaction.h \ + propertyobject.h \ + startdialogimpl.h \ + syntaxhighlighter_html.h \ + connectionitems.h \ + editfunctionsimpl.h \ + variabledialogimpl.h \ + listviewdnd.h \ + listboxdnd.h \ + listdnd.h \ + listboxrename.h \ + connectiontable.h \ + popupmenueditor.h \ + menubareditor.h + +FORMS += listboxeditor.ui \ + editfunctions.ui \ + newform.ui \ + listvieweditor.ui \ + customwidgeteditor.ui \ + paletteeditor.ui \ + iconvieweditor.ui \ + preferences.ui \ + multilineeditor.ui \ + formsettings.ui \ + about.ui \ + pixmapfunction.ui \ + createtemplate.ui \ + actioneditor.ui \ + projectsettings.ui \ + finddialog.ui \ + replacedialog.ui \ + gotolinedialog.ui \ + pixmapcollectioneditor.ui \ + previewwidget.ui \ + paletteeditoradvanced.ui \ + wizardeditor.ui \ + listeditor.ui \ + startdialog.ui \ + richtextfontdialog.ui \ + connectiondialog.ui \ + variabledialog.ui \ + configtoolboxdialog.ui + +IMAGES += images/designer_adjustsize.png \ + images/designer_edithlayoutsplit.png \ + images/designer_left.png \ + images/designer_sizeall.png \ + images/designer_arrow.png \ + images/designer_editlower.png \ + images/designer_line.png \ + images/designer_sizeb.png \ + images/designer_background.png \ + images/designer_editpaste.png \ + images/designer_lineedit.png \ + images/designer_sizef.png \ + images/designer_book.png \ + images/designer_editraise.png \ + images/designer_listbox.png \ + images/designer_sizeh.png \ + images/designer_buttongroup.png \ + images/designer_editslots.png \ + images/designer_listview.png \ + images/designer_sizev.png \ + images/designer_checkbox.png \ + images/designer_editvlayout.png \ + images/designer_multilineedit.png \ + images/designer_slider.png \ + images/designer_combobox.png \ + images/designer_editvlayoutsplit.png \ + images/designer_newform.png \ + images/designer_spacer.png \ + images/designer_connecttool.png \ + images/designer_filenew.png \ + images/designer_no.png \ + images/designer_spinbox.png \ + images/designer_cross.png \ + images/designer_fileopen.png \ + images/designer_ordertool.png \ + images/designer_splash.png \ + images/designer_customwidget.png \ + images/designer_filesave.png \ + images/designer_pixlabel.png \ + images/designer_table.png \ + images/designer_databrowser.png \ + images/designer_form.png \ + images/designer_pointer.png \ + images/designer_tabwidget.png \ + images/designer_datatable.png \ + images/designer_frame.png \ + images/designer_print.png \ + images/designer_textbrowser.png \ + images/designer_dataview.png \ + images/designer_groupbox.png \ + images/designer_progress.png \ + images/designer_textedit.png \ + images/designer_dateedit.png \ + images/designer_hand.png \ + images/designer_project.png \ + images/designer_textview.png \ + images/designer_datetimeedit.png \ + images/designer_help.png \ + images/designer_pushbutton.png \ + images/designer_timeedit.png \ + images/designer_dial.png \ + images/designer_home.png \ + images/designer_qtlogo.png \ + images/designer_toolbutton.png \ + images/designer_toolbox.png \ + images/designer_down.png \ + images/designer_hsplit.png \ + images/designer_radiobutton.png \ + images/designer_undo.png \ + images/designer_editbreaklayout.png \ + images/designer_ibeam.png \ + images/designer_redo.png \ + images/designer_up.png \ + images/designer_resetproperty.png \ + images/designer_editcopy.png \ + images/designer_iconview.png \ + images/designer_resetproperty.png \ + images/designer_uparrow.png \ + images/designer_editcut.png \ + images/designer_image.png \ + images/designer_richtextedit.png \ + images/designer_vsplit.png \ + images/designer_editdelete.png \ + images/designer_label.png \ + images/designer_right.png \ + images/designer_wait.png \ + images/designer_editgrid.png \ + images/designer_layout.png \ + images/designer_scrollbar.png \ + images/designer_widgetstack.png \ + images/designer_edithlayout.png \ + images/designer_lcdnumber.png \ + images/designer_searchfind.png \ + images/designer_folder.png \ + images/designer_setbuddy.png \ + images/designer_textbold.png \ + images/designer_textcenter.png \ + images/designer_texth1.png \ + images/designer_texth2.png \ + images/designer_texth3.png \ + images/designer_textitalic.png \ + images/designer_textjustify.png \ + images/designer_textlarger.png \ + images/designer_textleft.png \ + images/designer_textlinebreak.png \ + images/designer_textparagraph.png \ + images/designer_textright.png \ + images/designer_textsmaller.png \ + images/designer_textteletext.png \ + images/designer_textunderline.png \ + images/designer_wizarddata.png \ + images/designer_wizarddialog.png \ + images/designer_d_adjustsize.png \ + images/designer_d_label.png \ + images/designer_d_book.png \ + images/designer_d_layout.png \ + images/designer_d_buttongroup.png \ + images/designer_d_lcdnumber.png \ + images/designer_d_checkbox.png \ + images/designer_d_left.png \ + images/designer_d_combobox.png \ + images/designer_d_line.png \ + images/designer_d_connecttool.png \ + images/designer_d_lineedit.png \ + images/designer_d_customwidget.png \ + images/designer_d_listbox.png \ + images/designer_d_databrowser.png \ + images/designer_d_listview.png \ + images/designer_d_datatable.png \ + images/designer_d_multilineedit.png \ + images/designer_d_dataview.png \ + images/designer_d_newform.png \ + images/designer_d_dateedit.png \ + images/designer_d_ordertool.png \ + images/designer_d_datetimeedit.png \ + images/designer_d_pixlabel.png \ + images/designer_d_dial.png \ + images/designer_d_pointer.png \ + images/designer_d_down.png \ + images/designer_d_print.png \ + images/designer_d_editbreaklayout.png \ + images/designer_d_progress.png \ + images/designer_d_editcopy.png \ + images/designer_d_project.png \ + images/designer_d_editcut.png \ + images/designer_d_pushbutton.png \ + images/designer_d_editdelete.png \ + images/designer_d_radiobutton.png \ + images/designer_d_editgrid.png \ + images/designer_d_redo.png \ + images/designer_d_edithlayout.png \ + images/designer_d_richtextedit.png \ + images/designer_d_edithlayoutsplit.png \ + images/designer_d_right.png \ + images/designer_d_editlower.png \ + images/designer_d_scrollbar.png \ + images/designer_d_editpaste.png \ + images/designer_d_searchfind.png \ + images/designer_d_editraise.png \ + images/designer_d_slider.png \ + images/designer_d_editslots.png \ + images/designer_d_spacer.png \ + images/designer_d_editvlayout.png \ + images/designer_d_spinbox.png \ + images/designer_d_editvlayoutsplit.png \ + images/designer_d_table.png \ + images/designer_d_filenew.png \ + images/designer_d_folder.png \ + images/designer_d_tabwidget.png \ + images/designer_d_fileopen.png \ + images/designer_d_textbrowser.png \ + images/designer_d_filesave.png \ + images/designer_d_textedit.png \ + images/designer_d_form.png \ + images/designer_d_textview.png \ + images/designer_d_frame.png \ + images/designer_d_timeedit.png \ + images/designer_d_groupbox.png \ + images/designer_d_toolbutton.png \ + images/designer_d_toolbox.png \ + images/designer_d_help.png \ + images/designer_d_undo.png \ + images/designer_d_home.png \ + images/designer_d_up.png \ + images/designer_d_iconview.png \ + images/designer_d_widgetstack.png \ + images/designer_d_setbuddy.png \ + images/designer_d_textbold.png \ + images/designer_d_texth1.png \ + images/designer_d_texth2.png \ + images/designer_d_texth3.png \ + images/designer_d_textitalic.png \ + images/designer_d_textjustify.png \ + images/designer_d_textlarger.png \ + images/designer_d_textleft.png \ + images/designer_d_textlinebreak.png \ + images/designer_d_textparagraph.png \ + images/designer_d_textright.png \ + images/designer_d_textsmaller.png \ + images/designer_d_textteletext.png \ + images/designer_d_textunderline.png \ + images/designer_d_textcenter.png \ + images/designer_d_wizarddata.png \ + images/designer_d_wizarddialog.png \ + images/designer_s_editcut.png \ + images/designer_s_up.png \ + images/designer_s_down.png \ + images/designer_s_left.png \ + images/designer_s_right.png \ + images/designer_d_image.png \ + images/designer_d_textfont.png \ + images/designer_textfont.png \ + images/designer_object.png \ + images/designer_appicon.png \ + images/designer_wordwrap.png \ + images/designer_d_wordwrap.png + + +OBJECTS_DIR = . + +DEPENDPATH += $$QT_SOURCE_TREE/include +VERSION = 1.0.0 +DESTDIR = $$QT_BUILD_TREE/lib + +aix-g++ { + QMAKE_CFLAGS += -mminimal-toc + QMAKE_CXXFLAGS += -mminimal-toc +} + +sql { + SOURCES += database.cpp dbconnectionimpl.cpp dbconnectionsimpl.cpp + HEADERS += database.h dbconnectionimpl.h dbconnectionsimpl.h + FORMS += dbconnections.ui dbconnection.ui dbconnectioneditor.ui +} + +table { + HEADERS += tableeditorimpl.h + SOURCES += tableeditorimpl.cpp + FORMS += tableeditor.ui +} + +INCLUDEPATH += ../shared ../uilib +LIBS += -L$$QT_BUILD_TREE/lib -lqui + +hpux-acc* { + LIBS += $$QT_BUILD_TREE/lib/libqassistantclient.a +} + +!hpux-acc* { + LIBS += -lqassistantclient +} + +TRANSLATIONS = designer_de.ts designer_fr.ts + +target.path=$$libs.path +INSTALLS += target + +templates.path=$$data.path/templates +templates.files = ../templates/* +INSTALLS += templates + +designertranlations.files = *.qm +designertranlations.path = $$translations.path +INSTALLS += designertranlations + +!macx-g++:PRECOMPILED_HEADER = designer_pch.h diff --git a/tools/designer/designer/designer_de.ts b/tools/designer/designer/designer_de.ts new file mode 100644 index 0000000..64f3cf3 --- /dev/null +++ b/tools/designer/designer/designer_de.ts @@ -0,0 +1,4969 @@ + + + AboutDialog + + Qt Designer + + + + Version 2.0 + + + + Copyright (C) 2000-2008 Trolltech AS + + + + <p>This program is licensed to you under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation. This gives you legal permission to copy, distribute and/or modify this software under certain conditions. For details, see the file 'COPYING' that came with this software distribution. If you did not get the file, send email to info@trolltech.com.</p> +<p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> + + + + &OK + + + + + ActionEditor + + Actions + + + + New &Action + + + + New Action &Group + + + + New &Dropdown Action Group + + + + + ActionEditorBase + + Edit Actions + + + + Create new Action + + + + Delete current Action + + + + Connect current action + + + + + ActionListView + + New &Action + + + + New Action &Group + + + + New &Dropdown Action Group + + + + &Connect Action... + + + + Delete Action + + + + + ConnectionEditor + + Signals (%1): + + + + Connect/Disconnect signals and slots of '%1' and '%2' + + + + Remove connection + + + + Remove connections + + + + Add connection + + + + Add connections + + + + + ConnectionEditorBase + + Edit Connections + + + + <b>Edit Connections</b><p>Add and remove connections in the current form .</p><p>Select a signal and a corresponding slot and press the <b>Connect</b>-button to create a connection.</p><p>Select a connection from the list and press the <b>Disconnect</b>-button to delete the connection.</p> + + + + Sender + + + + Signal + + + + Receiver + + + + Slot + + + + Displays the connections between the sender and the receiver. + + + + Si&gnals: + + + + <b>A list of slots for the receiver.</b><p>Only those slots are displayed that have arguments corresponding with the signal selected in the Signal-list.</b> + + + + Connec&tions: + + + + Co&nnect + + + + Create connection + + + + Create the connection between signal and slot. + + + + &Disconnect + + + + Remove selected connection + + + + Remove the selected connection. + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + &Edit Slots + + + + Displays a list of signals for the emitting widget. + + + + &Slots: + + + + + ConnectionViewer + + Remove connection between %1 and %2 + + + + + ConnectionViewerBase + + View Connections + + + + <b>View Connections</b><p>Displays all connections in the current form Select a connection from the list and click the <b>Edit</b>-button to change the connection.</p> + + + + &Help + + + + &Close + + + + Close the Dialog. + + + + Sender + + + + Signal + + + + Receiver + + + + Slot + + + + <b>Displays a list of connections.</b><p>Select a connection and choose edit, or double-click on an item to change the connection.</p> + + + + &Edit... + + + + Edit connection + + + + Opens a dialog to change the selected connection. + + + + &Disconnect + + + + + CreateTemplate + + Create Template + + + + Template &Name: + + + + Name of the new template + + + + Enter the name of the new template here + + + + Class of the new template + + + + Choose the class which should be used as baseclass for the new template here + + + + C&reate + + + + Creates the new template + + + + &Cancel + + + + Closes the Dialog + + + + &Baseclass for Template: + + + + + CustomWidgetEditor + + Adding a Custom Widget + + + + There exists already a custom widget with the name '%1', +so it is not possible to add another one with this name. + + + + Removing Custom Widget + + + + The custom widget '%1' is currently used, so it can't be removed. + + + + Header Files (*.h *.h++ *.hxx *.hh) + + + + Renaming a Custom Widget + + + + The name '%1' is already use by another custom widget, +so it is not possible to rename it to this name. + + + + protected + + + + Custom-Widget Description (*.cw);;All Files (*) + + + + + CustomWidgetEditorBase + + Edit Custom Widgets + + + + <b>Edit Custom Widgets</b><p>Add and remove custom widgets to the designer's database, and change the properties of existing widgets.</p> + + + + The list of all custom widgets known to the designer. + + + + &New Widget + + + + Add new custom widget. + + + + <b>Create an empty custom widget and add it to the list.</b><p>New custom widgets have a default name and header-file, which must both be provided.</p> + + + + &Delete Widget + + + + Delete custom widget + + + + <b>Delete the selected custom widget.</b><p>You can only delete widgets that are not used in any open form.</p> + + + + &Help + + + + &Close + + + + Closes the Dialog. + + + + &Load Descriptions... + + + + Loads widget description file + + + + <b>Load Descriptions</b><p>Loads a file which contains descriptions of custom widgets, so that these custom widgets can be used in the Qt Designer.</p> +<p>As it is a lot of work to type in all the information for custom widgets, you should check the tool createcw which you can find in $QTDIR/tools/designer/tools/createcw. Using that tool you can create custom widget description files for your custom widgets without the need of typing in all that information. For more information about that see the README file in that directory</p> + + + + &Save Descriptions... + + + + Saves widget description file + + + + <b>Save Descriptions</b><p>Saves all descriptions of the shown custom widgets to file which can be used to import these custom widgets somewhere else. + + + + Change properties for the selected custom widget. + + + + De&finition + + + + ... + + + + Select a Pixmap + + + + <b>Select a pixmap-file.</b><p>The pixmap will be used to represent the widget in forms.</b> + + + + Enter filename + + + + <b>Change the headerfile's name for the selected custom widget.</b><p>The headerfile will be included by forms using the widget.</p> + + + + Choose headerfile + + + + Look for the headerfile in a filedialog. + + + + Global + + + + Local + + + + Select access + + + + <b>Change how the include file will be included.</b><p>Global include-files will be included using &lt;&gt;-brackets, while local files will included using quotation marks.</p> + + + + Change classname + + + + <b>Enter the classname for the selected customwidget.</b><p>A class of that name has to be defined in the headerfile.</p> + + + + Heade&rfile: + + + + Cl&ass: + + + + Pixmap: + + + + Si&ze Hint: + + + + Size P&olicy + + + + Fixed + + + + Minimum + + + + Maximum + + + + Preferred + + + + MinimumExpanding + + + + Expanding + + + + Horizontal Sizepolicy + + + + Choose the horizontal sizepolicy here + + + + Size hint width + + + + <b>Set the sizehint for the selected widget.</b><p>The sizehint provides the recommended size for the widget. Enter a sizehint of -1/-1 if no size is recommended.</p> + + + + Size hint height + + + + Vertical Sizepolicy + + + + Choose the verical sizepolicy for the widget here + + + + Con&tainer Widget + + + + Container Widget + + + + <p><b>Container Widget</b></p> +<p>If this customwidget should be able to contain other widgets (children), check this checkbox.</p> + + + + Si&gnals + + + + The list of all signals the selected widget can emit. + + + + N&ew Signal + + + + Add new signal + + + + <b>Add a new signal for the current custom widget.</b><p>An argument list should be provided in the signal's name, and the name has to be unique.</p> + + + + Dele&te Signal + + + + Delete signal + + + + <b>Delete the signal.</b><p>All connections using this signal will be deleted, too.</p> + + + + S&ignal: + + + + Change signal name + + + + <b>Change the name of the selected slot.</b><p>An argument list should be provided in the signal's name, and the name has to be unique.</p> + + + + S&lots + + + + Slot + + + + Access + + + + The list of all slots of the selected custom widget. + + + + Sl&ot: + + + + Change slot name + + + + &Access: + + + + public + + + + protected + + + + Change slot access + + + + <b>Change the access policy of the slot.</b><p>You can only connect to public slots of the widget.</p> + + + + N&ew Slot + + + + Add new slot + + + + <b>Add a new slot to the current custom widget.</b><p>An argument list should be provided in the signal's name, and the name has to be unique.</p> + + + + Dele&te Slot + + + + Delete slot + + + + <b>Delete the slot.</b><p>All connections using this slot will be deleted, too.</p> + + + + &Properties + + + + N&ew Property + + + + Add new property + + + + <b>Add a new property to the current customwidget.</b><p>The properties have to be implemented in the class using the property system of Qt.</p> + + + + Dele&te Property + + + + Delete property + + + + Deletes the selected property. + + + + String + + + + CString + + + + StringList + + + + Bool + + + + Int + + + + UInt + + + + Font + + + + Color + + + + Rect + + + + Point + + + + Size + + + + Pixmap + + + + Palette + + + + Cursor + + + + SizePolicy + + + + Select property type + + + + <b>Select the type of the property.</b><p>The propertiy has to be implemented in the class using the property system of Qt.</p><p>You can use integer types to support enumeration properties in the property editor.</p> + + + + Property + + + + Type + + + + <b>The list of properties of the current custom widget.</b><p>The properties of the custom widget can be changed in the property editor.</p> + + + + Change property name + + + + <b>Enter a name for the property.</b><p>The properties have to be implemented in the class using the property system of Qt.</p> + + + + P&roperty Name: + + + + T&ype: + + + + + DatabaseConnectionBase + + Edit Database Connections + + + + &New Connection + + + + &Delete Connection + + + + &Help + + + + &Close + + + + Close dialog and discard all changes. + + + + Conn&ection + + + + Connec&t + + + + + DatabaseConnectionEditorBase + + Connect + + + + &Cancel + + + + &OK + + + + Connection Details + + + + + DatabaseConnectionWidget + + Edit Database Connection + + + + &Database Name: + + + + &Username: + + + + &Password: + + + + D&river + + + + &Hostname: + + + + &Name: + + + + P&ort + + + + Default + + + + + EditSlots + + Yes + + + + No + + + + Add/Remove slots of '%1' + + + + Remove slot + + + + Remove slots + + + + Add slot + + + + Add slots + + + + Edit Slots + + + + Some syntatically wrong slots defined. +Remove these slots? + + + + &Yes + + + + &No + + + + + EditSlotsBase + + Edit Slots + + + + <b>Edit Slots</b><p>Add, change and remove slots of the current form.</p><p>Press the <b>Add Slot</b>-button to create a new slot, enter a slot name and choose an access mode.</p><p>Select an entry from the list and press the <b>Delete Slot</b>-button to remove a slot. All connections using this slot will be removed, too.</p> + + + + Slot + + + + Type + + + + Specifier + + + + Access + + + + In Use + + + + <b>This form's slots.</b><p>Select the slot you want to change or delete.</p> + + + + &New Slot + + + + Add new slot + + + + <b>Add a new slot.</b><p>New slots have a default name and public access.</p> + + + + &Delete Slot + + + + Delete slot + + + + <b>Delete the selected slot.</b><p>All connections using this slot are removed, too.</p> + + + + Slot Properties + + + + &Slot: + + + + Change slot name + + + + <b>Change the name of the selected slot.</b><p>The name should include the argument list and has to be syntactically correct.</p> + + + + &Return type: + + + + S&pecifier: + + + + non virtual + + + + virtual + + + + pure virtual + + + + Change slot access + + + + <b>Change the access policy of the slot</b><p>All slots will be created virtual and should be reimplemented in subclasses.</p> + + + + &Access: + + + + public + + + + protected + + + + private + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + EventList + + New Signal Handler + + + + Delete Signal Handler + + + + Remove connection + + + + Add connection + + + + + FindDialog + + Find Text + + + + &Find: + + + + &Find + + + + Close + + + + &Direction + + + + Forwar&d + + + + &Backward + + + + &Options + + + + &Whole words only + + + + &Case sensitive + + + + Start at &Beginning + + + + + FormDefinitionView + + Slots + + + + private + + + + protected + + + + public + + + + Edit... + + + + New + + + + Properties... + + + + Goto Implementation + + + + Delete + + + + Edit...Alt+V + + + + Edit %1 + + + + Edit Class Variables + + + + + FormFile + + Failed to save file %1. + + + + %1 saved. + + + + Qt User-Interface Files (*.ui) + + + + All Files (*) + + + + Save form '%1' as .... + + + + Edit %1 + + + + Save Form + + + + Save changes to the form '%1'? + + + + &Yes + + + + &No + + + + &Cancel + + + + Qt Designer + + + + The file %1 has been changed outside Qt Designer. +Do you want to reload it? + + + + Invalid Filename + + + + The project contains already a form with the +filename '%1'. Please choose a new filename. + + + + + FormSettingsBase + + Form Settings + + + + <b>Form Settings</b><p>Change settings for the form. Settings like <b>Comment</b> and <b>Author</b> are for personal use and not required.</p> + + + + &Pixmaps + + + + Save In&line + + + + Save pixmaps into the .ui files + + + + <b>Save Inline</b><p>Saves the pixmaps you choose as binary data into the .ui files. Pixmaps are not shared between forms. We recommend using Project Imagefiles instead. + + + + Project &Imagefile + + + + Use the Project's Image file to load pixmaps + + + + <b>Use the Project's Image file to open pixmaps</b> +<p>Each project has a collection of pixmaps. If you use a project, we recommend that you use this option since it shares images and is the fastest and most efficient way to use pixmaps in your forms.</p> + + + + Specify Pixmap-Loader function (only function-name, no parentheses!) + + + + <b>Specify Pixmap-Loader function</b><p>Specify the function which should be used for loading a pixmap in the generated code. <em>Only enter the function-name, no parentheses!</em> + + + + Use &Function: + + + + Use a defined function to load pixmaps + + + + <b>Use a defined function to open pixmaps</b><p>If you choose this option you must define a function in the line edit at the right which will be used in the generated code for loading pixmaps. When choosing a pixmap in <i>Qt Designer</i> you will be asked to specify the arguments which will be passed to the function in the generated code.<p> This approach makes it possible to use your own icon-loader function for loading pixmaps. <i>Qt Designer</i> can't preview the correct image if you use your own function. + + + + &Settings + + + + Change class name + + + + <b>Enter the name of the class that will be created.</b><p><em>classname.h</em> and <em>classname.cpp</em> will be generated as C++-output when it is compiled with the uic.</p> + + + + A&uthor: + + + + Enter your name + + + + Enter your name here. + + + + Class &Name: + + + + Co&mment: + + + + Enter a comment about the form. + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + La&youts + + + + Default Mar&gin: + + + + D&efault Spacing: + + + + + FormWindow + + Set 'name' property + + + + The name of a widget has to be unique! +'%1' is already used in the form '%2', +so the name has been changed back to '%3'. + + + + The name of a widget must not be null! +The name has been changed back to '%1'. + + + + &Horizontal + + + + &Vertical + + + + <b>A %1 (custom widget)</b> <p>Select <b>Edit Custom Widgets...</b> in the <b>Tools->Custom</b> menu to add and change the custom widgets. You can add properties as well as signals and slots to integrate them into the designer, and provide a pixmap which will be used to represent the widget on the form.</p> + + + + A %1 (custom widget) + + + + Reparent Widgets + + + + Insert %1 + + + + Connect '%1' with... + + + + Change Tab Order + + + + %1/%2 + + + + Connect '%1' with '%2' + + + + Inserting a Widget + + + + You tried to insert a widget into the laid out Container Widget '%1'. +This is not possible. In order to insert the widget, the layout of '%1' +has to be broken. Break the layout or cancel the operation? + + + + &Break Layout + + + + &Cancel + + + + Move + + + + Use Size Hint + + + + Delete + + + + Adjust Size + + + + Click widgets to change tab order... + + + + Drag a line to create a connection... + + + + Click on the form to insert a %1... + + + + Following custom widgets are used in '%1', +but they are not known to the designer: + + + + Save Form + + + + Lower + + + + Check Accelerators + + + + The accelerator '%1' is used %2 times. + + + + &Select + + + + No accelerator is used more than once! + + + + Raise + + + + Layout horizontally + + + + Layout vertically + + + + Layout horizontally (in splitter) + + + + Layout vertically (in splitter) + + + + Layout in a grid + + + + Layout children horizontally + + + + Layout children vertically + + + + Layout children in a grid + + + + Break Layout + + + + Edit connections... + + + + Paste + + + + Page + + + + + GotoLineDialog + + Goto Line + + + + &Line: + + + + &Goto + + + + &Close + + + + + HierarchyList + + Name + + + + Class + + + + Database + + + + Add Page to %1 + + + + Remove Page %1 of %2 + + + + + HierarchyView + + Widgets + + + + Source + + + + Classes + + + + + IconViewEditor + + New Item + + + + Edit Items of '%1' + + + + + IconViewEditorBase + + Edit Iconview + + + + <b>Edit Iconview</b><p>Add, change and remove items in the icon view.</p><p>Press the <b>New Item</b>-button to create a new entry, and enter a text or choose a pixmap.</p><p>Select an item from the view and press the <b>Delete Item</b>-button to remove the item from the view.</p> + + + + All items in the view. + + + + &New Item + + + + Add an item + + + + Create a new item for the view. + + + + &Delete Item + + + + Delete item + + + + Delete the selected item. + + + + &Item Properties + + + + &Text: + + + + Change text + + + + Change the text for the selected item. + + + + &Pixmap: + + + + Label4 + + + + Delete Pixmap + + + + Delete the pixmap of the selected item. + + + + ... + + + + Select a Pixmap + + + + Select a pixmap-file for the current item. + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + ListBoxEditor + + New Item + + + + Edit Items of '%1' + + + + + ListBoxEditorBase + + Edit Listbox + + + + <b>Edit Listbox</b><p>Add, change and remove items in the listbox.</p><p>Press the <b>New Item</b>-button to create a new listbox entry, and enter text or choose a pixmap.</p><p>Select an item from the list and press the <b>Delete Item</b>-button to remove the item from the list.</p> + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + Delete Item + + + + The list of items. + + + + &Item Properties + + + + &Pixmap: + + + + Label4 + + + + Delete Pixmap + + + + Delete the pixmap of the selected item. + + + + ... + + + + Select a Pixmap + + + + Choose a pixmap-file for the selected item. + + + + &Text: + + + + Change text + + + + Change the text of the selected item. + + + + &New Item + + + + Add an item + + + + <b>Add a new item.</b><p>New items are appended to the list.</p> + + + + &Delete Item + + + + Delete the selected item + + + + Move up + + + + Moves the selected item up. + + + + Move down + + + + Move the selected item down. + + + + + ListEditor + + Edit... + + + + Column 1 + + + + &Add + + + + &Remove + + + + Re&name + + + + &Close + + + + + ListViewEditor + + Edit Items and Columns of '%1' + + + + New Column + + + + &Items + + + + + ListViewEditorBase + + Edit Listview + + + + <b>Edit Listview</b><p>Use the controls on the <b>Items</b>-tab to add, change and remove items in the listview. Change the column configuration of the view using the controls on the <b>Columns</b>-tab.</p>Press the <b>New Item</b>-button to create a new item and enter a text or provide a pixmap.</p><p>Select an item from the list and press the <b>Delete Item</b>-button to remove the item from the list.</p> + + + + &Items + + + + &Delete Item + + + + Delete item + + + + <b>Deletes the selected item.</b><p>Existing subitems are deleted, too.</p> + + + + Item &Properties + + + + Pi&xmap: + + + + &Text: + + + + Change text + + + + <b>Change the text of the item.</b><p>The text will be changed in the current column of the selected item.</p> + + + + Change column + + + + <b>Select the current column.</b><p>Itemtext and pixmap will be changed for the current column</p> + + + + Colu&mn: + + + + Label4 + + + + Delete Pixmap + + + + <b>Delete the pixmap of the selected item.</b><p>The pixmap in the current column of the selected item will be deleted.</p> + + + + ... + + + + Select a Pixmap + + + + <b>Select a pixmap-file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p> + + + + &New Item + + + + Add an item + + + + <b>Adds a new item to the list.</b><p>The item will be inserted at the top of the list and can be moved using the up- and down-buttons.</p> + + + + The list of items. + + + + New &Subitem + + + + Add a subitem + + + + <b>Create a new subitem for the selected item.</b><p>New subitems are inserted at the top of the list of subitems, and new levels will be created automatically.</p> + + + + Move up + + + + <b>Move the selected item up.</b><p>The item will be moved within the hierarchy level.</p> + + + + Move down + + + + <b>Move the selected item down.</b><p>The item will be moved within the hierarchy level.</p> + + + + Move left + + + + <b>Move the selected item one level up.</b><p>This will also change the level of the parent item.</p> + + + + Move right + + + + <b>Move the selected item one level down.</b><p>This will also change the level of the parent item.</p> + + + + Co&lumns + + + + Column Properties + + + + &Pixmap: + + + + Delete the pixmap of the selected column. + + + + <b>Select a pixmap-file for the selected column.</b><p>The pixmap will be displayed in the header of the listview.</p> + + + + Enter column text + + + + <b>Enter the text for the selected column.</b><p>The text will be displayed in the header of the listview.</p> + + + + Clicka&ble + + + + If this option is checked, the selected column will react on mouseclicks on the header. + + + + Re&sizable + + + + The column's width will be resizeable if this option is checked. + + + + &Delete Column + + + + Delete column + + + + Deletes the selected Column. + + + + <b>Move the selected item down.</b><p>The topmost column will be the first column of the list.</p> + + + + &New Column + + + + Add a Column + + + + <b>Create a new column.</b><p>New columns are appended to the list and may be moved using the up- and down-buttons.</p> + + + + <b>Move the selected item up.</b><p>The topmost column will be the first column of the list.</p> + + + + The list of columns. + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + MainWindow + + Qt User-Interface Files (*.ui) + + + + Ready - This is the non-commercial version of Qt - For commercial evaluation purposes, use the help menu to register with Trolltech. + + + + Layout + + + + Property Editor/Signal Handlers + + + + <b>The Property Editor</b><p>You can change the appearance and behaviour of the selected widget in the property editor.</p><p>You can set properties for components and forms at design time and see the changes immediately. Each property has its own editor which you can use to enter new values, open a special dialog or select values from a predefined list. Use <b>F1</b> to get detailed help for the selected property.</p><p>You can resize the columns of the editor by dragging the separators of the list header.</p><p><b>Signal Handlers</b></p><p>In the Signal Handlers tab you can define connections between signals of widgets and slots of the form. That is just a convenience way, you can use the connection tool to do that as well. + + + + Output Window + + + + Object Explorer + + + + <b>The Object Explorer</b><p>The object explorer gives a quick overview about the relations between the widgets in your form. You can use the clipboard functions using a context menu for each item in the view.</p><p>The columns can be resized by dragging the separator in the list header.</p><p>On the second tab you can see all the declared slots, variables, includes, etc. of the form.</p> + + + + Start typing the buffer you want to switch to here (ALT+B) + + + + File Overview + + + + <b>The File Overview box</b><p>The File Overview Box displays all files of all projects, including forms and source files.</p><p>Its search field allows rapid switching between files.</p> + + + + Action Editor + + + + <b>The Action Editor</b><p>Todo Whatsthis</p> + + + + Error + + + + Couldn't find the Qt documentation property index file! +Define the correct documentation path in the preferences dialog. + + + + <b>The Form Window</b><p>Use the different tools to add widgets or to change the layout and behaviour of the components in your form. Select one or multiple widgets and move them, or resize a single widget using the handles.</p><p>Changes in the <b>Property Editor</b> can be seen at design time, and you can open a preview of your form in different styles.</p><p>You can change the grid resolution, or turn the grid off in the <b>Preferences</b> dialog in the <b>Edit</b> menu.<p>You can have several forms open, and all open forms are listed in the <b>Form List</b>. + + + + New Project + + + + Cannot create invalid project. + + + + &Undo + + + + &Redo + + + + &Undo: %1 + + + + &Undo: Not Available + + + + &Redo: %1 + + + + &Redo: Not Available + + + + Choose Pixmap... + + + + Edit Text... + + + + Edit Title... + + + + Edit Page Title... + + + + Remove Page + + + + Add Page + + + + Edit... + + + + Edit Pages... + + + + Add Menu Item + + + + Add Toolbar + + + + Text + + + + New text + + + + Set 'text' of '%2' + + + + Title + + + + New title + + + + Set 'title' of '%2' + + + + Page Title + + + + New page title + + + + Set 'pageTitle' of '%2' + + + + Set 'pixmap' of '%2' + + + + Add Page to %1 + + + + Remove Page %1 of %2 + + + + Rename page %1 of %2 + + + + Add Toolbar to '%1' + + + + Add Menu to '%1' + + + + Save Project Settings + + + + Save changes to '%1'? + + + + &Yes + + + + &No + + + + &Cancel + + + + Edit %1... + + + + Restoring last session + + + + The Qt Designer found some temporary saved files, which have been +written when the Qt Designer crashed last time. Do you want to +load these files? + + + + Help + + + + There is no help available for this dialog at the moment. + + + + Open File + + + + Could not open '%1'. File does not exist. + + + + Open Project + + + + Undo + + + + Reverses the last action + + + + Redo + + + + Redoes the last undone operation + + + + Cut + + + + Cu&t + + + + Cuts the selected widgets and puts them on the clipboard + + + + Copy + + + + &Copy + + + + Copies the selected widgets to the clipboard + + + + Paste + + + + &Paste + + + + Pastes clipboard contents + + + + Delete + + + + &Delete + + + + Deletes the selected widgets + + + + Select All + + + + Select &All + + + + Selects all widgets + + + + Bring to Front + + + + Bring to &Front + + + + Raises the selected widgets + + + + Send to Back + + + + Send to &Back + + + + Lowers the selected widgets + + + + Check Accelerators + + + + Chec&k Accelerators + + + + Checks if the accelerators used in the form are unique + + + + Slots + + + + S&lots... + + + + Opens a dialog to edit slots + + + + Connections + + + + Co&nnections... + + + + Opens a dialog to edit connections + + + + Source + + + + &Source... + + + + Opens an editor to edit the source of the form + + + + Form Settings + + + + &Form Settings... + + + + Opens a dialog to change the settings of the form + + + + Preferences + + + + Preferences... + + + + Opens a dialog to change preferences + + + + <b>The Edit toolbar</b>%1 + + + + Edit + + + + &Edit + + + + Find + + + + &Find... + + + + Find Incremental + + + + Find &Incremental + + + + Replace + + + + &Replace... + + + + Goto Line + + + + &Goto Line... + + + + Search + + + + Incremetal Search (ALT+I) + + + + &Search + + + + Adjust Size + + + + Adjust &Size + + + + Adjusts the size of the selected widget + + + + Lay Out Horizontally + + + + Lay Out &Horizontally + + + + Lays out the selected widgets horizontally + + + + Lay Out Vertically + + + + Lay Out &Vertically + + + + Lays out the selected widgets vertically + + + + Lay Out in a Grid + + + + Lay Out in a &Grid + + + + Lays out the selected widgets in a grid + + + + Lay Out Horizontally (in Splitter) + + + + Lay Out Horizontally (in S&plitter) + + + + Lays out the selected widgets horizontally in a splitter + + + + Lay Out Vertically (in Splitter) + + + + Lay Out Vertically (in Sp&litter) + + + + Lays out the selected widgets vertically in a splitter + + + + Break Layout + + + + &Break Layout + + + + Breaks the selected layout + + + + Add + + + + Insert a %1 + + + + <b>The Layout toolbar</b>%1 + + + + &Layout + + + + Pointer + + + + &Pointer + + + + Selects the pointer tool + + + + Connect Signal/Slots + + + + &Connect Signal/Slots + + + + Selects the connection tool + + + + Tab Order + + + + Tab &Order + + + + Selects the tab order tool + + + + <b>The Tools toolbar</b>%1 + + + + Tools + + + + &Tools + + + + Custom Widgets + + + + Edit &Custom Widgets... + + + + Opens a dialog to change the custom widgets + + + + <b>The %1</b>%2 + + + + Click on a button to insert a single widget, or double click to insert multiple %1. + + + + <b>The %1 Widgets</b>%2 + + + + Click on a button to insert a single %1 widget, or double click to insert multiple widgets. + + + + <p>Double click on this tool to keep it selected.</p> + + + + <b>The Custom Widgets toolbar</b>%1<p>Select <b>Edit Custom Widgets...</b> in the <b>Tools->Custom</b> menu to add and change custom widgets</p> + + + + Click on the buttons to insert a single widget, or double click to insert multiple widgets. + + + + <b>The File toolbar</b>%1 + + + + File + + + + &File + + + + New + + + + &New... + + + + Creates a new project, form or source file. + + + + Open + + + + &Open... + + + + Opens an existing project, form for source file + + + + Close + + + + &Close + + + + Closes the current project or document + + + + Save + + + + &Save + + + + Saves the current project or document + + + + Save As + + + + Save &As... + + + + Saves the current form with a new filename + + + + Save All + + + + Sa&ve All + + + + Saves all open documents + + + + Create Template + + + + Create &Template... + + + + Creates a new template + + + + Recently opened files + + + + Recently opened projects + + + + Exit + + + + E&xit + + + + Quits the application and prompts to save changed forms, source files and project settings + + + + Pr&oject + + + + Active Project + + + + <No Project> + + + + Add File + + + + &Add File... + + + + Adds a file to the current project + + + + Image Collection... + + + + &Image Collection... + + + + Opens a dialog to edit the image collection of the current project + + + + Database Connections... + + + + &Database Connections... + + + + Opens a dialog to edit the database connections of the current project + + + + Project Settings... + + + + &Project Settings... + + + + Opens a dialog to change the settings of the project + + + + &Preview + + + + Preview Form + + + + Preview &Form + + + + Opens a preview + + + + The preview will use the Motif Look&Feel used as the default style on most UNIX-Systems. + + + + The preview will use the Windows Look&Feel used as the default style on Windows-Systems. + + + + The preview will use the Platinum Look&Feel resembling a Macinosh-like GUI style. + + + + The preview will use the CDE Look&Feel which is similar to some versions of the Common Desktop Environment. + + + + The preview will use the Motif Look&Feel used as the default style on SGI-systems. + + + + The preview will use an advanced Motif Look&Feel as used by the GIMP toolkit (GTK) on Linux. + + + + Preview Form in %1 Style + + + + ... in %1 Style + + + + Opens a preview in %1 style + + + + <b>Open a preview in %1 style.</b><p>Use the preview to test the design and signal-slot connections of the current form. %2</p> + + + + Tile + + + + &Tile + + + + Arranges all windows tiled + + + + Cascade + + + + &Cascade + + + + Arrange all windows cascaded + + + + Cl&ose + + + + Closes the active window + + + + Close All + + + + Close Al&l + + + + Closes all form windows + + + + Next + + + + Ne&xt + + + + Activates the next window + + + + Previous + + + + Pre&vious + + + + Activates the previous window + + + + &Window + + + + Vie&ws + + + + Tool&bars + + + + Contents + + + + &Contents + + + + Opens the online help + + + + Manual + + + + &Manual + + + + Opens the Qt Designer manual + + + + About + + + + &About + + + + Displays information about this product + + + + About Qt + + + + About &Qt + + + + Displays information about the Qt Toolkit + + + + Register Qt + + + + &Register Qt... + + + + Launches web browser with evaluation form at www.trolltech.com + + + + Register with Trolltech + + + + What's This? + + + + "What's This?" context sensitive help + + + + <b>The Help toolbar</b>%1 + + + + &Help + + + + Select new item ... + + + + Select a file... + + + + Designer Files (*.ui *.pro) + + + + QMAKE Project Files (*.pro) + + + + All Files (*) + + + + Add + + + + No import filter available for %1 + + + + Importing %1 using import filter ... + + + + Nothing to load in %1 + + + + Reading file %1... + + + + File %1 opened. + + + + Failed to load file %1 + + + + Load File + + + + Couldn't load file %1 + + + + Project '%1' saved. + + + + Enter a filename... + + + + Qt Designer is crashing - attempting to save work... + + + + NewTemplate + + + + Couldn't create the template + + + + Edit slots of current form... + + + + Edit connections in current form... + + + + Edit Source + + + + Edit settings of current form... + + + + Edit preferences... + + + + Edit custom widgets... + + + + New Item + + + + Column 1 + + + + Tab 1 + + + + Tab 2 + + + + Load Template + + + + + MultiLineEditor + + Set text of '%1' + + + + + MultiLineEditorBase + + Edit Multiline Edit + + + + <b>Edit Multiline Edit</b><p>Enter the text and press the <b>OK</b>-Button to apply the changes.</p> + + + + &Text: + + + + Enter your text here. + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + NewForm + + Project + + + + Dialog + + + + Wizard + + + + Widget + + + + Main Window + + + + + NewFormBase + + New File + + + + <b>New Form</b><p>Select a template for the new form and click the <b>OK</b>-button to open it.</p> + + + + &Help + + + + &OK + + + + Open a new form using the selected template. + + + + &Cancel + + + + Close dialog and do not open a form. + + + + Displays a list of available templates. + + + + &Insert into: + + + + + OutputWindow + + Error Messages + + + + Message + + + + Line + + + + + PaletteEditorAdvancedBase + + Tune Palette + + + + <b>Edit Palette</b><p>Change the palette of the current widget or form.</p><p>Use a generated palette or select colors for each color group and each color role.</p><p>The palette can be tested with different widget layouts in the preview section.</p> + + + + Select &Palette: + + + + Active Palette + + + + Inactive Palette + + + + Disabled Palette + + + + Auto + + + + Build inactive palette from active. + + + + Build disabled palette from active. + + + + Central color &roles + + + + Background + + + + Foreground + + + + Button + + + + Base + + + + Text + + + + BrightText + + + + ButtonText + + + + Highlight + + + + HighlightText + + + + Link + + + + LinkVisited + + + + Choose central color role + + + + <b>Select a color role.</b><p>Available central roles are: <ul> <li>Background - general background color.</li> <li>Foreground - general foreground color. </li> <li>Base - used as background color for e.g. text entry widgets, usually white or another light color. </li> <li>Text - the forground color used with Base. Usually this is the same as the Foreground, in what case it must provide good contrast both with Background and Base. </li> <li>Button - general button background color, where buttons need a background different from Background, as in the Macintosh style. </li> <li>ButtonText - a foreground color used with the Button color. </li> <li>Highlight - a color to indicate a selected or highlighted item. </li> <li>HighlightedText - a text color that contrasts to Highlight. </li> <li>BrightText - a text color that is very different from Foreground and contrasts well with e.g. black. </li> </ul> </p> + + + + Choose Pi&xmap: + + + + Select a pixmap + + + + Choose a pixmap-file for the selected central color role. + + + + &Select Color: + + + + Choose a color + + + + Choose a color for the selected central color role. + + + + 3-D shadow &effects + + + + Build &from button color + + + + Generate shadings + + + + Check to let 3D-effect colors be calculated from button-color. + + + + Light + + + + Midlight + + + + Mid + + + + Dark + + + + Shadow + + + + Choose 3D-effect color role + + + + <b>Select a color role.</b><p>Available effect roles are: <ul> <li>Light - lighter than Button color. </li> <li>Midlight - between Button and Light. </li> <li>Mid - between Button and Dark. </li> <li>Dark - darker than Button. </li> <li>Shadow - a very dark color. </li> </ul> + + + + Select Co&lor: + + + + Choose a color for the selected effect color role. + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + PaletteEditorBase + + Edit Palette + + + + Build Palette + + + + &3-D Effects: + + + + Choose a color + + + + Choose the effect-color for the generated palette. + + + + Back&ground: + + + + Choose the background color for the generated palette. + + + + &Tune Palette... + + + + Preview + + + + Select &Palette: + + + + Active Palette + + + + Inactive Palette + + + + Disabled Palette + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + PixmapCollectionEditor + + Manage Image Collection + + + + &Add... + + + + &Delete + + + + &OK + + + + &Cancel + + + + &Close + + + + Choose an Image + + + + + PixmapFunction + + Choose Pixmap + + + + &Enter arguments for loading the pixmap + + + + QPixmap( + + + + ) + + + + &Help + + + + &OK + + + + &Cancel + + + + + Preferences + + Preferences + + + + <b>Preferences</b><p>Change the preferences of the designer application. There is always one tab with general preferenced. Depending on installed plugins, there might be more tabs for plugin preferences.</p> + + + + General + + + + Backgro&und + + + + Choose a color + + + + Select a color in the colordialog. + + + + Co&lor + + + + Use a background color + + + + Use a background color. + + + + &Pixmap + + + + Use a background pixmap + + + + Use a background pixmap. + + + + Select a pixmap + + + + Choose a pixmap-file. + + + + Show &Grid + + + + Show Grid + + + + <b>Customize the grid appearance for all forms.</b><p>When <b>Show Grid</b> is checked, all forms show a grid.</p> + + + + Gr&id + + + + Sn&ap to Grid + + + + Snap to the grid + + + + <b>Customize the grid-settings for all forms.</b><p>When <b>Snap to Grid</b> is checked, the widgets snap to the grid using the the X/Y resolution.</p> + + + + Grid resolution + + + + <b>Customize the grid-settings for all forms.</b><p>When <b>Show Grid</b> is checked, a grid is shown on all forms using the X/Y resolution.</p> + + + + Grid-&X: + + + + Grid-&Y: + + + + A splashscreen is displayed when starting the designer if this option is checked. + + + + Ge&neral + + + + Restore Last &Workspace on Startup + + + + Restore last workspace + + + + The current workspace settings will be restored next time you start the designer if this option is checked. + + + + Show &Splash Screen on Startup + + + + Show Splashscreen + + + + Disable Data&base Auto-Edit in Preview + + + + &Documentation Path: + + + + <b>Enter the path to the documentation.</b><p>You may provide an $environment variable as first part of your pathname.</p> + + + + ... + + + + Select path + + + + Look for the documentation path. + + + + &Toolbars + + + + Show &Big Icons + + + + Big Icons + + + + Uses big icons in the toolbars when checked. + + + + Show Text Lab&els + + + + Text Labels + + + + Shows textlabels in the toolbars when checked. + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + PreviewWidgetBase + + Preview Window + + + + ButtonGroup + + + + RadioButton1 + + + + RadioButton2 + + + + RadioButton3 + + + + ButtonGroup2 + + + + CheckBox1 + + + + CheckBox2 + + + + LineEdit + + + + ComboBox + + + + PushButton + + + + <p> +<a href="http://www.trolltech.com"> http://www.trolltech.com </a> +</p> +<p> +<a href="http://www.kde.org"> http://www.kde.org </a> +</p> + + + + + Project + + <No Project> + + + + + ProjectSettings + + unnamed.pro + + + + Database Files (*.db);;All Files (*) + + + + Project Files (*.pro);;All Files (*) + + + + + ProjectSettingsBase + + Project Settings + + + + &Settings + + + + &Project File: + + + + ... + + + + &Language + + + + &Description: + + + + &Files + + + + For&ms and Sources: + + + + Filename + + + + Form + + + + &Remove + + + + Add... + + + + &Database File: + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + PropertyBoolItem + + False + + + + True + + + + + PropertyColorItem + + Red + + + + Green + + + + Blue + + + + + PropertyCoordItem + + x + + + + y + + + + width + + + + height + + + + + PropertyCursorItem + + Arrow + + + + Up-Arrow + + + + Cross + + + + Waiting + + + + iBeam + + + + Size Vertical + + + + Size Horizontal + + + + Size Slash + + + + Size Backslash + + + + Size All + + + + Blank + + + + Split Vertical + + + + Split Horizontal + + + + Pointing Hand + + + + Forbidden + + + + + PropertyDatabaseItem + + Connection + + + + Table + + + + Field + + + + + PropertyEditor + + Reset property to its default value + + + + Click this button to reset the property to its default value + + + + Property Editor + + + + &Properties + + + + &Signal Handlers + + + + Property Editor (%1) + + + + + PropertyFontItem + + Family + + + + Point Size + + + + Bold + + + + Italic + + + + Underline + + + + Strikeout + + + + + PropertyList + + Property + + + + Value + + + + Set '%1' of '%2' + + + + Sort &Categorized + + + + Sort &Alphabetically + + + + Reset '%1' of '%2' + + + + <p><b>QWidget::%1</b></p><p>There is no documentation available for this property.</p> + + + + + PropertySizePolicyItem + + hSizeType + + + + vSizeType + + + + horizontalStretch + + + + verticalStretch + + + + %1/%2/%2/%2 + + + + + PropertyTextItem + + ... + + + + + QApplication + + Connection + + + + Could not connect to the database. +Press 'OK' to continue or 'Cancel' to specify different +connection information. + + + + + &OK + + + + &Cancel + + + + + QDesignerMenuBar + + Delete Item + + + + Rename Item... + + + + Remove Menu '%1' + + + + Rename Menuitem + + + + Menu Text + + + + Rename Menu '%1' to '%2' + + + + Move menu '%1' + + + + + QDesignerPopupMenu + + Delete Item + + + + Insert Separator + + + + Remove Action '%1' from the Popup Menu '%2' + + + + Add Separator to the Popup Menu '%1' + + + + Add Action '%1' to the Popup Menu '%2' + + + + Insert/Move Action + + + + The Action '%1' has already been added to this menu. +An Action can only be added once to the same menu. + + + + + QDesignerTabWidget + + Move Tab Page + + + + + QDesignerToolBar + + Delete Toolbar + + + + Remove Toolbar '%1' + + + + Delete Item + + + + Insert Separator + + + + Remove Action '%1' from Toolbar '%2' + + + + Add Separator to Toolbar '%1' + + + + Add Action '%1' to Toolbar '%2' + + + + Insert/Move Action + + + + The Action '%1' has already been added to this toolbar. +An Action can only be added once to the same toolbar. + + + + Add Widget '%1' to Toolbar '%2' + + + + + ReplaceDialog + + Replace Text + + + + R&eplace + + + + &Find + + + + &Replace + + + + Replace &All + + + + Close + + + + &Options + + + + &Whole words only + + + + &Case sensitive + + + + &Start at Beginning + + + + &Direction + + + + Forwar&d + + + + &Backward + + + + + SizeHandle + + %1/%2 + + + + Resize + + + + + SourceEditor + + Edit %1 + + + + + SourceFile + + Edit %1 + + + + Save Code + + + + Save changes to '%1'? + + + + &Yes + + + + &No + + + + &Cancel + + + + Qt Designer + + + + The file %1 has been changed outside Qt Designer. +Do you want to reload it? + + + + Invalid Filename + + + + The project contains already a sourcefile with the +filename '%1'. Please choose a new filename. + + + + + TableEditor + + Edit Rows and Columns of '%1' + + + + + TableEditorBase + + Edit Table + + + + 1 + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + Co&lumns + + + + Move up + + + + <b>Move the selected item up.</b><p>The topmost column will be the first column of the list.</p> + + + + Move down + + + + <b>Move the selected item down.</b><p>The topmost column will be the first column of the list.</p> + + + + &Delete Column + + + + &New Column + + + + Table: + + + + Label4 + + + + Delete Pixmap + + + + <b>Delete the pixmap of the selected item.</b><p>The pixmap in the current column of the selected item will be deleted.</p> + + + + ... + + + + Select a Pixmap + + + + <b>Select a pixmap-file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p> + + + + &Label: + + + + Pixmap: + + + + &Field: + + + + <no table> + + + + &Rows + + + + &New Row + + + + &Delete Row + + + + + TextEditor + + Text + + + + + WizardEditor + + Edit Wizard Pages + + + + Add Page to %1 + + + + Remove Page %1 of %2 + + + + Swap pages %1 and %2 of %1 + + + + Page Title + + + + New page title + + + + Rename page %1 of %2 + + + + + WizardEditorBase + + Wizard Page Editor + + + + Wizard Pages: + + + + &Add + + + + &Remove + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + Workspace + + Files + + + + &Open source file... + + + + &Remove source file from project + + + + &Open form... + + + + &Remove form from project + + + + &Open form source... + + + + + qChoosePixmap + + All Pixmaps ( + + + + %1-Pixmaps (%2) + + + + + ) + + + + + All Files (*) + + + + Choose Images... + + + + Choose a Pixmap... + + + + diff --git a/tools/designer/designer/designer_fr.ts b/tools/designer/designer/designer_fr.ts new file mode 100644 index 0000000..64f3cf3 --- /dev/null +++ b/tools/designer/designer/designer_fr.ts @@ -0,0 +1,4969 @@ + + + AboutDialog + + Qt Designer + + + + Version 2.0 + + + + Copyright (C) 2000-2008 Trolltech AS + + + + <p>This program is licensed to you under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation. This gives you legal permission to copy, distribute and/or modify this software under certain conditions. For details, see the file 'COPYING' that came with this software distribution. If you did not get the file, send email to info@trolltech.com.</p> +<p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> + + + + &OK + + + + + ActionEditor + + Actions + + + + New &Action + + + + New Action &Group + + + + New &Dropdown Action Group + + + + + ActionEditorBase + + Edit Actions + + + + Create new Action + + + + Delete current Action + + + + Connect current action + + + + + ActionListView + + New &Action + + + + New Action &Group + + + + New &Dropdown Action Group + + + + &Connect Action... + + + + Delete Action + + + + + ConnectionEditor + + Signals (%1): + + + + Connect/Disconnect signals and slots of '%1' and '%2' + + + + Remove connection + + + + Remove connections + + + + Add connection + + + + Add connections + + + + + ConnectionEditorBase + + Edit Connections + + + + <b>Edit Connections</b><p>Add and remove connections in the current form .</p><p>Select a signal and a corresponding slot and press the <b>Connect</b>-button to create a connection.</p><p>Select a connection from the list and press the <b>Disconnect</b>-button to delete the connection.</p> + + + + Sender + + + + Signal + + + + Receiver + + + + Slot + + + + Displays the connections between the sender and the receiver. + + + + Si&gnals: + + + + <b>A list of slots for the receiver.</b><p>Only those slots are displayed that have arguments corresponding with the signal selected in the Signal-list.</b> + + + + Connec&tions: + + + + Co&nnect + + + + Create connection + + + + Create the connection between signal and slot. + + + + &Disconnect + + + + Remove selected connection + + + + Remove the selected connection. + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + &Edit Slots + + + + Displays a list of signals for the emitting widget. + + + + &Slots: + + + + + ConnectionViewer + + Remove connection between %1 and %2 + + + + + ConnectionViewerBase + + View Connections + + + + <b>View Connections</b><p>Displays all connections in the current form Select a connection from the list and click the <b>Edit</b>-button to change the connection.</p> + + + + &Help + + + + &Close + + + + Close the Dialog. + + + + Sender + + + + Signal + + + + Receiver + + + + Slot + + + + <b>Displays a list of connections.</b><p>Select a connection and choose edit, or double-click on an item to change the connection.</p> + + + + &Edit... + + + + Edit connection + + + + Opens a dialog to change the selected connection. + + + + &Disconnect + + + + + CreateTemplate + + Create Template + + + + Template &Name: + + + + Name of the new template + + + + Enter the name of the new template here + + + + Class of the new template + + + + Choose the class which should be used as baseclass for the new template here + + + + C&reate + + + + Creates the new template + + + + &Cancel + + + + Closes the Dialog + + + + &Baseclass for Template: + + + + + CustomWidgetEditor + + Adding a Custom Widget + + + + There exists already a custom widget with the name '%1', +so it is not possible to add another one with this name. + + + + Removing Custom Widget + + + + The custom widget '%1' is currently used, so it can't be removed. + + + + Header Files (*.h *.h++ *.hxx *.hh) + + + + Renaming a Custom Widget + + + + The name '%1' is already use by another custom widget, +so it is not possible to rename it to this name. + + + + protected + + + + Custom-Widget Description (*.cw);;All Files (*) + + + + + CustomWidgetEditorBase + + Edit Custom Widgets + + + + <b>Edit Custom Widgets</b><p>Add and remove custom widgets to the designer's database, and change the properties of existing widgets.</p> + + + + The list of all custom widgets known to the designer. + + + + &New Widget + + + + Add new custom widget. + + + + <b>Create an empty custom widget and add it to the list.</b><p>New custom widgets have a default name and header-file, which must both be provided.</p> + + + + &Delete Widget + + + + Delete custom widget + + + + <b>Delete the selected custom widget.</b><p>You can only delete widgets that are not used in any open form.</p> + + + + &Help + + + + &Close + + + + Closes the Dialog. + + + + &Load Descriptions... + + + + Loads widget description file + + + + <b>Load Descriptions</b><p>Loads a file which contains descriptions of custom widgets, so that these custom widgets can be used in the Qt Designer.</p> +<p>As it is a lot of work to type in all the information for custom widgets, you should check the tool createcw which you can find in $QTDIR/tools/designer/tools/createcw. Using that tool you can create custom widget description files for your custom widgets without the need of typing in all that information. For more information about that see the README file in that directory</p> + + + + &Save Descriptions... + + + + Saves widget description file + + + + <b>Save Descriptions</b><p>Saves all descriptions of the shown custom widgets to file which can be used to import these custom widgets somewhere else. + + + + Change properties for the selected custom widget. + + + + De&finition + + + + ... + + + + Select a Pixmap + + + + <b>Select a pixmap-file.</b><p>The pixmap will be used to represent the widget in forms.</b> + + + + Enter filename + + + + <b>Change the headerfile's name for the selected custom widget.</b><p>The headerfile will be included by forms using the widget.</p> + + + + Choose headerfile + + + + Look for the headerfile in a filedialog. + + + + Global + + + + Local + + + + Select access + + + + <b>Change how the include file will be included.</b><p>Global include-files will be included using &lt;&gt;-brackets, while local files will included using quotation marks.</p> + + + + Change classname + + + + <b>Enter the classname for the selected customwidget.</b><p>A class of that name has to be defined in the headerfile.</p> + + + + Heade&rfile: + + + + Cl&ass: + + + + Pixmap: + + + + Si&ze Hint: + + + + Size P&olicy + + + + Fixed + + + + Minimum + + + + Maximum + + + + Preferred + + + + MinimumExpanding + + + + Expanding + + + + Horizontal Sizepolicy + + + + Choose the horizontal sizepolicy here + + + + Size hint width + + + + <b>Set the sizehint for the selected widget.</b><p>The sizehint provides the recommended size for the widget. Enter a sizehint of -1/-1 if no size is recommended.</p> + + + + Size hint height + + + + Vertical Sizepolicy + + + + Choose the verical sizepolicy for the widget here + + + + Con&tainer Widget + + + + Container Widget + + + + <p><b>Container Widget</b></p> +<p>If this customwidget should be able to contain other widgets (children), check this checkbox.</p> + + + + Si&gnals + + + + The list of all signals the selected widget can emit. + + + + N&ew Signal + + + + Add new signal + + + + <b>Add a new signal for the current custom widget.</b><p>An argument list should be provided in the signal's name, and the name has to be unique.</p> + + + + Dele&te Signal + + + + Delete signal + + + + <b>Delete the signal.</b><p>All connections using this signal will be deleted, too.</p> + + + + S&ignal: + + + + Change signal name + + + + <b>Change the name of the selected slot.</b><p>An argument list should be provided in the signal's name, and the name has to be unique.</p> + + + + S&lots + + + + Slot + + + + Access + + + + The list of all slots of the selected custom widget. + + + + Sl&ot: + + + + Change slot name + + + + &Access: + + + + public + + + + protected + + + + Change slot access + + + + <b>Change the access policy of the slot.</b><p>You can only connect to public slots of the widget.</p> + + + + N&ew Slot + + + + Add new slot + + + + <b>Add a new slot to the current custom widget.</b><p>An argument list should be provided in the signal's name, and the name has to be unique.</p> + + + + Dele&te Slot + + + + Delete slot + + + + <b>Delete the slot.</b><p>All connections using this slot will be deleted, too.</p> + + + + &Properties + + + + N&ew Property + + + + Add new property + + + + <b>Add a new property to the current customwidget.</b><p>The properties have to be implemented in the class using the property system of Qt.</p> + + + + Dele&te Property + + + + Delete property + + + + Deletes the selected property. + + + + String + + + + CString + + + + StringList + + + + Bool + + + + Int + + + + UInt + + + + Font + + + + Color + + + + Rect + + + + Point + + + + Size + + + + Pixmap + + + + Palette + + + + Cursor + + + + SizePolicy + + + + Select property type + + + + <b>Select the type of the property.</b><p>The propertiy has to be implemented in the class using the property system of Qt.</p><p>You can use integer types to support enumeration properties in the property editor.</p> + + + + Property + + + + Type + + + + <b>The list of properties of the current custom widget.</b><p>The properties of the custom widget can be changed in the property editor.</p> + + + + Change property name + + + + <b>Enter a name for the property.</b><p>The properties have to be implemented in the class using the property system of Qt.</p> + + + + P&roperty Name: + + + + T&ype: + + + + + DatabaseConnectionBase + + Edit Database Connections + + + + &New Connection + + + + &Delete Connection + + + + &Help + + + + &Close + + + + Close dialog and discard all changes. + + + + Conn&ection + + + + Connec&t + + + + + DatabaseConnectionEditorBase + + Connect + + + + &Cancel + + + + &OK + + + + Connection Details + + + + + DatabaseConnectionWidget + + Edit Database Connection + + + + &Database Name: + + + + &Username: + + + + &Password: + + + + D&river + + + + &Hostname: + + + + &Name: + + + + P&ort + + + + Default + + + + + EditSlots + + Yes + + + + No + + + + Add/Remove slots of '%1' + + + + Remove slot + + + + Remove slots + + + + Add slot + + + + Add slots + + + + Edit Slots + + + + Some syntatically wrong slots defined. +Remove these slots? + + + + &Yes + + + + &No + + + + + EditSlotsBase + + Edit Slots + + + + <b>Edit Slots</b><p>Add, change and remove slots of the current form.</p><p>Press the <b>Add Slot</b>-button to create a new slot, enter a slot name and choose an access mode.</p><p>Select an entry from the list and press the <b>Delete Slot</b>-button to remove a slot. All connections using this slot will be removed, too.</p> + + + + Slot + + + + Type + + + + Specifier + + + + Access + + + + In Use + + + + <b>This form's slots.</b><p>Select the slot you want to change or delete.</p> + + + + &New Slot + + + + Add new slot + + + + <b>Add a new slot.</b><p>New slots have a default name and public access.</p> + + + + &Delete Slot + + + + Delete slot + + + + <b>Delete the selected slot.</b><p>All connections using this slot are removed, too.</p> + + + + Slot Properties + + + + &Slot: + + + + Change slot name + + + + <b>Change the name of the selected slot.</b><p>The name should include the argument list and has to be syntactically correct.</p> + + + + &Return type: + + + + S&pecifier: + + + + non virtual + + + + virtual + + + + pure virtual + + + + Change slot access + + + + <b>Change the access policy of the slot</b><p>All slots will be created virtual and should be reimplemented in subclasses.</p> + + + + &Access: + + + + public + + + + protected + + + + private + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + EventList + + New Signal Handler + + + + Delete Signal Handler + + + + Remove connection + + + + Add connection + + + + + FindDialog + + Find Text + + + + &Find: + + + + &Find + + + + Close + + + + &Direction + + + + Forwar&d + + + + &Backward + + + + &Options + + + + &Whole words only + + + + &Case sensitive + + + + Start at &Beginning + + + + + FormDefinitionView + + Slots + + + + private + + + + protected + + + + public + + + + Edit... + + + + New + + + + Properties... + + + + Goto Implementation + + + + Delete + + + + Edit...Alt+V + + + + Edit %1 + + + + Edit Class Variables + + + + + FormFile + + Failed to save file %1. + + + + %1 saved. + + + + Qt User-Interface Files (*.ui) + + + + All Files (*) + + + + Save form '%1' as .... + + + + Edit %1 + + + + Save Form + + + + Save changes to the form '%1'? + + + + &Yes + + + + &No + + + + &Cancel + + + + Qt Designer + + + + The file %1 has been changed outside Qt Designer. +Do you want to reload it? + + + + Invalid Filename + + + + The project contains already a form with the +filename '%1'. Please choose a new filename. + + + + + FormSettingsBase + + Form Settings + + + + <b>Form Settings</b><p>Change settings for the form. Settings like <b>Comment</b> and <b>Author</b> are for personal use and not required.</p> + + + + &Pixmaps + + + + Save In&line + + + + Save pixmaps into the .ui files + + + + <b>Save Inline</b><p>Saves the pixmaps you choose as binary data into the .ui files. Pixmaps are not shared between forms. We recommend using Project Imagefiles instead. + + + + Project &Imagefile + + + + Use the Project's Image file to load pixmaps + + + + <b>Use the Project's Image file to open pixmaps</b> +<p>Each project has a collection of pixmaps. If you use a project, we recommend that you use this option since it shares images and is the fastest and most efficient way to use pixmaps in your forms.</p> + + + + Specify Pixmap-Loader function (only function-name, no parentheses!) + + + + <b>Specify Pixmap-Loader function</b><p>Specify the function which should be used for loading a pixmap in the generated code. <em>Only enter the function-name, no parentheses!</em> + + + + Use &Function: + + + + Use a defined function to load pixmaps + + + + <b>Use a defined function to open pixmaps</b><p>If you choose this option you must define a function in the line edit at the right which will be used in the generated code for loading pixmaps. When choosing a pixmap in <i>Qt Designer</i> you will be asked to specify the arguments which will be passed to the function in the generated code.<p> This approach makes it possible to use your own icon-loader function for loading pixmaps. <i>Qt Designer</i> can't preview the correct image if you use your own function. + + + + &Settings + + + + Change class name + + + + <b>Enter the name of the class that will be created.</b><p><em>classname.h</em> and <em>classname.cpp</em> will be generated as C++-output when it is compiled with the uic.</p> + + + + A&uthor: + + + + Enter your name + + + + Enter your name here. + + + + Class &Name: + + + + Co&mment: + + + + Enter a comment about the form. + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + La&youts + + + + Default Mar&gin: + + + + D&efault Spacing: + + + + + FormWindow + + Set 'name' property + + + + The name of a widget has to be unique! +'%1' is already used in the form '%2', +so the name has been changed back to '%3'. + + + + The name of a widget must not be null! +The name has been changed back to '%1'. + + + + &Horizontal + + + + &Vertical + + + + <b>A %1 (custom widget)</b> <p>Select <b>Edit Custom Widgets...</b> in the <b>Tools->Custom</b> menu to add and change the custom widgets. You can add properties as well as signals and slots to integrate them into the designer, and provide a pixmap which will be used to represent the widget on the form.</p> + + + + A %1 (custom widget) + + + + Reparent Widgets + + + + Insert %1 + + + + Connect '%1' with... + + + + Change Tab Order + + + + %1/%2 + + + + Connect '%1' with '%2' + + + + Inserting a Widget + + + + You tried to insert a widget into the laid out Container Widget '%1'. +This is not possible. In order to insert the widget, the layout of '%1' +has to be broken. Break the layout or cancel the operation? + + + + &Break Layout + + + + &Cancel + + + + Move + + + + Use Size Hint + + + + Delete + + + + Adjust Size + + + + Click widgets to change tab order... + + + + Drag a line to create a connection... + + + + Click on the form to insert a %1... + + + + Following custom widgets are used in '%1', +but they are not known to the designer: + + + + Save Form + + + + Lower + + + + Check Accelerators + + + + The accelerator '%1' is used %2 times. + + + + &Select + + + + No accelerator is used more than once! + + + + Raise + + + + Layout horizontally + + + + Layout vertically + + + + Layout horizontally (in splitter) + + + + Layout vertically (in splitter) + + + + Layout in a grid + + + + Layout children horizontally + + + + Layout children vertically + + + + Layout children in a grid + + + + Break Layout + + + + Edit connections... + + + + Paste + + + + Page + + + + + GotoLineDialog + + Goto Line + + + + &Line: + + + + &Goto + + + + &Close + + + + + HierarchyList + + Name + + + + Class + + + + Database + + + + Add Page to %1 + + + + Remove Page %1 of %2 + + + + + HierarchyView + + Widgets + + + + Source + + + + Classes + + + + + IconViewEditor + + New Item + + + + Edit Items of '%1' + + + + + IconViewEditorBase + + Edit Iconview + + + + <b>Edit Iconview</b><p>Add, change and remove items in the icon view.</p><p>Press the <b>New Item</b>-button to create a new entry, and enter a text or choose a pixmap.</p><p>Select an item from the view and press the <b>Delete Item</b>-button to remove the item from the view.</p> + + + + All items in the view. + + + + &New Item + + + + Add an item + + + + Create a new item for the view. + + + + &Delete Item + + + + Delete item + + + + Delete the selected item. + + + + &Item Properties + + + + &Text: + + + + Change text + + + + Change the text for the selected item. + + + + &Pixmap: + + + + Label4 + + + + Delete Pixmap + + + + Delete the pixmap of the selected item. + + + + ... + + + + Select a Pixmap + + + + Select a pixmap-file for the current item. + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + ListBoxEditor + + New Item + + + + Edit Items of '%1' + + + + + ListBoxEditorBase + + Edit Listbox + + + + <b>Edit Listbox</b><p>Add, change and remove items in the listbox.</p><p>Press the <b>New Item</b>-button to create a new listbox entry, and enter text or choose a pixmap.</p><p>Select an item from the list and press the <b>Delete Item</b>-button to remove the item from the list.</p> + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + Delete Item + + + + The list of items. + + + + &Item Properties + + + + &Pixmap: + + + + Label4 + + + + Delete Pixmap + + + + Delete the pixmap of the selected item. + + + + ... + + + + Select a Pixmap + + + + Choose a pixmap-file for the selected item. + + + + &Text: + + + + Change text + + + + Change the text of the selected item. + + + + &New Item + + + + Add an item + + + + <b>Add a new item.</b><p>New items are appended to the list.</p> + + + + &Delete Item + + + + Delete the selected item + + + + Move up + + + + Moves the selected item up. + + + + Move down + + + + Move the selected item down. + + + + + ListEditor + + Edit... + + + + Column 1 + + + + &Add + + + + &Remove + + + + Re&name + + + + &Close + + + + + ListViewEditor + + Edit Items and Columns of '%1' + + + + New Column + + + + &Items + + + + + ListViewEditorBase + + Edit Listview + + + + <b>Edit Listview</b><p>Use the controls on the <b>Items</b>-tab to add, change and remove items in the listview. Change the column configuration of the view using the controls on the <b>Columns</b>-tab.</p>Press the <b>New Item</b>-button to create a new item and enter a text or provide a pixmap.</p><p>Select an item from the list and press the <b>Delete Item</b>-button to remove the item from the list.</p> + + + + &Items + + + + &Delete Item + + + + Delete item + + + + <b>Deletes the selected item.</b><p>Existing subitems are deleted, too.</p> + + + + Item &Properties + + + + Pi&xmap: + + + + &Text: + + + + Change text + + + + <b>Change the text of the item.</b><p>The text will be changed in the current column of the selected item.</p> + + + + Change column + + + + <b>Select the current column.</b><p>Itemtext and pixmap will be changed for the current column</p> + + + + Colu&mn: + + + + Label4 + + + + Delete Pixmap + + + + <b>Delete the pixmap of the selected item.</b><p>The pixmap in the current column of the selected item will be deleted.</p> + + + + ... + + + + Select a Pixmap + + + + <b>Select a pixmap-file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p> + + + + &New Item + + + + Add an item + + + + <b>Adds a new item to the list.</b><p>The item will be inserted at the top of the list and can be moved using the up- and down-buttons.</p> + + + + The list of items. + + + + New &Subitem + + + + Add a subitem + + + + <b>Create a new subitem for the selected item.</b><p>New subitems are inserted at the top of the list of subitems, and new levels will be created automatically.</p> + + + + Move up + + + + <b>Move the selected item up.</b><p>The item will be moved within the hierarchy level.</p> + + + + Move down + + + + <b>Move the selected item down.</b><p>The item will be moved within the hierarchy level.</p> + + + + Move left + + + + <b>Move the selected item one level up.</b><p>This will also change the level of the parent item.</p> + + + + Move right + + + + <b>Move the selected item one level down.</b><p>This will also change the level of the parent item.</p> + + + + Co&lumns + + + + Column Properties + + + + &Pixmap: + + + + Delete the pixmap of the selected column. + + + + <b>Select a pixmap-file for the selected column.</b><p>The pixmap will be displayed in the header of the listview.</p> + + + + Enter column text + + + + <b>Enter the text for the selected column.</b><p>The text will be displayed in the header of the listview.</p> + + + + Clicka&ble + + + + If this option is checked, the selected column will react on mouseclicks on the header. + + + + Re&sizable + + + + The column's width will be resizeable if this option is checked. + + + + &Delete Column + + + + Delete column + + + + Deletes the selected Column. + + + + <b>Move the selected item down.</b><p>The topmost column will be the first column of the list.</p> + + + + &New Column + + + + Add a Column + + + + <b>Create a new column.</b><p>New columns are appended to the list and may be moved using the up- and down-buttons.</p> + + + + <b>Move the selected item up.</b><p>The topmost column will be the first column of the list.</p> + + + + The list of columns. + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + MainWindow + + Qt User-Interface Files (*.ui) + + + + Ready - This is the non-commercial version of Qt - For commercial evaluation purposes, use the help menu to register with Trolltech. + + + + Layout + + + + Property Editor/Signal Handlers + + + + <b>The Property Editor</b><p>You can change the appearance and behaviour of the selected widget in the property editor.</p><p>You can set properties for components and forms at design time and see the changes immediately. Each property has its own editor which you can use to enter new values, open a special dialog or select values from a predefined list. Use <b>F1</b> to get detailed help for the selected property.</p><p>You can resize the columns of the editor by dragging the separators of the list header.</p><p><b>Signal Handlers</b></p><p>In the Signal Handlers tab you can define connections between signals of widgets and slots of the form. That is just a convenience way, you can use the connection tool to do that as well. + + + + Output Window + + + + Object Explorer + + + + <b>The Object Explorer</b><p>The object explorer gives a quick overview about the relations between the widgets in your form. You can use the clipboard functions using a context menu for each item in the view.</p><p>The columns can be resized by dragging the separator in the list header.</p><p>On the second tab you can see all the declared slots, variables, includes, etc. of the form.</p> + + + + Start typing the buffer you want to switch to here (ALT+B) + + + + File Overview + + + + <b>The File Overview box</b><p>The File Overview Box displays all files of all projects, including forms and source files.</p><p>Its search field allows rapid switching between files.</p> + + + + Action Editor + + + + <b>The Action Editor</b><p>Todo Whatsthis</p> + + + + Error + + + + Couldn't find the Qt documentation property index file! +Define the correct documentation path in the preferences dialog. + + + + <b>The Form Window</b><p>Use the different tools to add widgets or to change the layout and behaviour of the components in your form. Select one or multiple widgets and move them, or resize a single widget using the handles.</p><p>Changes in the <b>Property Editor</b> can be seen at design time, and you can open a preview of your form in different styles.</p><p>You can change the grid resolution, or turn the grid off in the <b>Preferences</b> dialog in the <b>Edit</b> menu.<p>You can have several forms open, and all open forms are listed in the <b>Form List</b>. + + + + New Project + + + + Cannot create invalid project. + + + + &Undo + + + + &Redo + + + + &Undo: %1 + + + + &Undo: Not Available + + + + &Redo: %1 + + + + &Redo: Not Available + + + + Choose Pixmap... + + + + Edit Text... + + + + Edit Title... + + + + Edit Page Title... + + + + Remove Page + + + + Add Page + + + + Edit... + + + + Edit Pages... + + + + Add Menu Item + + + + Add Toolbar + + + + Text + + + + New text + + + + Set 'text' of '%2' + + + + Title + + + + New title + + + + Set 'title' of '%2' + + + + Page Title + + + + New page title + + + + Set 'pageTitle' of '%2' + + + + Set 'pixmap' of '%2' + + + + Add Page to %1 + + + + Remove Page %1 of %2 + + + + Rename page %1 of %2 + + + + Add Toolbar to '%1' + + + + Add Menu to '%1' + + + + Save Project Settings + + + + Save changes to '%1'? + + + + &Yes + + + + &No + + + + &Cancel + + + + Edit %1... + + + + Restoring last session + + + + The Qt Designer found some temporary saved files, which have been +written when the Qt Designer crashed last time. Do you want to +load these files? + + + + Help + + + + There is no help available for this dialog at the moment. + + + + Open File + + + + Could not open '%1'. File does not exist. + + + + Open Project + + + + Undo + + + + Reverses the last action + + + + Redo + + + + Redoes the last undone operation + + + + Cut + + + + Cu&t + + + + Cuts the selected widgets and puts them on the clipboard + + + + Copy + + + + &Copy + + + + Copies the selected widgets to the clipboard + + + + Paste + + + + &Paste + + + + Pastes clipboard contents + + + + Delete + + + + &Delete + + + + Deletes the selected widgets + + + + Select All + + + + Select &All + + + + Selects all widgets + + + + Bring to Front + + + + Bring to &Front + + + + Raises the selected widgets + + + + Send to Back + + + + Send to &Back + + + + Lowers the selected widgets + + + + Check Accelerators + + + + Chec&k Accelerators + + + + Checks if the accelerators used in the form are unique + + + + Slots + + + + S&lots... + + + + Opens a dialog to edit slots + + + + Connections + + + + Co&nnections... + + + + Opens a dialog to edit connections + + + + Source + + + + &Source... + + + + Opens an editor to edit the source of the form + + + + Form Settings + + + + &Form Settings... + + + + Opens a dialog to change the settings of the form + + + + Preferences + + + + Preferences... + + + + Opens a dialog to change preferences + + + + <b>The Edit toolbar</b>%1 + + + + Edit + + + + &Edit + + + + Find + + + + &Find... + + + + Find Incremental + + + + Find &Incremental + + + + Replace + + + + &Replace... + + + + Goto Line + + + + &Goto Line... + + + + Search + + + + Incremetal Search (ALT+I) + + + + &Search + + + + Adjust Size + + + + Adjust &Size + + + + Adjusts the size of the selected widget + + + + Lay Out Horizontally + + + + Lay Out &Horizontally + + + + Lays out the selected widgets horizontally + + + + Lay Out Vertically + + + + Lay Out &Vertically + + + + Lays out the selected widgets vertically + + + + Lay Out in a Grid + + + + Lay Out in a &Grid + + + + Lays out the selected widgets in a grid + + + + Lay Out Horizontally (in Splitter) + + + + Lay Out Horizontally (in S&plitter) + + + + Lays out the selected widgets horizontally in a splitter + + + + Lay Out Vertically (in Splitter) + + + + Lay Out Vertically (in Sp&litter) + + + + Lays out the selected widgets vertically in a splitter + + + + Break Layout + + + + &Break Layout + + + + Breaks the selected layout + + + + Add + + + + Insert a %1 + + + + <b>The Layout toolbar</b>%1 + + + + &Layout + + + + Pointer + + + + &Pointer + + + + Selects the pointer tool + + + + Connect Signal/Slots + + + + &Connect Signal/Slots + + + + Selects the connection tool + + + + Tab Order + + + + Tab &Order + + + + Selects the tab order tool + + + + <b>The Tools toolbar</b>%1 + + + + Tools + + + + &Tools + + + + Custom Widgets + + + + Edit &Custom Widgets... + + + + Opens a dialog to change the custom widgets + + + + <b>The %1</b>%2 + + + + Click on a button to insert a single widget, or double click to insert multiple %1. + + + + <b>The %1 Widgets</b>%2 + + + + Click on a button to insert a single %1 widget, or double click to insert multiple widgets. + + + + <p>Double click on this tool to keep it selected.</p> + + + + <b>The Custom Widgets toolbar</b>%1<p>Select <b>Edit Custom Widgets...</b> in the <b>Tools->Custom</b> menu to add and change custom widgets</p> + + + + Click on the buttons to insert a single widget, or double click to insert multiple widgets. + + + + <b>The File toolbar</b>%1 + + + + File + + + + &File + + + + New + + + + &New... + + + + Creates a new project, form or source file. + + + + Open + + + + &Open... + + + + Opens an existing project, form for source file + + + + Close + + + + &Close + + + + Closes the current project or document + + + + Save + + + + &Save + + + + Saves the current project or document + + + + Save As + + + + Save &As... + + + + Saves the current form with a new filename + + + + Save All + + + + Sa&ve All + + + + Saves all open documents + + + + Create Template + + + + Create &Template... + + + + Creates a new template + + + + Recently opened files + + + + Recently opened projects + + + + Exit + + + + E&xit + + + + Quits the application and prompts to save changed forms, source files and project settings + + + + Pr&oject + + + + Active Project + + + + <No Project> + + + + Add File + + + + &Add File... + + + + Adds a file to the current project + + + + Image Collection... + + + + &Image Collection... + + + + Opens a dialog to edit the image collection of the current project + + + + Database Connections... + + + + &Database Connections... + + + + Opens a dialog to edit the database connections of the current project + + + + Project Settings... + + + + &Project Settings... + + + + Opens a dialog to change the settings of the project + + + + &Preview + + + + Preview Form + + + + Preview &Form + + + + Opens a preview + + + + The preview will use the Motif Look&Feel used as the default style on most UNIX-Systems. + + + + The preview will use the Windows Look&Feel used as the default style on Windows-Systems. + + + + The preview will use the Platinum Look&Feel resembling a Macinosh-like GUI style. + + + + The preview will use the CDE Look&Feel which is similar to some versions of the Common Desktop Environment. + + + + The preview will use the Motif Look&Feel used as the default style on SGI-systems. + + + + The preview will use an advanced Motif Look&Feel as used by the GIMP toolkit (GTK) on Linux. + + + + Preview Form in %1 Style + + + + ... in %1 Style + + + + Opens a preview in %1 style + + + + <b>Open a preview in %1 style.</b><p>Use the preview to test the design and signal-slot connections of the current form. %2</p> + + + + Tile + + + + &Tile + + + + Arranges all windows tiled + + + + Cascade + + + + &Cascade + + + + Arrange all windows cascaded + + + + Cl&ose + + + + Closes the active window + + + + Close All + + + + Close Al&l + + + + Closes all form windows + + + + Next + + + + Ne&xt + + + + Activates the next window + + + + Previous + + + + Pre&vious + + + + Activates the previous window + + + + &Window + + + + Vie&ws + + + + Tool&bars + + + + Contents + + + + &Contents + + + + Opens the online help + + + + Manual + + + + &Manual + + + + Opens the Qt Designer manual + + + + About + + + + &About + + + + Displays information about this product + + + + About Qt + + + + About &Qt + + + + Displays information about the Qt Toolkit + + + + Register Qt + + + + &Register Qt... + + + + Launches web browser with evaluation form at www.trolltech.com + + + + Register with Trolltech + + + + What's This? + + + + "What's This?" context sensitive help + + + + <b>The Help toolbar</b>%1 + + + + &Help + + + + Select new item ... + + + + Select a file... + + + + Designer Files (*.ui *.pro) + + + + QMAKE Project Files (*.pro) + + + + All Files (*) + + + + Add + + + + No import filter available for %1 + + + + Importing %1 using import filter ... + + + + Nothing to load in %1 + + + + Reading file %1... + + + + File %1 opened. + + + + Failed to load file %1 + + + + Load File + + + + Couldn't load file %1 + + + + Project '%1' saved. + + + + Enter a filename... + + + + Qt Designer is crashing - attempting to save work... + + + + NewTemplate + + + + Couldn't create the template + + + + Edit slots of current form... + + + + Edit connections in current form... + + + + Edit Source + + + + Edit settings of current form... + + + + Edit preferences... + + + + Edit custom widgets... + + + + New Item + + + + Column 1 + + + + Tab 1 + + + + Tab 2 + + + + Load Template + + + + + MultiLineEditor + + Set text of '%1' + + + + + MultiLineEditorBase + + Edit Multiline Edit + + + + <b>Edit Multiline Edit</b><p>Enter the text and press the <b>OK</b>-Button to apply the changes.</p> + + + + &Text: + + + + Enter your text here. + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + NewForm + + Project + + + + Dialog + + + + Wizard + + + + Widget + + + + Main Window + + + + + NewFormBase + + New File + + + + <b>New Form</b><p>Select a template for the new form and click the <b>OK</b>-button to open it.</p> + + + + &Help + + + + &OK + + + + Open a new form using the selected template. + + + + &Cancel + + + + Close dialog and do not open a form. + + + + Displays a list of available templates. + + + + &Insert into: + + + + + OutputWindow + + Error Messages + + + + Message + + + + Line + + + + + PaletteEditorAdvancedBase + + Tune Palette + + + + <b>Edit Palette</b><p>Change the palette of the current widget or form.</p><p>Use a generated palette or select colors for each color group and each color role.</p><p>The palette can be tested with different widget layouts in the preview section.</p> + + + + Select &Palette: + + + + Active Palette + + + + Inactive Palette + + + + Disabled Palette + + + + Auto + + + + Build inactive palette from active. + + + + Build disabled palette from active. + + + + Central color &roles + + + + Background + + + + Foreground + + + + Button + + + + Base + + + + Text + + + + BrightText + + + + ButtonText + + + + Highlight + + + + HighlightText + + + + Link + + + + LinkVisited + + + + Choose central color role + + + + <b>Select a color role.</b><p>Available central roles are: <ul> <li>Background - general background color.</li> <li>Foreground - general foreground color. </li> <li>Base - used as background color for e.g. text entry widgets, usually white or another light color. </li> <li>Text - the forground color used with Base. Usually this is the same as the Foreground, in what case it must provide good contrast both with Background and Base. </li> <li>Button - general button background color, where buttons need a background different from Background, as in the Macintosh style. </li> <li>ButtonText - a foreground color used with the Button color. </li> <li>Highlight - a color to indicate a selected or highlighted item. </li> <li>HighlightedText - a text color that contrasts to Highlight. </li> <li>BrightText - a text color that is very different from Foreground and contrasts well with e.g. black. </li> </ul> </p> + + + + Choose Pi&xmap: + + + + Select a pixmap + + + + Choose a pixmap-file for the selected central color role. + + + + &Select Color: + + + + Choose a color + + + + Choose a color for the selected central color role. + + + + 3-D shadow &effects + + + + Build &from button color + + + + Generate shadings + + + + Check to let 3D-effect colors be calculated from button-color. + + + + Light + + + + Midlight + + + + Mid + + + + Dark + + + + Shadow + + + + Choose 3D-effect color role + + + + <b>Select a color role.</b><p>Available effect roles are: <ul> <li>Light - lighter than Button color. </li> <li>Midlight - between Button and Light. </li> <li>Mid - between Button and Dark. </li> <li>Dark - darker than Button. </li> <li>Shadow - a very dark color. </li> </ul> + + + + Select Co&lor: + + + + Choose a color for the selected effect color role. + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + PaletteEditorBase + + Edit Palette + + + + Build Palette + + + + &3-D Effects: + + + + Choose a color + + + + Choose the effect-color for the generated palette. + + + + Back&ground: + + + + Choose the background color for the generated palette. + + + + &Tune Palette... + + + + Preview + + + + Select &Palette: + + + + Active Palette + + + + Inactive Palette + + + + Disabled Palette + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + PixmapCollectionEditor + + Manage Image Collection + + + + &Add... + + + + &Delete + + + + &OK + + + + &Cancel + + + + &Close + + + + Choose an Image + + + + + PixmapFunction + + Choose Pixmap + + + + &Enter arguments for loading the pixmap + + + + QPixmap( + + + + ) + + + + &Help + + + + &OK + + + + &Cancel + + + + + Preferences + + Preferences + + + + <b>Preferences</b><p>Change the preferences of the designer application. There is always one tab with general preferenced. Depending on installed plugins, there might be more tabs for plugin preferences.</p> + + + + General + + + + Backgro&und + + + + Choose a color + + + + Select a color in the colordialog. + + + + Co&lor + + + + Use a background color + + + + Use a background color. + + + + &Pixmap + + + + Use a background pixmap + + + + Use a background pixmap. + + + + Select a pixmap + + + + Choose a pixmap-file. + + + + Show &Grid + + + + Show Grid + + + + <b>Customize the grid appearance for all forms.</b><p>When <b>Show Grid</b> is checked, all forms show a grid.</p> + + + + Gr&id + + + + Sn&ap to Grid + + + + Snap to the grid + + + + <b>Customize the grid-settings for all forms.</b><p>When <b>Snap to Grid</b> is checked, the widgets snap to the grid using the the X/Y resolution.</p> + + + + Grid resolution + + + + <b>Customize the grid-settings for all forms.</b><p>When <b>Show Grid</b> is checked, a grid is shown on all forms using the X/Y resolution.</p> + + + + Grid-&X: + + + + Grid-&Y: + + + + A splashscreen is displayed when starting the designer if this option is checked. + + + + Ge&neral + + + + Restore Last &Workspace on Startup + + + + Restore last workspace + + + + The current workspace settings will be restored next time you start the designer if this option is checked. + + + + Show &Splash Screen on Startup + + + + Show Splashscreen + + + + Disable Data&base Auto-Edit in Preview + + + + &Documentation Path: + + + + <b>Enter the path to the documentation.</b><p>You may provide an $environment variable as first part of your pathname.</p> + + + + ... + + + + Select path + + + + Look for the documentation path. + + + + &Toolbars + + + + Show &Big Icons + + + + Big Icons + + + + Uses big icons in the toolbars when checked. + + + + Show Text Lab&els + + + + Text Labels + + + + Shows textlabels in the toolbars when checked. + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + PreviewWidgetBase + + Preview Window + + + + ButtonGroup + + + + RadioButton1 + + + + RadioButton2 + + + + RadioButton3 + + + + ButtonGroup2 + + + + CheckBox1 + + + + CheckBox2 + + + + LineEdit + + + + ComboBox + + + + PushButton + + + + <p> +<a href="http://www.trolltech.com"> http://www.trolltech.com </a> +</p> +<p> +<a href="http://www.kde.org"> http://www.kde.org </a> +</p> + + + + + Project + + <No Project> + + + + + ProjectSettings + + unnamed.pro + + + + Database Files (*.db);;All Files (*) + + + + Project Files (*.pro);;All Files (*) + + + + + ProjectSettingsBase + + Project Settings + + + + &Settings + + + + &Project File: + + + + ... + + + + &Language + + + + &Description: + + + + &Files + + + + For&ms and Sources: + + + + Filename + + + + Form + + + + &Remove + + + + Add... + + + + &Database File: + + + + &Help + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + PropertyBoolItem + + False + + + + True + + + + + PropertyColorItem + + Red + + + + Green + + + + Blue + + + + + PropertyCoordItem + + x + + + + y + + + + width + + + + height + + + + + PropertyCursorItem + + Arrow + + + + Up-Arrow + + + + Cross + + + + Waiting + + + + iBeam + + + + Size Vertical + + + + Size Horizontal + + + + Size Slash + + + + Size Backslash + + + + Size All + + + + Blank + + + + Split Vertical + + + + Split Horizontal + + + + Pointing Hand + + + + Forbidden + + + + + PropertyDatabaseItem + + Connection + + + + Table + + + + Field + + + + + PropertyEditor + + Reset property to its default value + + + + Click this button to reset the property to its default value + + + + Property Editor + + + + &Properties + + + + &Signal Handlers + + + + Property Editor (%1) + + + + + PropertyFontItem + + Family + + + + Point Size + + + + Bold + + + + Italic + + + + Underline + + + + Strikeout + + + + + PropertyList + + Property + + + + Value + + + + Set '%1' of '%2' + + + + Sort &Categorized + + + + Sort &Alphabetically + + + + Reset '%1' of '%2' + + + + <p><b>QWidget::%1</b></p><p>There is no documentation available for this property.</p> + + + + + PropertySizePolicyItem + + hSizeType + + + + vSizeType + + + + horizontalStretch + + + + verticalStretch + + + + %1/%2/%2/%2 + + + + + PropertyTextItem + + ... + + + + + QApplication + + Connection + + + + Could not connect to the database. +Press 'OK' to continue or 'Cancel' to specify different +connection information. + + + + + &OK + + + + &Cancel + + + + + QDesignerMenuBar + + Delete Item + + + + Rename Item... + + + + Remove Menu '%1' + + + + Rename Menuitem + + + + Menu Text + + + + Rename Menu '%1' to '%2' + + + + Move menu '%1' + + + + + QDesignerPopupMenu + + Delete Item + + + + Insert Separator + + + + Remove Action '%1' from the Popup Menu '%2' + + + + Add Separator to the Popup Menu '%1' + + + + Add Action '%1' to the Popup Menu '%2' + + + + Insert/Move Action + + + + The Action '%1' has already been added to this menu. +An Action can only be added once to the same menu. + + + + + QDesignerTabWidget + + Move Tab Page + + + + + QDesignerToolBar + + Delete Toolbar + + + + Remove Toolbar '%1' + + + + Delete Item + + + + Insert Separator + + + + Remove Action '%1' from Toolbar '%2' + + + + Add Separator to Toolbar '%1' + + + + Add Action '%1' to Toolbar '%2' + + + + Insert/Move Action + + + + The Action '%1' has already been added to this toolbar. +An Action can only be added once to the same toolbar. + + + + Add Widget '%1' to Toolbar '%2' + + + + + ReplaceDialog + + Replace Text + + + + R&eplace + + + + &Find + + + + &Replace + + + + Replace &All + + + + Close + + + + &Options + + + + &Whole words only + + + + &Case sensitive + + + + &Start at Beginning + + + + &Direction + + + + Forwar&d + + + + &Backward + + + + + SizeHandle + + %1/%2 + + + + Resize + + + + + SourceEditor + + Edit %1 + + + + + SourceFile + + Edit %1 + + + + Save Code + + + + Save changes to '%1'? + + + + &Yes + + + + &No + + + + &Cancel + + + + Qt Designer + + + + The file %1 has been changed outside Qt Designer. +Do you want to reload it? + + + + Invalid Filename + + + + The project contains already a sourcefile with the +filename '%1'. Please choose a new filename. + + + + + TableEditor + + Edit Rows and Columns of '%1' + + + + + TableEditorBase + + Edit Table + + + + 1 + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + Co&lumns + + + + Move up + + + + <b>Move the selected item up.</b><p>The topmost column will be the first column of the list.</p> + + + + Move down + + + + <b>Move the selected item down.</b><p>The topmost column will be the first column of the list.</p> + + + + &Delete Column + + + + &New Column + + + + Table: + + + + Label4 + + + + Delete Pixmap + + + + <b>Delete the pixmap of the selected item.</b><p>The pixmap in the current column of the selected item will be deleted.</p> + + + + ... + + + + Select a Pixmap + + + + <b>Select a pixmap-file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p> + + + + &Label: + + + + Pixmap: + + + + &Field: + + + + <no table> + + + + &Rows + + + + &New Row + + + + &Delete Row + + + + + TextEditor + + Text + + + + + WizardEditor + + Edit Wizard Pages + + + + Add Page to %1 + + + + Remove Page %1 of %2 + + + + Swap pages %1 and %2 of %1 + + + + Page Title + + + + New page title + + + + Rename page %1 of %2 + + + + + WizardEditorBase + + Wizard Page Editor + + + + Wizard Pages: + + + + &Add + + + + &Remove + + + + &Help + + + + &Apply + + + + Apply all changes. + + + + &OK + + + + Close dialog and apply all changes. + + + + &Cancel + + + + Close dialog and discard all changes. + + + + + Workspace + + Files + + + + &Open source file... + + + + &Remove source file from project + + + + &Open form... + + + + &Remove form from project + + + + &Open form source... + + + + + qChoosePixmap + + All Pixmaps ( + + + + %1-Pixmaps (%2) + + + + + ) + + + + + All Files (*) + + + + Choose Images... + + + + Choose a Pixmap... + + + + diff --git a/tools/designer/designer/designer_pch.h b/tools/designer/designer/designer_pch.h new file mode 100644 index 0000000..6b53f98 --- /dev/null +++ b/tools/designer/designer/designer_pch.h @@ -0,0 +1,44 @@ +/* + * This is a precompiled header file for use in Xcode / Mac GCC / + * GCC >= 3.4 / VC to greatly speed the building of Qt Designer. It may + * also be of use to people developing their own project, but it is + * probably better to define your own header. Use of this header is + * currently UNSUPPORTED. + */ + +#if defined __cplusplus + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "command.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "project.h" +#include "widgetfactory.h" + +#endif diff --git a/tools/designer/designer/designerapp.cpp b/tools/designer/designer/designerapp.cpp new file mode 100644 index 0000000..d546d1d --- /dev/null +++ b/tools/designer/designer/designerapp.cpp @@ -0,0 +1,181 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "designerappiface.h" +#include "designerapp.h" +#include "mainwindow.h" +#include "formwindow.h" + +#include +#include +#include +#include + +#ifdef Q_WS_WIN +#include +#include +#endif + +static QSplashScreen *splash = 0; + +void set_splash_status( const QString &txt ) +{ + if ( !splash ) + return; + QString splashText = "Licensed to " + + QString::fromLatin1( QT_PRODUCT_LICENSEE ) + "\n" + + txt; + splash->message( splashText, Qt::AlignRight|Qt::AlignTop ); +} + +DesignerApplication::DesignerApplication( int &argc, char **argv ) + : QApplication( argc, argv ) +{ +#if defined(Q_WS_WIN) + if ( winVersion() & Qt::WV_NT_based ) + DESIGNER_OPENFILE = RegisterWindowMessage((TCHAR*)"QT_DESIGNER_OPEN_FILE"); + else + DESIGNER_OPENFILE = RegisterWindowMessageA("QT_DESIGNER_OPEN_FILE"); +#endif +} + +QSplashScreen *DesignerApplication::showSplash() +{ + QRect screen = QApplication::desktop()->screenGeometry(); + QSettings config; + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + QRect mainRect; + QString keybase = settingsKey(); + bool show = config.readBoolEntry( keybase + "SplashScreen", TRUE ); + mainRect.setX( config.readNumEntry( keybase + "Geometries/MainwindowX", 0 ) ); + mainRect.setY( config.readNumEntry( keybase + "Geometries/MainwindowY", 0 ) ); + mainRect.setWidth( config.readNumEntry( keybase + "Geometries/MainwindowWidth", 500 ) ); + mainRect.setHeight( config.readNumEntry( keybase + "Geometries/MainwindowHeight", 500 ) ); + screen = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber( mainRect.center() ) ); + + if ( show ) { + splash = new QSplashScreen( QPixmap::fromMimeSource("designer_splash.png") ); + splash->show(); + set_splash_status( "Initializing..." ); + } + + return splash; +} + +void DesignerApplication::closeSplash() +{ + splash->hide(); +} + +static QString *settings_key = 0; +static QString *old_settings_key = 0; + +QString DesignerApplication::settingsKey() +{ + if ( !settings_key ) + settings_key = new QString( "/Qt Designer/" + + QString::number( (QT_VERSION >> 16) & 0xff ) + + "." + QString::number( (QT_VERSION >> 8) & 0xff ) + "/" ); + return *settings_key; +} + +QString DesignerApplication::oldSettingsKey() +{ + if ( !old_settings_key ) { + int majorVer = (QT_VERSION >> 16) & 0xff; + int minorVer = (QT_VERSION >> 8) & 0xff; + + // If minorVer is 0 (e.g. 4.0) then we don't want to read the + // old settings, too much might have changed. + if ( !minorVer == 0 ) + minorVer--; + + old_settings_key = new QString( "/Qt Designer/" + + QString::number( majorVer ) + + "." + QString::number( minorVer ) + "/" ); + } + return *old_settings_key; +} + +void DesignerApplication::setSettingsKey( const QString &key ) +{ + if ( !settings_key ) + settings_key = new QString( key ); + else + *settings_key = key; +} + +#if defined(Q_WS_WIN) +bool DesignerApplication::winEventFilter( MSG *msg ) +{ + if ( msg->message == DESIGNER_OPENFILE ) { + QFile f( QDir::homeDirPath() + "/.designerargs" ); + QFileInfo fi(f); + if ( fi.lastModified() == lastMod ) + return QApplication::winEventFilter( msg ); + lastMod = fi.lastModified(); + f.open( IO_ReadOnly ); + QString args; + f.readLine( args, f.size() ); + QStringList lst = QStringList::split( " ", args ); + + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + QString arg = (*it).stripWhiteSpace(); + if ( arg[0] != '-' ) { + QObjectList* l = MainWindow::self->queryList( "FormWindow" ); + FormWindow* fw = (FormWindow*) l->first(); + FormWindow* totop = 0; + bool haveit = FALSE; + while ( fw ) { + haveit = haveit || fw->fileName() == arg; + if ( haveit ) + totop = fw; + + fw = (FormWindow*) l->next(); + } + + if ( !haveit ) { + FlashWindow( MainWindow::self->winId(), TRUE ); + MainWindow::self->openFormWindow( arg ); + } else if ( totop ) { + totop->setFocus(); + } + delete l; + } + } + return TRUE; + } + return QApplication::winEventFilter( msg ); +} +#endif diff --git a/tools/designer/designer/designerapp.h b/tools/designer/designer/designerapp.h new file mode 100644 index 0000000..e59b5b9 --- /dev/null +++ b/tools/designer/designer/designerapp.h @@ -0,0 +1,65 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DESIGNERAPP_H +#define DESIGNERAPP_H + +class QSplashScreen; + +#include + +class DesignerApplication : public QApplication +{ +public: + const char *className() const { return "DesignerApplication"; } + + DesignerApplication( int &argc, char **argv ); + + QSplashScreen *showSplash(); + static void closeSplash(); + + static QString settingsKey(); + static QString oldSettingsKey(); + static void setSettingsKey( const QString &key ); + +protected: + QDateTime lastMod; + +#if defined(Q_WS_WIN) + bool winEventFilter( MSG *msg ); + uint DESIGNER_OPENFILE; +#endif + +}; + +#endif diff --git a/tools/designer/designer/designerappiface.cpp b/tools/designer/designer/designerappiface.cpp new file mode 100644 index 0000000..770d39d --- /dev/null +++ b/tools/designer/designer/designerappiface.cpp @@ -0,0 +1,1100 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include "designerappiface.h" +#include "mainwindow.h" +#include "project.h" +#include "formwindow.h" +#include "workspace.h" +#include "widgetfactory.h" +#include "command.h" +#include "outputwindow.h" +#include "../shared/widgetdatabase.h" +#include +#include +#include +#include +#include "pixmapcollection.h" +#include "hierarchyview.h" +#include +#include +#include "popupmenueditor.h" +#include "menubareditor.h" + +DesignerInterfaceImpl::DesignerInterfaceImpl( MainWindow *mw ) + : mainWindow( mw ) +{ +} + +QRESULT DesignerInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + *iface = 0; + + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_QComponentInformation ) + *iface = (QComponentInformationInterface*)this; + else if ( uuid == IID_Designer ) + *iface = (DesignerInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + + +DesignerProject *DesignerInterfaceImpl::currentProject() const +{ + return mainWindow->currProject()->iFace(); +} + +DesignerFormWindow *DesignerInterfaceImpl::currentForm() const +{ + if ( mainWindow->formWindow() ) + return mainWindow->formWindow()->iFace(); + return 0; +} + +DesignerSourceFile *DesignerInterfaceImpl::currentSourceFile() const +{ + if ( mainWindow->sourceFile() ) + return mainWindow->sourceFile()->iFace(); + return 0; +} + +QPtrList DesignerInterfaceImpl::projectList() const +{ + return mainWindow->projectList(); +} + +void DesignerInterfaceImpl::showStatusMessage( const QString &text, int ms ) const +{ + if ( text.isEmpty() ) { + mainWindow->statusBar()->clear(); + return; + } + if ( ms ) + mainWindow->statusBar()->message( text, ms ); + else + mainWindow->statusBar()->message( text ); +} + +DesignerDock *DesignerInterfaceImpl::createDock() const +{ + return 0; +} + +DesignerOutputDock *DesignerInterfaceImpl::outputDock() const +{ + return mainWindow->outputWindow() ? mainWindow->outputWindow()->iFace() : 0; +} + +void DesignerInterfaceImpl::setModified( bool b, QWidget *window ) +{ + mainWindow->setModified( b, window ); +} + +void DesignerInterfaceImpl::updateFunctionList() +{ + mainWindow->updateFunctionList(); + if ( mainWindow->objectHierarchy()->sourceEditor() ) + mainWindow->objectHierarchy()->updateClassBrowsers(); +} + +void DesignerInterfaceImpl::onProjectChange( QObject *receiver, const char *slot ) +{ + QObject::connect( mainWindow, SIGNAL( projectChanged() ), receiver, slot ); +} + +void DesignerInterfaceImpl::onFormChange( QObject *receiver, const char *slot ) +{ + QObject::connect( mainWindow, SIGNAL( formWindowChanged() ), receiver, slot ); + QObject::connect( mainWindow, SIGNAL( editorChanged() ), receiver, slot ); +} + +bool DesignerInterfaceImpl::singleProjectMode() const +{ + return mainWindow->singleProjectMode(); +} + +void DesignerInterfaceImpl::showError( QWidget *widget, + int line, const QString &message ) +{ + mainWindow->showErrorMessage( widget, line, message ); +} + +void DesignerInterfaceImpl::runFinished() +{ + mainWindow->finishedRun(); +} + +void DesignerInterfaceImpl::showStackFrame( QWidget *w, int line ) +{ + mainWindow->showStackFrame( w, line ); +} + +void DesignerInterfaceImpl::showDebugStep( QWidget *w, int line ) +{ + mainWindow->showDebugStep( w, line ); +} + +void DesignerInterfaceImpl::runProjectPrecondition() +{ + mainWindow->runProjectPrecondition(); +} + +void DesignerInterfaceImpl::runProjectPostcondition( QObjectList *l ) +{ + mainWindow->runProjectPostcondition( l ); +} + +DesignerProjectImpl::DesignerProjectImpl( Project *pr ) + : project( pr ) +{ +} + +QPtrList DesignerProjectImpl::formList() const +{ + QPtrList list; + QObjectList *forms = project->formList(); + if ( !forms ) + return list; + + QPtrListIterator it( *forms ); + while ( it.current() ) { + QObject *obj = it.current(); + ++it; + QWidget *par = ::qt_cast(obj->parent()); + if ( !obj->isWidgetType() || !par ) + continue; + + list.append( ((FormWindow*)par)->iFace() ); + } + + delete forms; + return list; +} + +QString DesignerProjectImpl::formFileName( const QString &form ) const +{ + for ( QPtrListIterator forms = project->formFiles(); + forms.current(); ++forms ) { + if ( QString( forms.current()->formName() ) == form ) + return forms.current()->fileName(); + } + return QString::null; +} + +QStringList DesignerProjectImpl::formNames() const +{ + QStringList l; + for ( QPtrListIterator forms = project->formFiles(); + forms.current(); ++forms ) { + FormFile* f = forms.current(); + if ( f->isFake() ) + continue; + l << f->formName(); + } + return l; +} + +void DesignerProjectImpl::addForm( DesignerFormWindow * ) +{ +} + +void DesignerProjectImpl::removeForm( DesignerFormWindow * ) +{ +} + +QString DesignerProjectImpl::fileName() const +{ + return project->fileName(); +} + +void DesignerProjectImpl::setFileName( const QString & ) +{ +} + +QString DesignerProjectImpl::projectName() const +{ + return project->projectName(); +} + +void DesignerProjectImpl::setProjectName( const QString & ) +{ +} + +QString DesignerProjectImpl::databaseFile() const +{ + return QString::null; +} + +void DesignerProjectImpl::setDatabaseFile( const QString & ) +{ +} + +void DesignerProjectImpl::setupDatabases() const +{ + MainWindow::self->editDatabaseConnections(); +} + +QPtrList DesignerProjectImpl::databaseConnections() const +{ + QPtrList lst; +#ifndef QT_NO_SQL + QPtrList conns = project->databaseConnections(); + for ( DatabaseConnection *d = conns.first(); d; d = conns.next() ) + lst.append( d->iFace() ); +#endif + return lst; +} + +void DesignerProjectImpl::addDatabase( DesignerDatabase * ) +{ +} + +void DesignerProjectImpl::removeDatabase( DesignerDatabase * ) +{ +} + +void DesignerProjectImpl::save() const +{ +} + +void DesignerProjectImpl::setLanguage( const QString &l ) +{ + project->setLanguage( l ); +} + +QString DesignerProjectImpl::language() const +{ + return project->language(); +} + +void DesignerProjectImpl::setCustomSetting( const QString &key, const QString &value ) +{ + project->setCustomSetting( key, value ); +} + +QString DesignerProjectImpl::customSetting( const QString &key ) const +{ + if ( key == "QTSCRIPT_PACKAGES" ) { + QString s = getenv( "QTSCRIPT_PACKAGES" ); + QString s2 = project->customSetting( "QUICK_PACKAGES" ); + if ( !s.isEmpty() && !s2.isEmpty() ) +#if defined(Q_OS_WIN32) + s += ";"; +#else + s += ":"; +#endif + s += s2; + return s; + } + return project->customSetting( key ); +} + +DesignerPixmapCollection *DesignerProjectImpl::pixmapCollection() const +{ + return project->pixmapCollection()->iFace(); +} + +void DesignerProjectImpl::breakPoints( QMap > &bps ) const +{ + MainWindow::self->saveAllBreakPoints(); + for ( QPtrListIterator sources = project->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + bps.insert( project->makeRelative( f->fileName() ) + " ", MetaDataBase::breakPoints( f ) ); + } + for ( QPtrListIterator forms = project->formFiles(); + forms.current(); ++forms ) { + if ( forms.current()->formWindow() ) + bps.insert( QString( forms.current()->formWindow()->name() ) + "
", MetaDataBase::breakPoints( forms.current()->formWindow() ) ); + } +} + +QString DesignerProjectImpl::breakPointCondition( QObject *o, int line ) const +{ + return MetaDataBase::breakPointCondition( MainWindow::self->findRealObject( o ), line ); +} + +void DesignerProjectImpl::setBreakPointCondition( QObject *o, int line, const QString &condition ) +{ + MetaDataBase::setBreakPointCondition( MainWindow::self->findRealObject( o ), line, condition ); +} + +void DesignerProjectImpl::clearAllBreakpoints() const +{ + QValueList empty; + for ( QPtrListIterator sources = project->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + MetaDataBase::setBreakPoints( f, empty ); + } + for ( QPtrListIterator forms = project->formFiles(); + forms.current(); ++forms ) { + if ( forms.current()->formWindow() ) + MetaDataBase::setBreakPoints( forms.current()->formWindow(), empty ); + MainWindow::self->resetBreakPoints(); + } +} + +void DesignerProjectImpl::setIncludePath( const QString &platform, const QString &path ) +{ + project->setIncludePath( platform, path ); +} + +void DesignerProjectImpl::setLibs( const QString &platform, const QString &path ) +{ + project->setLibs( platform, path ); +} + +void DesignerProjectImpl::setDefines( const QString &platform, const QString &path ) +{ + project->setDefines( platform, path ); +} + +void DesignerProjectImpl::setConfig( const QString &platform, const QString &config ) +{ + project->setConfig( platform, config ); +} + +void DesignerProjectImpl::setTemplate( const QString &t ) +{ + project->setTemplate( t ); +} + +QString DesignerProjectImpl::config( const QString &platform ) const +{ + return project->config( platform ); +} + +QString DesignerProjectImpl::libs( const QString &platform ) const +{ + return project->libs( platform ); +} + +QString DesignerProjectImpl::defines( const QString &platform ) const +{ + return project->defines( platform ); +} + +QString DesignerProjectImpl::includePath( const QString &platform ) const +{ + return project->includePath( platform ); +} + +QString DesignerProjectImpl::templte() const +{ + return project->templte(); +} + +bool DesignerProjectImpl::isGenericObject( QObject *o ) const +{ + return !!project->fakeFormFileFor( o ); +} + + + + + + + +#ifndef QT_NO_SQL +DesignerDatabaseImpl::DesignerDatabaseImpl( DatabaseConnection *d ) + : db( d ) +{ +} + +QString DesignerDatabaseImpl::name() const +{ + return db->name(); +} + +void DesignerDatabaseImpl::setName( const QString & ) +{ +} + +QString DesignerDatabaseImpl::driver() const +{ + return db->driver(); +} + +void DesignerDatabaseImpl::setDriver( const QString & ) +{ +} + +QString DesignerDatabaseImpl::database() const +{ + return db->database(); +} + +void DesignerDatabaseImpl::setDatabase( const QString & ) +{ +} + +QString DesignerDatabaseImpl::userName() const +{ + return db->username(); +} + +void DesignerDatabaseImpl::setUserName( const QString & ) +{ +} + +QString DesignerDatabaseImpl::password() const +{ + return db->password(); +} + +void DesignerDatabaseImpl::setPassword( const QString & ) +{ +} + +QString DesignerDatabaseImpl::hostName() const +{ + return db->hostname(); +} + +void DesignerDatabaseImpl::setHostName( const QString & ) +{ +} + +QStringList DesignerDatabaseImpl::tables() const +{ + return db->tables(); +} + +QMap DesignerDatabaseImpl::fields() const +{ + return db->fields(); +} + +void DesignerDatabaseImpl::open( bool suppressDialog ) const +{ + db->open( suppressDialog ); +} + +void DesignerDatabaseImpl::close() const +{ + db->close(); +} + +void DesignerDatabaseImpl::setFields( const QMap & ) +{ +} + +void DesignerDatabaseImpl::setTables( const QStringList & ) +{ +} + +QSqlDatabase* DesignerDatabaseImpl::connection() +{ + return db->connection(); +} +#endif + + + +DesignerPixmapCollectionImpl::DesignerPixmapCollectionImpl( PixmapCollection *coll ) + : pixCollection( coll ) +{ +} + +void DesignerPixmapCollectionImpl::addPixmap( const QPixmap &p, const QString &name, bool force ) +{ + PixmapCollection::Pixmap pix; + pix.pix = p; + pix.name = name; + pixCollection->addPixmap( pix, force ); + FormWindow *fw = MainWindow::self->formWindow(); + if ( fw ) + MetaDataBase::setPixmapKey( fw, p.serialNumber(), name ); +} + +QPixmap DesignerPixmapCollectionImpl::pixmap( const QString &name ) const +{ + return pixCollection->pixmap( name ); +} + + + +DesignerFormWindowImpl::DesignerFormWindowImpl( FormWindow *fw ) + : formWindow( fw ) +{ +} + +QString DesignerFormWindowImpl::name() const +{ + return formWindow->name(); + } + +void DesignerFormWindowImpl::setName( const QString &n ) +{ + formWindow->setName( n ); +} + +QString DesignerFormWindowImpl::fileName() const +{ + return formWindow->fileName(); +} + +void DesignerFormWindowImpl::setFileName( const QString & ) +{ +} + +void DesignerFormWindowImpl::save() const +{ +} + +bool DesignerFormWindowImpl::isModified() const +{ + return formWindow->commandHistory()->isModified(); +} + +void DesignerFormWindowImpl::insertWidget( QWidget * ) +{ +} + +QWidget *DesignerFormWindowImpl::create( const char *className, QWidget *parent, const char *name ) +{ + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( className ), parent, name ); + formWindow->insertWidget( w, TRUE ); + formWindow->killAccels( formWindow->mainContainer() ); + return w; +} + +void DesignerFormWindowImpl::removeWidget( QWidget * ) +{ +} + +QWidgetList DesignerFormWindowImpl::widgets() const +{ + return QWidgetList(); +} + +void DesignerFormWindowImpl::undo() +{ +} + +void DesignerFormWindowImpl::redo() +{ +} + +void DesignerFormWindowImpl::cut() +{ +} + +void DesignerFormWindowImpl::copy() +{ +} + +void DesignerFormWindowImpl::paste() +{ +} + +void DesignerFormWindowImpl::adjustSize() +{ +} + +void DesignerFormWindowImpl::editConnections() +{ +} + +void DesignerFormWindowImpl::checkAccels() +{ +} + +void DesignerFormWindowImpl::layoutH() +{ + formWindow->layoutHorizontal(); +} + +void DesignerFormWindowImpl::layoutV() +{ +} + +void DesignerFormWindowImpl::layoutHSplit() +{ +} + +void DesignerFormWindowImpl::layoutVSplit() +{ +} + +void DesignerFormWindowImpl::layoutG() +{ + formWindow->layoutGrid(); +} + +void DesignerFormWindowImpl::layoutHContainer( QWidget* w ) +{ + formWindow->layoutHorizontalContainer( w ); +} + +void DesignerFormWindowImpl::layoutVContainer( QWidget* w ) +{ + formWindow->layoutVerticalContainer( w ); +} + +void DesignerFormWindowImpl::layoutGContainer( QWidget* w ) +{ + formWindow->layoutGridContainer( w ); +} + +void DesignerFormWindowImpl::breakLayout() +{ +} + +void DesignerFormWindowImpl::selectWidget( QWidget * w ) +{ + formWindow->selectWidget( w, TRUE ); +} + +void DesignerFormWindowImpl::selectAll() +{ +} + +void DesignerFormWindowImpl::clearSelection() +{ + formWindow->clearSelection(); +} + +bool DesignerFormWindowImpl::isWidgetSelected( QWidget * ) const +{ + return FALSE; +} + +QWidgetList DesignerFormWindowImpl::selectedWidgets() const +{ + return formWindow->selectedWidgets(); +} + +QWidget *DesignerFormWindowImpl::currentWidget() const +{ + return formWindow->currentWidget(); +} + +QWidget *DesignerFormWindowImpl::form() const +{ + return formWindow; +} + + +void DesignerFormWindowImpl::setCurrentWidget( QWidget * ) +{ +} + +QPtrList DesignerFormWindowImpl::actionList() const +{ + return QPtrList(); +} + +QAction *DesignerFormWindowImpl::createAction( const QString& text, const QIconSet& icon, const QString& menuText, int accel, + QObject* parent, const char* name, bool toggle ) +{ + QDesignerAction *a = new QDesignerAction( parent ); + a->setName( name ); + a->setText( text ); + if ( !icon.isNull() && !icon.pixmap().isNull() ) + a->setIconSet( icon ); + a->setMenuText( menuText ); + a->setAccel( accel ); + a->setToggleAction( toggle ); + return a; +} + +void DesignerFormWindowImpl::addAction( QAction *a ) +{ + if ( formWindow->actionList().findRef( a ) != -1 ) + return; + formWindow->actionList().append( a ); + MetaDataBase::addEntry( a ); + setPropertyChanged( a, "name", TRUE ); + setPropertyChanged( a, "text", TRUE ); + setPropertyChanged( a, "menuText", TRUE ); + setPropertyChanged( a, "accel", TRUE ); + if ( !a->iconSet().isNull() && !a->iconSet().pixmap().isNull() ) + setPropertyChanged( a, "iconSet", TRUE ); +} + +void DesignerFormWindowImpl::removeAction( QAction *a ) +{ + formWindow->actionList().removeRef( a ); +} + +void DesignerFormWindowImpl::preview() const +{ +} + +void DesignerFormWindowImpl::addConnection( QObject *sender, const char *signal, QObject *receiver, const char *slot ) +{ + MetaDataBase::addConnection( formWindow, sender, signal, receiver, slot ); +} + +void DesignerFormWindowImpl::addFunction( const QCString &function, const QString &specifier, + const QString &access, const QString &type, + const QString &language, const QString &returnType ) +{ + MetaDataBase::addFunction( formWindow, function, specifier, access, type, language, returnType ); + formWindow->mainWindow()->functionsChanged(); +} + + + +void DesignerFormWindowImpl::setProperty( QObject *o, const char *property, const QVariant &value ) +{ + int id = o->metaObject()->findProperty( property, TRUE ); + const QMetaProperty* p = o->metaObject()->property( id, TRUE ); + if ( p && p->isValid() ) + o->setProperty( property, value ); + else + MetaDataBase::setFakeProperty( o, property, value ); +} + +QVariant DesignerFormWindowImpl::property( QObject *o, const char *prop ) const +{ + int id = o->metaObject()->findProperty( prop, TRUE ); + const QMetaProperty* p = o->metaObject()->property( id, TRUE ); + if ( p && p->isValid() ) + return o->property( prop ); + return MetaDataBase::fakeProperty( o, prop ); +} + +void DesignerFormWindowImpl::setPropertyChanged( QObject *o, const char *property, bool changed ) +{ + MetaDataBase::setPropertyChanged( o, property, changed ); +} + +bool DesignerFormWindowImpl::isPropertyChanged( QObject *o, const char *property ) const +{ + return MetaDataBase::isPropertyChanged( o, property ); +} + +void DesignerFormWindowImpl::setColumnFields( QObject *o, const QMap &f ) +{ + MetaDataBase::setColumnFields( o, f ); +} + +QStringList DesignerFormWindowImpl::implementationIncludes() const +{ + QValueList includes = MetaDataBase::includes( formWindow ); + QStringList lst; + for ( QValueList::Iterator it = includes.begin(); it != includes.end(); ++it ) { + MetaDataBase::Include inc = *it; + if ( inc.implDecl != "in implementation" ) + continue; + QString s = inc.header; + if ( inc.location == "global" ) { + s.prepend( "<" ); + s.append( ">" ); + } else { + s.prepend( "\"" ); + s.append( "\"" ); + } + lst << s; + } + return lst; +} + +QStringList DesignerFormWindowImpl::declarationIncludes() const +{ + QValueList includes = MetaDataBase::includes( formWindow ); + QStringList lst; + for ( QValueList::Iterator it = includes.begin(); it != includes.end(); ++it ) { + MetaDataBase::Include inc = *it; + if ( inc.implDecl == "in implementation" ) + continue; + QString s = inc.header; + if ( inc.location == "global" ) { + s.prepend( "<" ); + s.append( ">" ); + } else { + s.prepend( "\"" ); + s.append( "\"" ); + } + lst << s; + } + return lst; +} + +void DesignerFormWindowImpl::setImplementationIncludes( const QStringList &lst ) +{ + QValueList oldIncludes = MetaDataBase::includes( formWindow ); + QValueList includes; + for ( QValueList::Iterator it = oldIncludes.begin(); it != oldIncludes.end(); ++it ) { + MetaDataBase::Include inc = *it; + if ( inc.implDecl == "in implementation" ) + continue; + includes << inc; + } + + for ( QStringList::ConstIterator sit = lst.begin(); sit != lst.end(); ++sit ) { + QString s = *sit; + if ( s.startsWith( "#include" ) ) + s.remove( (uint)0, 8 ); + s = s.simplifyWhiteSpace(); + if ( s[ 0 ] != '<' && s[ 0 ] != '"' ) { + s.prepend( "\"" ); + s.append( "\"" ); + } + if ( s[ 0 ] == '<' ) { + s.remove( (uint)0, 1 ); + s.remove( s.length() - 1, 1 ); + MetaDataBase::Include inc; + inc.header = s; + inc.implDecl = "in implementation"; + inc.location = "global"; + includes << inc; + } else { + s.remove( (uint)0, 1 ); + s.remove( s.length() - 1, 1 ); + MetaDataBase::Include inc; + inc.header = s; + inc.implDecl = "in implementation"; + inc.location = "local"; + includes << inc; + } + } + MetaDataBase::setIncludes( formWindow, includes ); + formWindow->mainWindow()->objectHierarchy()->formDefinitionView()->setup(); +} + +void DesignerFormWindowImpl::setDeclarationIncludes( const QStringList &lst ) +{ + QValueList oldIncludes = MetaDataBase::includes( formWindow ); + QValueList includes; + for ( QValueList::Iterator it = oldIncludes.begin(); it != oldIncludes.end(); ++it ) { + MetaDataBase::Include inc = *it; + if ( inc.implDecl == "in declaration" ) + continue; + includes << inc; + } + + for ( QStringList::ConstIterator sit = lst.begin(); sit != lst.end(); ++sit ) { + QString s = *sit; + if ( s.startsWith( "#include" ) ) + s.remove( (uint)0, 8 ); + s = s.simplifyWhiteSpace(); + if ( s[ 0 ] != '<' && s[ 0 ] != '"' ) { + s.prepend( "\"" ); + s.append( "\"" ); + } + if ( s[ 0 ] == '<' ) { + s.remove( (uint)0, 1 ); + s.remove( s.length() - 1, 1 ); + MetaDataBase::Include inc; + inc.header = s; + inc.implDecl = "in declaration"; + inc.location = "global"; + includes << inc; + } else { + s.remove( (uint)0, 1 ); + s.remove( s.length() - 1, 1 ); + MetaDataBase::Include inc; + inc.header = s; + inc.implDecl = "in declaration"; + inc.location = "local"; + includes << inc; + } + } + MetaDataBase::setIncludes( formWindow, includes ); + formWindow->mainWindow()->objectHierarchy()->formDefinitionView()->setup(); +} + +QStringList DesignerFormWindowImpl::forwardDeclarations() const +{ + return MetaDataBase::forwards( formWindow ); +} + +void DesignerFormWindowImpl::setForwardDeclarations( const QStringList &lst ) +{ + MetaDataBase::setForwards( formWindow, lst ); + formWindow->mainWindow()->objectHierarchy()->formDefinitionView()->setup(); +} + +QStringList DesignerFormWindowImpl::signalList() const +{ + return MetaDataBase::signalList( formWindow ); +} + +void DesignerFormWindowImpl::setSignalList( const QStringList &lst ) +{ + MetaDataBase::setSignalList( formWindow, lst ); + formWindow->mainWindow()->objectHierarchy()->formDefinitionView()->setup(); +} + +void DesignerFormWindowImpl::onModificationChange( QObject *receiver, const char *slot ) +{ + QObject::connect( formWindow, SIGNAL( modificationChanged( bool, FormWindow * ) ), receiver, slot ); +} + +void DesignerFormWindowImpl::addMenu( const QString &text, const QString &name ) +{ + if ( !::qt_cast(formWindow->mainContainer()) ) + return; + + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + PopupMenuEditor *popup = new PopupMenuEditor( formWindow, mw ); + QString n = name; + formWindow->unify( popup, n, TRUE ); + popup->setName( n ); + MenuBarEditor *mb = (MenuBarEditor *)mw->child( 0, "MenuBarEditor" ); + if ( !mb ) { + mb = new MenuBarEditor( formWindow, mw ); + mb->setName( "MenuBar" ); + MetaDataBase::addEntry( mb ); + } + mb->insertItem( text, popup ); + MetaDataBase::addEntry( popup ); +} + +void DesignerFormWindowImpl::addMenuAction( const QString &menu, QAction *a ) +{ + if ( !::qt_cast(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + if ( !mw->child( 0, "MenuBarEditor" ) ) + return; + PopupMenuEditor *popup = (PopupMenuEditor*)mw->child( menu, "PopupMenuEditor" ); + if ( !popup ) + return; + popup->insert( a ); +} + +void DesignerFormWindowImpl::addMenuSeparator( const QString &menu ) +{ + if ( !::qt_cast(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + if ( !mw->child( 0, "MenuBarEditor" ) ) + return; + PopupMenuEditor *popup = (PopupMenuEditor*)mw->child( menu, "PopupMenuEditor" ); + if ( !popup ) + return; + QAction *a = new QSeparatorAction( 0 ); + popup->insert( a ); +} + +void DesignerFormWindowImpl::addToolBar( const QString &text, const QString &name ) +{ + if ( !::qt_cast(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + QToolBar *tb = new QDesignerToolBar( mw ); + QString n = name; + formWindow->unify( tb, n, TRUE ); + tb->setName( n ); + mw->addToolBar( tb, text ); +} + +void DesignerFormWindowImpl::addToolBarAction( const QString &tbn, QAction *a ) +{ + if ( !::qt_cast(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + QDesignerToolBar *tb = (QDesignerToolBar*)mw->child( tbn, "QDesignerToolBar" ); + if ( !tb ) + return; + a->addTo( tb ); + tb->addAction( a ); +} + +void DesignerFormWindowImpl::addToolBarSeparator( const QString &tbn ) +{ + if ( !::qt_cast(formWindow->mainContainer()) ) + return; + QMainWindow *mw = (QMainWindow*)formWindow->mainContainer(); + QDesignerToolBar *tb = (QDesignerToolBar*)mw->child( tbn, "QDesignerToolBar" ); + if ( !tb ) + return; + QAction *a = new QSeparatorAction( 0 ); + a->addTo( tb ); + tb->addAction( a ); +} + +DesignerDockImpl::DesignerDockImpl() +{ +} + +QDockWindow *DesignerDockImpl::dockWindow() const +{ + return 0; +} + +DesignerOutputDockImpl::DesignerOutputDockImpl( OutputWindow *ow ) + : outWin( ow ) +{ +} + +QWidget *DesignerOutputDockImpl::addView( const QString &title ) +{ + QWidget *page = new QWidget( outWin ); + outWin->addTab( page, title ); + return page; +} + +void DesignerOutputDockImpl::appendDebug( const QString &s ) +{ + outWin->appendDebug( s ); +} + +void DesignerOutputDockImpl::clearDebug() +{ +} + +void DesignerOutputDockImpl::appendError( const QString &s, int l ) +{ + QStringList ls; + ls << s; + QValueList ll; + ll << l; + outWin->setErrorMessages( ls, ll, FALSE, QStringList(), QObjectList() ); +} + +void DesignerOutputDockImpl::clearError() +{ +} + +DesignerSourceFileImpl::DesignerSourceFileImpl( SourceFile *e ) + : ed( e ) +{ +} + +QString DesignerSourceFileImpl::fileName() const +{ + return ed->fileName(); +} diff --git a/tools/designer/designer/designerappiface.h b/tools/designer/designer/designerappiface.h new file mode 100644 index 0000000..91c29a5 --- /dev/null +++ b/tools/designer/designer/designerappiface.h @@ -0,0 +1,284 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DESIGNERAPPIFACE_H +#define DESIGNERAPPIFACE_H + +#include "../interfaces/designerinterface.h" +#include "project.h" + +class FormWindow; +class MainWindow; +class Project; +class OutputWindow; +class SourceFile; + +class DesignerInterfaceImpl : public DesignerInterface +{ +public: + DesignerInterfaceImpl( MainWindow *mw ); + + DesignerProject *currentProject() const; + DesignerFormWindow *currentForm() const; + DesignerSourceFile *currentSourceFile() const; + QPtrList projectList() const; + void showStatusMessage( const QString &, int ms = 0 ) const; + DesignerDock *createDock() const; + DesignerOutputDock *outputDock() const; + void setModified( bool b, QWidget *window ); + void updateFunctionList(); + + void onProjectChange( QObject *receiver, const char *slot ); + void onFormChange( QObject *receiver, const char *slot ); + + bool singleProjectMode() const; + void showError( QWidget *widget, int line, const QString &message ); + void runFinished(); + void showStackFrame( QWidget *w, int line ); + void showDebugStep( QWidget *w, int line ); + void runProjectPrecondition(); + void runProjectPostcondition( QObjectList *l ); + + + QRESULT queryInterface( const QUuid &uuid, QUnknownInterface** iface ); + Q_REFCOUNT + +private: + MainWindow *mainWindow; + +}; + +class DesignerProjectImpl: public DesignerProject +{ +public: + DesignerProjectImpl( Project *pr ); + + QPtrList formList() const; + QStringList formNames() const; + QString formFileName( const QString &form ) const; + void addForm( DesignerFormWindow * ); + void removeForm( DesignerFormWindow * ); + QString fileName() const; + void setFileName( const QString & ); + QString projectName() const; + void setProjectName( const QString & ); + QString databaseFile() const; + void setDatabaseFile( const QString & ); + void setupDatabases() const; + QPtrList databaseConnections() const; + void addDatabase( DesignerDatabase * ); + void removeDatabase( DesignerDatabase * ); + void save() const; + void setLanguage( const QString & ); + QString language() const; + void setCustomSetting( const QString &key, const QString &value ); + QString customSetting( const QString &key ) const; + DesignerPixmapCollection *pixmapCollection() const; + void breakPoints( QMap > &bps ) const; + QString breakPointCondition( QObject *o, int line ) const; + void setBreakPointCondition( QObject *o, int line, const QString &condition ); + void clearAllBreakpoints() const; + void setIncludePath( const QString &platform, const QString &path ); + void setLibs( const QString &platform, const QString &path ); + void setDefines( const QString &platform, const QString &path ); + void setConfig( const QString &platform, const QString &config ); + void setTemplate( const QString &t ); + QString config( const QString &platform ) const; + QString libs( const QString &platform ) const; + QString defines( const QString &platform ) const; + QString includePath( const QString &platform ) const; + QString templte() const; + bool isGenericObject( QObject *o ) const; + +private: + Project *project; + +}; + +#ifndef QT_NO_SQL +class QSqlDatabase; + +class DesignerDatabaseImpl: public DesignerDatabase +{ +public: + DesignerDatabaseImpl( DatabaseConnection *d ); + + QString name() const; + void setName( const QString & ); + QString driver() const; + void setDriver( const QString & ); + QString database() const; + void setDatabase( const QString & ); + QString userName() const; + void setUserName( const QString & ); + QString password() const; + void setPassword( const QString & ); + QString hostName() const; + void setHostName( const QString & ); + QStringList tables() const; + void setTables( const QStringList & ); + QMap fields() const; + void setFields( const QMap & ); + void open( bool suppressDialog = TRUE ) const; + void close() const; + QSqlDatabase* connection(); +private: + DatabaseConnection *db; + +}; +#endif + +class DesignerPixmapCollectionImpl : public DesignerPixmapCollection +{ +public: + DesignerPixmapCollectionImpl( PixmapCollection *coll ); + void addPixmap( const QPixmap &p, const QString &name, bool force ); + QPixmap pixmap( const QString &name ) const; + +private: + PixmapCollection *pixCollection; + +}; + +class DesignerFormWindowImpl: public DesignerFormWindow +{ +public: + DesignerFormWindowImpl( FormWindow *fw ); + + QString name() const; + void setName( const QString &n ); + QString fileName() const; + void setFileName( const QString & ); + void save() const; + bool isModified() const; + void insertWidget( QWidget * ); + QWidget *create( const char *className, QWidget *parent, const char *name ); + void removeWidget( QWidget * ); + QWidgetList widgets() const; + void undo(); + void redo(); + void cut(); + void copy(); + void paste(); + void adjustSize(); + void editConnections(); + void checkAccels(); + void layoutH(); + void layoutV(); + void layoutHSplit(); + void layoutVSplit(); + void layoutG(); + void layoutHContainer( QWidget* w ); + void layoutVContainer( QWidget* w ); + void layoutGContainer( QWidget* w ); + void breakLayout(); + void selectWidget( QWidget * ); + void selectAll(); + void clearSelection(); + bool isWidgetSelected( QWidget * ) const; + QWidgetList selectedWidgets() const; + QWidget *currentWidget() const; + QWidget *form() const; + void setCurrentWidget( QWidget * ); + QPtrList actionList() const; + QAction *createAction( const QString& text, const QIconSet& icon, const QString& menuText, int accel, + QObject* parent, const char* name = 0, bool toggle = FALSE ); + void addAction( QAction * ); + void removeAction( QAction * ); + void preview() const; + void addFunction( const QCString &function, const QString& specifier, const QString &access, + const QString &type, const QString &language, const QString &returnType ); + void addConnection( QObject *sender, const char *signal, QObject *receiver, const char *slot ); + void setProperty( QObject *o, const char *property, const QVariant &value ); + QVariant property( QObject *o, const char *property ) const; + void setPropertyChanged( QObject *o, const char *property, bool changed ); + bool isPropertyChanged( QObject *o, const char *property ) const; + void setColumnFields( QObject *o, const QMap & ); + QStringList implementationIncludes() const; + QStringList declarationIncludes() const; + void setImplementationIncludes( const QStringList &lst ); + void setDeclarationIncludes( const QStringList &lst ); + QStringList forwardDeclarations() const; + void setForwardDeclarations( const QStringList &lst ); + QStringList signalList() const; + void setSignalList( const QStringList &lst ); + void addMenu( const QString &text, const QString &name ); + void addMenuAction( const QString &menu, QAction *a ); + void addMenuSeparator( const QString &menu ); + void addToolBar( const QString &text, const QString &name ); + void addToolBarAction( const QString &tb, QAction *a ); + void addToolBarSeparator( const QString &tb ); + + void onModificationChange( QObject *receiver, const char *slot ); + +private: + FormWindow *formWindow; + +}; + +class DesignerDockImpl: public DesignerDock +{ +public: + DesignerDockImpl(); + + QDockWindow *dockWindow() const; +}; + +class DesignerOutputDockImpl: public DesignerOutputDock +{ +public: + DesignerOutputDockImpl( OutputWindow *ow ); + + QWidget *addView( const QString &pageName ); + void appendDebug( const QString & ); + void clearDebug(); + void appendError( const QString &, int ); + void clearError(); + +private: + OutputWindow *outWin; + +}; + +class DesignerSourceFileImpl : public DesignerSourceFile +{ +public: + DesignerSourceFileImpl( SourceFile *e ); + QString fileName() const; + +private: + SourceFile *ed; + +}; + +#endif diff --git a/tools/designer/designer/editfunctions.ui b/tools/designer/designer/editfunctions.ui new file mode 100644 index 0000000..74f799c --- /dev/null +++ b/tools/designer/designer/editfunctions.ui @@ -0,0 +1,721 @@ + +EditFunctionsBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + EditFunctionsBase + + + + 0 + 0 + 600 + 371 + + + + Edit Functions + + + true + + + <b>Edit Functions</b><p>Add, edit or delete the current form's slots or functions.</p><p>Click the <b>Add Function</b>-button to create a new function; enter a name, choose an access mode and specify if it should be a slot or normal function.</p><p>Select an entry from the list and click the <b>Delete Function</b>-button to remove a function; in case of a slot all connections using this slot will also be removed.</p> + + + + unnamed + + + 11 + + + 6 + + + + + Function + + + true + + + true + + + + + Return Type + + + true + + + true + + + + + Specifier + + + true + + + true + + + + + Access + + + true + + + true + + + + + Type + + + true + + + true + + + + + In Use + + + true + + + true + + + + functionListView + + + + 7 + 7 + 0 + 0 + + + + StyledPanel + + + Sunken + + + true + + + true + + + <b>This form's functions.</b><p>Select the function you want to change or delete.</p> + + + + + Layout11 + + + + unnamed + + + 6 + + + + showOnlySlots + + + StrongFocus + + + Only d&isplay slots + + + Change displaying mode for functions + + + <b>Check this button if only the slots should be displayed</b><p>Otherwise all functions, i.e. normal C++ functions and slots are displayed.</p> + + + + + + Vertical Spacing1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + addFunction + + + &New Function + + + Add new function + + + <b>Add a new function.</b><p>New functions have a default name and public access.</p> + + + + + deleteFunction + + + &Delete Function + + + Delete function + + + <b>Delete the selected function.</b><p>All connections using this function are also removed.</p> + + + + + + + boxProperties + + + + 5 + 5 + 0 + 0 + + + + Function Properties + + + + unnamed + + + 11 + + + 6 + + + + Layout14 + + + + unnamed + + + 0 + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + Label8 + + + &Function: + + + AlignVCenter|AlignRight + + + functionName + + + + + functionName + + + + 7 + 0 + 0 + 0 + + + + Change function name + + + <b>Change the name of the selected function.</b><p>The name should include the argument list and must be syntactically correct.</p> + + + + + labelType + + + &Return type: + + + AlignVCenter|AlignRight + + + editType + + + + + editType + + + + 5 + 0 + 0 + 0 + + + + Change the return type of the function + + + <b>Change the return type of the selected function.</b><p>Specifiy here the datatype which should be returned by the function.</p> + + + + + + + Spacer6_2 + + + Vertical + + + Fixed + + + + 20 + 16 + + + + + + Layout13 + + + + unnamed + + + 0 + + + + Label9_2 + + + S&pecifier: + + + AlignVCenter|AlignRight + + + functionSpecifier + + + + + + non virtual + + + + + virtual + + + + + pure virtual + + + + + static + + + + functionSpecifier + + + + 1 + 0 + 0 + 0 + + + + Change function access + + + <b>Change the access policy of the function</b><p>All functions are created virtual and should be reimplemented in subclasses.</p> + + + + + TextLabel1 + + + &Access: + + + WordBreak|AlignVCenter|AlignRight + + + functionAccess + + + + + + public + + + + + protected + + + + + private + + + + functionAccess + + + + 1 + 0 + 0 + 0 + + + + Change function access + + + <b>Change the access policy of the function</b><p>All functions are created virtual and should be reimplemented in subclasses.</p> + + + + + TextLabel1_2 + + + &Type: + + + AlignVCenter|AlignRight + + + functionType + + + + + + slot + + + + + function + + + + functionType + + + Change function type + + + <b>Change the type of the function.</b><p>The type specifies if the function is either a slot or a normal C++ function.</p> + + + + + Spacer5 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + helpButton + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okButton + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + cancelButton + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + + + cancelButton + clicked() + EditFunctionsBase + reject() + + + okButton + clicked() + EditFunctionsBase + okClicked() + + + deleteFunction + clicked() + EditFunctionsBase + functionRemove() + + + addFunction + clicked() + EditFunctionsBase + functionAdd() + + + functionName + textChanged(const QString&) + EditFunctionsBase + currentTextChanged(const QString&) + + + functionListView + selectionChanged(QListViewItem*) + EditFunctionsBase + currentItemChanged(QListViewItem*) + + + functionListView + currentChanged(QListViewItem*) + EditFunctionsBase + currentItemChanged(QListViewItem*) + + + editType + textChanged(const QString&) + EditFunctionsBase + currentReturnTypeChanged(const QString&) + + + functionSpecifier + activated(const QString&) + EditFunctionsBase + currentSpecifierChanged(const QString&) + + + functionAccess + activated(const QString&) + EditFunctionsBase + currentAccessChanged(const QString&) + + + functionType + activated(const QString&) + EditFunctionsBase + currentTypeChanged(const QString&) + + + showOnlySlots + toggled(bool) + EditFunctionsBase + displaySlots(bool) + + + + functionName + editType + functionSpecifier + functionAccess + functionType + helpButton + okButton + cancelButton + functionListView + showOnlySlots + addFunction + deleteFunction + + + currentItemChanged( QListViewItem * ) + currentSpecifierChanged( const QString & ) + currentTextChanged( const QString & ) + currentReturnTypeChanged( const QString & ) + destroy() + init() + currentAccessChanged( const QString & ) + currentTypeChanged( const QString & ) + okClicked() + functionAdd() + functionRemove() + displaySlots( bool ) + + + diff --git a/tools/designer/designer/editfunctionsimpl.cpp b/tools/designer/designer/editfunctionsimpl.cpp new file mode 100644 index 0000000..3e0bac4 --- /dev/null +++ b/tools/designer/designer/editfunctionsimpl.cpp @@ -0,0 +1,536 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "editfunctionsimpl.h" +#include "formwindow.h" +#include "metadatabase.h" +#include "asciivalidator.h" +#include "mainwindow.h" +#include "hierarchyview.h" +#include "project.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EditFunctions::EditFunctions( QWidget *parent, FormWindow *fw, bool justSlots ) + : EditFunctionsBase( parent, 0, TRUE ), formWindow( fw ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + id = 0; + functList.clear(); + + QValueList functionList = MetaDataBase::functionList( fw ); + for ( QValueList::Iterator it = functionList.begin(); it != functionList.end(); ++it ) { + QListViewItem *i = new QListViewItem( functionListView ); + + i->setPixmap( 0, QPixmap::fromMimeSource( "designer_editslots.png" ) ); + i->setText( 0, (*it).function ); + i->setText( 1, (*it).returnType ); + i->setText( 2, (*it).specifier ); + i->setText( 3, (*it).access ); + i->setText( 4, (*it).type ); + + FunctItem fui; + fui.id = id; + fui.oldName = (*it).function; + fui.newName = fui.oldName; + fui.oldRetTyp = (*it).returnType; + fui.retTyp = fui.oldRetTyp; + fui.oldSpec = (*it).specifier; + fui.spec = fui.oldSpec; + fui.oldAccess = (*it).access; + fui.access = fui.oldAccess; + fui.oldType = (*it).type; + fui.type = fui.oldType; + functList.append( fui ); + + functionIds.insert( i, id ); + id++; + + if ( (*it).type == "slot" ) { + if ( MetaDataBase::isSlotUsed( formWindow, MetaDataBase::normalizeFunction( (*it).function ).latin1() ) ) + i->setText( 5, tr( "Yes" ) ); + else + i->setText( 5, tr( "No" ) ); + } else { + i->setText( 5, "---" ); + } + } + + boxProperties->setEnabled( FALSE ); + functionName->setValidator( new AsciiValidator( TRUE, functionName ) ); + + if ( functionListView->firstChild() ) + functionListView->setCurrentItem( functionListView->firstChild() ); + + showOnlySlots->setChecked( justSlots ); + lastType = "function"; + + // Enable rename for all QListViewItems + QListViewItemIterator lvit = functionListView->firstChild(); + for ( ; *lvit; lvit++ ) + (*lvit)->setRenameEnabled( 0, TRUE ); + + // Connect listview signal to signal-relay + QObject::connect( functionListView, + SIGNAL( itemRenamed( QListViewItem*, int, const QString & ) ), + this, + SLOT( emitItemRenamed(QListViewItem*, int, const QString&) ) ); + + // Connect signal-relay to QLineEdit "functionName" + QObjectList *l = parent->queryList( "QLineEdit", "functionName" ); + QObject *obj; + QObjectListIt itemsLineEditIt( *l ); + while ( (obj = itemsLineEditIt.current()) != 0 ) { + ++itemsLineEditIt; + QObject::connect( this, + SIGNAL( itemRenamed( const QString & ) ), + obj, + SLOT( setText( const QString & ) ) ); + } + delete l; +} + +void EditFunctions::okClicked() +{ + QValueList functionList = MetaDataBase::functionList( formWindow ); + QString n = tr( "Add/Remove functions of '%1'" ).arg( formWindow->name() ); + QPtrList commands; + QValueList::Iterator fit; + if ( !functionList.isEmpty() ) { + for ( fit = functionList.begin(); fit != functionList.end(); ++fit ) { + bool functionFound = FALSE; + QValueList::Iterator it = functList.begin(); + for ( ; it != functList.end(); ++it ) { + if ( MetaDataBase::normalizeFunction( (*it).oldName ) == + MetaDataBase::normalizeFunction( (*fit).function ) ) { + functionFound = TRUE; + break; + } + } + if ( !functionFound ) + commands.append( new RemoveFunctionCommand( tr( "Remove function" ), + formWindow, (*fit).function, (*fit).specifier, + (*fit).access, + (*fit).type, + formWindow->project()->language(), + (*fit).returnType ) ); + } + } + + bool invalidFunctions = FALSE; + QValueList invalidItems; + + if ( !functList.isEmpty() ) { + QStrList lst; + QValueList::Iterator it = functList.begin(); + for ( ; it != functList.end(); ++it ) { + MetaDataBase::Function function; + function.function = (*it).newName; + function.returnType = (*it).retTyp; + function.specifier = (*it).spec; + function.access = (*it).access; + function.type = (*it).type; + function.language = formWindow->project()->language(); + if ( function.returnType.isEmpty() ) + function.returnType = "void"; + QString s = function.function; + s = s.simplifyWhiteSpace(); + bool startNum = s[ 0 ] >= '0' && s[ 0 ] <= '9'; + bool noParens = s.contains( '(' ) != 1 || s.contains( ')' ) != 1; + bool illegalSpace = s.find( ' ' ) != -1 && s.find( ' ' ) < s.find( '(' ); + + if ( startNum || noParens || illegalSpace || lst.find( function.function ) != -1 ) { + invalidFunctions = TRUE; + invalidItems.append( (*it) ); + continue; + } + bool functionFound = FALSE; + for ( fit = functionList.begin(); fit != functionList.end(); ++fit ) { + if ( MetaDataBase::normalizeFunction( (*fit).function ) == + MetaDataBase::normalizeFunction( (*it).oldName ) ) { + functionFound = TRUE; + break; + } + } + if ( !functionFound ) + commands.append( new AddFunctionCommand( tr( "Add function" ), + formWindow, function.function, function.specifier, + function.access, + function.type, formWindow->project()->language(), + function.returnType ) ); + if ( MetaDataBase::normalizeFunction( (*it).newName ) != MetaDataBase::normalizeFunction( (*it).oldName ) || + (*it).spec != (*it).oldSpec || (*it).access != (*it).oldAccess || (*it).type != (*it).oldType || + (*it).retTyp != (*it).oldRetTyp ) { + QString normalizedOldName = MetaDataBase::normalizeFunction( (*it).oldName ); + if ((*it).oldName.endsWith("const")) // make sure we get the 'const' when we remove the old name + normalizedOldName += " const"; + commands.append( new ChangeFunctionAttribCommand( tr( "Change function attributes" ), + formWindow, function, normalizedOldName, + (*it).oldSpec, (*it).oldAccess, (*it).oldType, + formWindow->project()->language(), (*it).oldRetTyp ) ); + } + lst.append( function.function ); + } + } + + if ( invalidFunctions ) { + if ( QMessageBox::information( this, tr( "Edit Functions" ), + tr( "Some syntactically incorrect functions have been defined.\n" + "Remove these functions?" ), tr( "&Yes" ), tr( "&No" ) ) == 0 ) { + QValueList::Iterator it = functList.begin(); + while ( it != functList.end() ) { + bool found = FALSE; + QValueList::Iterator vit = invalidItems.begin(); + for ( ; vit != invalidItems.end(); ++vit ) { + if ( (*vit).newName == (*it).newName ) { + invalidItems.remove( vit ); + found = TRUE; + break; + } + } + if ( found ) { + int delId = (*it).id; + it = functList.remove( it ); + QMap::Iterator fit = functionIds.begin(); + while ( fit != functionIds.end() ) { + if ( *fit == delId ) { + QListViewItem *litem = fit.key(); + functionIds.remove( fit ); + delete litem; + if ( functionListView->currentItem() ) + functionListView->setSelected( functionListView->currentItem(), TRUE ); + currentItemChanged( functionListView->currentItem() ); + break; + } + ++fit; + } + } + else + ++it; + } + if ( functionListView->firstChild() ) { + functionListView->setCurrentItem( functionListView->firstChild() ); + functionListView->setSelected( functionListView->firstChild(), TRUE ); + } + } + formWindow->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + return; + } + + if ( !commands.isEmpty() ) { + MacroCommand *cmd = new MacroCommand( n, formWindow, commands ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + + formWindow->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + accept(); +} + +void EditFunctions::functionAdd( const QString &access, const QString &type ) +{ + QListViewItem *i = new QListViewItem( functionListView ); + i->setPixmap( 0, QPixmap::fromMimeSource( "designer_editslots.png" ) ); + i->setRenameEnabled( 0, TRUE ); + i->setText( 1, "void" ); + i->setText( 2, "virtual" ); + + if ( access.isEmpty() ) + i->setText( 3, "public" ); + else + i->setText( 3, access ); + + if( type.isEmpty() ) { + if ( showOnlySlots->isChecked() ) + i->setText( 4, "slot" ); + else { + i->setText( 4, lastType ); + } + } else { + i->setText( 4, type ); + } + + if ( i->text( 4 ) == "slot" ) { + i->setText( 0, "newSlot()" ); + if ( MetaDataBase::isSlotUsed( formWindow, "newSlot()" ) ) + i->setText( 5, tr( "Yes" ) ); + else + i->setText( 5, tr( "No" ) ); + } else { + i->setText( 0, "newFunction()" ); + i->setText( 5, "---" ); + } + + functionListView->setCurrentItem( i ); + functionListView->setSelected( i, TRUE ); + functionListView->ensureItemVisible( i ); + functionName->setFocus(); + functionName->selectAll(); + + FunctItem fui; + fui.id = id; + fui.oldName = i->text( 0 ); + fui.newName = fui.oldName; + fui.oldRetTyp = i->text( 1 ); + fui.retTyp = fui.oldRetTyp; + fui.oldSpec = i->text ( 2 ); + fui.spec = fui.oldSpec; + fui.oldAccess = i->text( 3 ); + fui.access = fui.oldAccess; + fui.oldType = i->text( 4 ); + fui.type = fui.oldType; + lastType = fui.oldType; + functList.append( fui ); + functionIds.insert( i, id ); + id++; +} + +void EditFunctions::functionRemove() +{ + if ( !functionListView->currentItem() ) + return; + + functionListView->blockSignals( TRUE ); + removedFunctions << MetaDataBase::normalizeFunction( functionListView->currentItem()->text( 0 ) ); + int delId = functionIds[ functionListView->currentItem() ]; + QValueList::Iterator it = functList.begin(); + while ( it != functList.end() ) { + if ( (*it).id == delId ) { + functList.remove( it ); + break; + } + ++it; + } + functionIds.remove( functionListView->currentItem() ); + delete functionListView->currentItem(); + if ( functionListView->currentItem() ) + functionListView->setSelected( functionListView->currentItem(), TRUE ); + functionListView->blockSignals( FALSE ); + currentItemChanged( functionListView->currentItem() ); +} + +void EditFunctions::currentItemChanged( QListViewItem *i ) +{ + functionName->blockSignals( TRUE ); + functionName->setText( "" ); + functionAccess->setCurrentItem( 0 ); + functionName->blockSignals( FALSE ); + + if ( !i ) { + boxProperties->setEnabled( FALSE ); + return; + } + + functionName->blockSignals( TRUE ); + functionName->setText( i->text( 0 ) ); + editType->setText( i->text( 1 ) ); + QString specifier = i->text( 2 ); + QString access = i->text( 3 ); + QString type = i->text( 4 ); + if ( specifier == "pure virtual" ) + functionSpecifier->setCurrentItem( 2 ); + else if ( specifier == "non virtual" ) + functionSpecifier->setCurrentItem( 0 ); + else if ( specifier == "virtual" ) + functionSpecifier->setCurrentItem( 1 ); + else + functionSpecifier->setCurrentItem( 3 ); + if ( access == "private" ) + functionAccess->setCurrentItem( 2 ); + else if ( access == "protected" ) + functionAccess->setCurrentItem( 1 ); + else + functionAccess->setCurrentItem( 0 ); + if ( type == "slot" ) + functionType->setCurrentItem( 0 ); + else + functionType->setCurrentItem( 1 ); + + functionName->blockSignals( FALSE ); + boxProperties->setEnabled( TRUE ); +} + +void EditFunctions::currentTextChanged( const QString &txt ) +{ + if ( !functionListView->currentItem() ) + return; + + changeItem( functionListView->currentItem(), Name, txt ); + functionListView->currentItem()->setText( 0, txt ); + + if ( functionListView->currentItem()->text( 4 ) == "slot" ) { + if ( MetaDataBase::isSlotUsed( formWindow, MetaDataBase::normalizeFunction( txt.latin1() ).latin1() ) ) + functionListView->currentItem()->setText( 5, tr( "Yes" ) ); + else + functionListView->currentItem()->setText( 5, tr( "No" ) ); + } else { + functionListView->currentItem()->setText( 5, "---" ); + } +} + +void EditFunctions::currentSpecifierChanged( const QString& s ) +{ + if ( !functionListView->currentItem() ) + return; + + changeItem( functionListView->currentItem(), Specifier, s ); + functionListView->currentItem()->setText( 2, s ); +} + +void EditFunctions::currentAccessChanged( const QString& a ) +{ + if ( !functionListView->currentItem() ) + return; + changeItem( functionListView->currentItem(), Access, a ); + functionListView->currentItem()->setText( 3, a ); +} + + +void EditFunctions::currentReturnTypeChanged( const QString &type ) +{ + if ( !functionListView->currentItem() ) + return; + changeItem( functionListView->currentItem(), ReturnType, type ); + functionListView->currentItem()->setText( 1, type ); +} + +void EditFunctions::currentTypeChanged( const QString &type ) +{ + if ( !functionListView->currentItem() ) + return; + changeItem( functionListView->currentItem(), Type, type ); + lastType = type; + functionListView->currentItem()->setText( 4, type ); + if ( type == "slot" ) { + if ( MetaDataBase::isSlotUsed( formWindow, + MetaDataBase::normalizeFunction( functionListView->currentItem()->text( 0 ).latin1() ).latin1() ) ) + functionListView->currentItem()->setText( 5, tr( "Yes" ) ); + else + functionListView->currentItem()->setText( 5, tr( "No" ) ); + } else { + functionListView->currentItem()->setText( 5, "---" ); + } +} + +void EditFunctions::changeItem( QListViewItem *item, Attribute a, const QString &nV ) +{ + int itemId; + QMap::Iterator fit = functionIds.find( item ); + if ( fit != functionIds.end() ) + itemId = *fit; + else + return; + + QValueList::Iterator it = functList.begin(); + for ( ; it != functList.end(); ++it ) { + if ( (*it).id == itemId ) { + switch( a ) { + case Name: + (*it).newName = nV; + break; + case Specifier: + (*it).spec = nV; + break; + case Access: + (*it).access = nV; + break; + case ReturnType: + (*it).retTyp = nV; + break; + case Type: + (*it).type = nV; + break; + } + } + } +} + +void EditFunctions::setCurrentFunction( const QString &function ) +{ + QListViewItemIterator it( functionListView ); + while ( it.current() ) { + if ( MetaDataBase::normalizeFunction( it.current()->text( 0 ) ) == function ) { + functionListView->setCurrentItem( it.current() ); + functionListView->setSelected( it.current(), TRUE ); + currentItemChanged( it.current() ); + return; + } + ++it; + } +} + +void EditFunctions::displaySlots( bool justSlots ) +{ + functionIds.clear(); + functionListView->clear(); + for ( QValueList::Iterator it = functList.begin(); it != functList.end(); ++it ) { + if ( (*it).type == "function" && justSlots ) + continue; + QListViewItem *i = new QListViewItem( functionListView ); + functionIds.insert( i, (*it).id ); + i->setPixmap( 0, QPixmap::fromMimeSource( "designer_editslots.png" ) ); + i->setText( 0, (*it).newName ); + i->setText( 1, (*it).retTyp ); + i->setText( 2, (*it).spec ); + i->setText( 3, (*it).access ); + i->setText( 4, (*it).type ); + + if ( (*it).type == "slot" ) { + if ( MetaDataBase::isSlotUsed( formWindow, MetaDataBase::normalizeFunction( (*it).newName ).latin1() ) ) + i->setText( 5, tr( "Yes" ) ); + else + i->setText( 5, tr( "No" ) ); + } else { + i->setText( 5, "---" ); + } + } + + if ( functionListView->firstChild() ) + functionListView->setSelected( functionListView->firstChild(), TRUE ); +} + +void EditFunctions::emitItemRenamed( QListViewItem *, int, const QString & text ) +{ + emit itemRenamed( text ); // Relay signal ( to QLineEdit ) +} diff --git a/tools/designer/designer/editfunctionsimpl.h b/tools/designer/designer/editfunctionsimpl.h new file mode 100644 index 0000000..a51ae24 --- /dev/null +++ b/tools/designer/designer/editfunctionsimpl.h @@ -0,0 +1,101 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef EDITFUNCTIONSIMPL_H +#define EDITFUNCTIONSIMPL_H + +#include "editfunctions.h" +#include "hierarchyview.h" +#include "metadatabase.h" +#include + +class FormWindow; +class QListViewItem; + +class EditFunctions : public EditFunctionsBase +{ + Q_OBJECT + +public: + EditFunctions( QWidget *parent, FormWindow *fw, bool showOnlySlots = FALSE ); + + void setCurrentFunction( const QString &function ); + void functionAdd( const QString &access = QString::null, + const QString &type = QString::null ); + void functionAdd() { functionAdd( "public" ); } + +signals: + void itemRenamed(const QString &); + +protected slots: + void okClicked(); + void functionRemove(); + void currentItemChanged( QListViewItem * ); + void currentTextChanged( const QString &txt ); + void currentSpecifierChanged( const QString &s ); + void currentAccessChanged( const QString &a ); + void currentReturnTypeChanged( const QString &type ); + void currentTypeChanged( const QString &type ); + void displaySlots( bool justSlots ); + void emitItemRenamed( QListViewItem *, int, const QString & ); + +private: + enum Attribute { Name, Specifier, Access, ReturnType, Type }; + struct FunctItem { + int id; + QString oldName; + QString newName; + QString oldRetTyp; + QString retTyp; + QString spec; + QString oldSpec; + QString access; + QString oldAccess; + QString type; + QString oldType; + + Q_DUMMY_COMPARISON_OPERATOR( FunctItem ) + }; + + void changeItem( QListViewItem *item, Attribute a, const QString &nV ); + + FormWindow *formWindow; + QMap functionIds; + QStringList removedFunctions; + QValueList itemList; + QValueList functList; + int id; + QString lastType; +}; + +#endif diff --git a/tools/designer/designer/finddialog.ui b/tools/designer/designer/finddialog.ui new file mode 100644 index 0000000..a5f9ba7 --- /dev/null +++ b/tools/designer/designer/finddialog.ui @@ -0,0 +1,281 @@ + +FindDialog +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + FindDialog + + + + 0 + 0 + 285 + 189 + + + + Find Text + + + + unnamed + + + 11 + + + 6 + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + F&ind: + + + comboFind + + + + + comboFind + + + + 7 + 0 + 0 + 0 + + + + true + + + + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + PushButton1 + + + &Find + + + true + + + + + PushButton2 + + + &Close + + + + + + + ButtonGroup2 + + + Direction + + + + unnamed + + + 11 + + + 6 + + + + radioForward + + + Forwar&d + + + true + + + + + radioBackward + + + Bac&kward + + + + + + + ButtonGroup1 + + + Options + + + + unnamed + + + 11 + + + 6 + + + + checkWords + + + &Whole words only + + + + + checkCase + + + Case &sensitive + + + + + checkBegin + + + Start at &Beginning + + + + + + + + + PushButton1 + clicked() + FindDialog + doFind() + + + PushButton2 + clicked() + FindDialog + reject() + + + + comboFind + checkWords + checkCase + checkBegin + radioForward + radioBackward + PushButton1 + PushButton2 + + + qlineedit.h + ../interfaces/editorinterface.h + finddialog.ui.h + + + struct EditorInterface; + + + EditorInterface *editor; + QObject *formWindow; + + + init() + destroy() + doFind() + setEditor( EditorInterface * e, QObject * fw ) + + + diff --git a/tools/designer/designer/finddialog.ui.h b/tools/designer/designer/finddialog.ui.h new file mode 100644 index 0000000..ed531ec --- /dev/null +++ b/tools/designer/designer/finddialog.ui.h @@ -0,0 +1,68 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +void FindDialog::init() +{ + editor = 0; + formWindow = 0; +} + +void FindDialog::destroy() +{ + if ( editor ) + editor->release(); +} + +void FindDialog::doFind() +{ + if ( !editor ) + return; + + if ( !editor->find( comboFind->currentText(), checkCase->isChecked(), + checkWords->isChecked(), radioForward->isChecked(), !checkBegin->isChecked() ) ) + checkBegin->setChecked( TRUE ); + else + checkBegin->setChecked( FALSE ); + +} + +void FindDialog::setEditor( EditorInterface * e, QObject * fw ) +{ + if ( fw != formWindow ) + checkBegin->setChecked( TRUE ); + formWindow = fw; + if ( editor ) + editor->release(); + editor = e; + editor->addRef(); +} diff --git a/tools/designer/designer/formfile.cpp b/tools/designer/designer/formfile.cpp new file mode 100644 index 0000000..a410f7e --- /dev/null +++ b/tools/designer/designer/formfile.cpp @@ -0,0 +1,924 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "formfile.h" +#include "timestamp.h" +#include "project.h" +#include "formwindow.h" +#include "command.h" +#include "sourceeditor.h" +#include "mainwindow.h" +#include "../interfaces/languageinterface.h" +#include "resource.h" +#include "workspace.h" +#include +#include +#include +#include "propertyeditor.h" +#include +#include +#include "designerappiface.h" +#include + +static QString make_func_pretty( const QString &s ) +{ + QString res = s; + if ( res.find( ")" ) - res.find( "(" ) == 1 ) + return res; + res.replace( "(", "( " ); + res.replace( ")", " )" ); + res.replace( "&", " &" ); + res.replace( "*", " *" ); + res.replace( ",", ", " ); + res.replace( ":", " : " ); + res = res.simplifyWhiteSpace(); + res.replace( " : : ", "::" ); + res.replace( ">>", "> >" ); + return res; +} + +FormFile::FormFile( const QString &fn, bool temp, Project *p, const char *name ) + : filename( fn ), fileNameTemp( temp ), pro( p ), fw( 0 ), ed( 0 ), + timeStamp( 0, fn + codeExtension() ), codeEdited( FALSE ), pkg( FALSE ), + cm( FALSE ), codeFileStat( None ), timeStampUi(0, fn) +{ + MetaDataBase::addEntry( this ); + fake = qstrcmp( name, "qt_fakewindow" ) == 0; + //codeFileStat = FormFile::None; + pro->addFormFile( this ); + loadCode(); + if ( !temp ) + checkFileName( FALSE ); + timeStampUi.update(); +} + +FormFile::~FormFile() +{ + pro->removeFormFile( this ); + if ( formWindow() ) + formWindow()->setFormFile( 0 ); +} + +void FormFile::setFormWindow( FormWindow *f ) +{ + if ( f == fw ) + return; + if ( fw ) + fw->setFormFile( 0 ); + fw = f; + if ( fw ) + fw->setFormFile( this ); + parseCode( cod, FALSE ); + QTimer::singleShot( 0, this, SLOT( notifyFormWindowChange() ) ); +} + +void FormFile::setEditor( SourceEditor *e ) +{ + ed = e; +} + +void FormFile::setFileName( const QString &fn ) +{ + if ( fn == filename ) + return; + if ( fn.isEmpty() ) { + fileNameTemp = TRUE; + if ( filename.find( "unnamed" ) != 0 ) + filename = createUnnamedFileName(); + return; + } else { + fileNameTemp = FALSE; + } + filename = fn; + timeStamp.setFileName( filename + codeExtension() ); + timeStampUi.setFileName( filename ); + cod = ""; + loadCode(); +} + +void FormFile::setCode( const QString &c ) +{ + cod = c; +} + +FormWindow *FormFile::formWindow() const +{ + return fw; +} + +SourceEditor *FormFile::editor() const +{ + return ed; +} + +QString FormFile::fileName() const +{ + return filename; +} + +QString FormFile::absFileName() const +{ + return pro->makeAbsolute( filename ); +} + +QString FormFile::codeFile() const +{ + QString codeExt = codeExtension(); + if ( codeExt.isEmpty() ) + return ""; + return filename + codeExt; +} + +QString FormFile::code() +{ + return cod; +} + +bool FormFile::save( bool withMsgBox, bool ignoreModified ) +{ + if ( fileNameTemp ) + return saveAs(); + if ( !ignoreModified && !isModified() ) + return TRUE; + if ( ed ) + ed->save(); + if (!shouldOverwriteUi()) + return TRUE; + + if ( formWindow() && isModified( WFormWindow ) ) { + if ( withMsgBox ) { + if ( !formWindow()->checkCustomWidgets() ) + return FALSE; + } + + if ( QFile::exists( pro->makeAbsolute( filename ) ) ) { + QString fn( pro->makeAbsolute( filename ) ); +#if defined(Q_OS_WIN32) + fn += ".bak"; +#else + fn += "~"; +#endif + QFile f( pro->makeAbsolute( filename ) ); + if ( f.open( IO_ReadOnly ) ) { + QFile f2( fn ); + if ( f2.open( IO_WriteOnly | IO_Translate ) ) { + QCString data( f.size() ); + f.readBlock( data.data(), f.size() ); + f2.writeBlock( data ); + } else { + QMessageBox::warning( MainWindow::self, "Save", "The file " + + codeFile() + " could not be saved" ); + } + } + } + } + + if ( isModified( WFormCode ) ) { + if ( QFile::exists( pro->makeAbsolute( codeFile() ) ) ) { + QString fn( pro->makeAbsolute( codeFile() ) ); +#if defined(Q_OS_WIN32) + fn += ".bak"; +#else + fn += "~"; +#endif + QFile f( pro->makeAbsolute( codeFile() ) ); + if ( f.open( IO_ReadOnly ) ) { + QFile f2( fn ); + if ( f2.open( IO_WriteOnly | IO_Translate) ) { + QCString data( f.size() ); + f.readBlock( data.data(), f.size() ); + f2.writeBlock( data ); + } else if ( qApp->type() != QApplication::Tty ) { + QMessageBox::warning( MainWindow::self, "Save", "The file " + + codeFile() + " could not be saved" ); + } + } + } + } + + if ( formWindow() ) { + Resource resource( MainWindow::self ); + resource.setWidget( formWindow() ); + bool formCodeOnly = isModified( WFormCode ) && !isModified( WFormWindow ); + if ( !resource.save( pro->makeAbsolute( filename ), formCodeOnly ) ) { + if ( MainWindow::self ) + MainWindow::self->statusBar()->message( tr( "Failed to save file '%1'.").arg( formCodeOnly ? codeFile(): filename ), + 5000 ); + if ( formCodeOnly ) + return FALSE; + return saveAs(); + } + if ( MainWindow::self ) + MainWindow::self->statusBar()->message( tr( "'%1' saved."). + arg( formCodeOnly ? codeFile() : filename ), + 3000 ); + } else { + if ( !Resource::saveFormCode(this, MetaDataBase::languageInterface(pro->language())) ) + return FALSE; + } + timeStamp.update(); + timeStampUi.update(); + setModified( FALSE ); + return TRUE; +} + +bool FormFile::shouldOverwriteUi() const +{ + if (timeStampUi.isUpToDate()) + return TRUE; + return (QMessageBox::information(MainWindow::self, tr( "Qt Designer" ), + tr("File '%1' has been changed outside Qt Designer.\n" + "Do you want to overwrite it?" ).arg(timeStampUi.fileName()), + tr("&Yes"), tr("&No")) == 0); +} + +bool FormFile::saveAs( bool ignoreModified ) +{ + QString f = pro->makeAbsolute( fileName() ); + if ( fileNameTemp && formWindow() ) { + f = QString( formWindow()->name() ).lower(); + f.replace( "::", "_" ); + f = pro->makeAbsolute( f + ".ui" ); + } + bool saved = FALSE; + if ( ignoreModified ) { + QString dir = QStringList::split( ':', pro->iFace()->customSetting( "QTSCRIPT_PACKAGES" ) ).first(); + f = QFileInfo( f ).fileName(); + f.prepend( dir + "/" ); + } + QString fn; + while ( !saved ) { + fn = QFileDialog::getSaveFileName( f, + tr( "Qt User-Interface Files (*.ui)" ) + ";;" + + tr( "All Files (*)" ), MainWindow::self, 0, + tr( "Save Form '%1' As ...").arg( formName() ), + MainWindow::self ? &MainWindow::self->lastSaveFilter : 0 ); + if ( fn.isEmpty() ) + return FALSE; + QFileInfo fi( fn ); + if ( fi.extension() != "ui" ) + fn += ".ui"; + fileNameTemp = FALSE; + filename = pro->makeRelative( fn ); + QFileInfo relfi( filename ); + if ( relfi.exists() ) { + if ( QMessageBox::warning( MainWindow::self, tr( "File Already Exists" ), + tr( "The file already exists. Do you wish to overwrite it?" ), + QMessageBox::Yes, + QMessageBox::No ) == QMessageBox::Yes ) { + saved = TRUE; + } else { + filename = f; + } + + } else { + saved = TRUE; + } + } + if ( !checkFileName( TRUE ) ) { + filename = f; + return FALSE; + } + pro->setModified( TRUE ); + timeStamp.setFileName( pro->makeAbsolute( codeFile() ) ); + if ( ed && formWindow() ) + ed->setCaption( tr( "Edit %1" ).arg( formWindow()->name() ) ); + setModified( TRUE ); + if ( pro->isDummy() ) + fw->mainWindow()->addRecentlyOpenedFile( fn ); + return save( TRUE, ignoreModified ); +} + +bool FormFile::close() +{ + if ( editor() ) { + editor()->save(); + editor()->close(); + } + if ( formWindow() ) + return formWindow()->close(); + return TRUE; +} + +bool FormFile::closeEvent() +{ + if ( !isModified() && fileNameTemp ) { + pro->removeFormFile( this ); + return TRUE; + } + + if ( !isModified() ) + return TRUE; + + if ( editor() ) + editor()->save(); + + switch ( QMessageBox::warning( MainWindow::self, tr( "Save Form" ), + tr( "Save changes to form '%1'?" ).arg( filename ), + tr( "&Yes" ), tr( "&No" ), tr( "&Cancel" ), 0, 2 ) ) { + case 0: // save + if ( !save() ) + return FALSE; + case 1: // don't save + loadCode(); + if ( ed ) + ed->editorInterface()->setText( cod ); + if ( fileNameTemp ) + pro->removeFormFile( this ); + if ( MainWindow::self ) + MainWindow::self->workspace()->update(); + break; + case 2: // cancel + return FALSE; + default: + break; + } + + setModified( FALSE ); + if ( MainWindow::self ) + MainWindow::self->updateFunctionList(); + setCodeEdited( FALSE ); + return TRUE; +} + +void FormFile::setModified( bool m, int who ) +{ + if ( ( who & WFormWindow ) == WFormWindow ) + setFormWindowModified( m ); + if ( ( who & WFormCode ) == WFormCode ) + setCodeModified( m ); +} + +bool FormFile::isModified( int who ) +{ + if ( who == WFormWindow ) + return isFormWindowModified(); + if ( who == WFormCode ) + return isCodeModified(); + return isCodeModified() || isFormWindowModified(); +} + +bool FormFile::isFormWindowModified() const +{ + if ( !formWindow() || !formWindow()->commandHistory() ) + return FALSE; + return formWindow()->commandHistory()->isModified(); +} + +bool FormFile::isCodeModified() const +{ + if ( !editor() ) + return cm; + return editor()->isModified(); +} + +void FormFile::setFormWindowModified( bool m ) +{ + bool b = isFormWindowModified(); + if ( m == b ) + return; + if ( !formWindow() || !formWindow()->commandHistory() ) + return; + formWindow()->commandHistory()->setModified( m ); + emit somethingChanged( this ); +} + +void FormFile::setCodeModified( bool m ) +{ + bool b = isCodeModified(); + if ( m == b ) + return; + emit somethingChanged( this ); + cm = m; + if ( !editor() ) + return; + editor()->setModified( m ); +} + +void FormFile::showFormWindow() +{ + if ( !MainWindow::self ) + return; + if ( formWindow() ) { + if ( ( formWindow()->hasFocus() || + MainWindow::self->qWorkspace()->activeWindow() == formWindow() ) && + MainWindow::self->propertyeditor()->formWindow() != formWindow() ) { + MainWindow::self->propertyeditor()->setWidget( formWindow()->currentWidget(), formWindow() ); + MainWindow::self->objectHierarchy()->setFormWindow( formWindow(), + formWindow()->currentWidget() ); + } + formWindow()->setFocus(); + return; + } + MainWindow::self->openFormWindow( pro->makeAbsolute( filename ), TRUE, this ); +} + +bool FormFile::setupUihFile( bool askForUih ) +{ + if ( !pro->isCpp() || !askForUih ) { + if ( !hasFormCode() ) { + createFormCode(); + setModified( TRUE ); + } + codeFileStat = FormFile::Ok; + return TRUE; + } + if ( codeFileStat != FormFile::Ok && !ed ) { + if ( hasFormCode() ) { + int i = QMessageBox::information( MainWindow::self, tr( "Using ui.h file" ), + tr( "An \"ui.h\" file for this form already exists.\n" + "Do you want to use it or create a new one?" ), + tr( "Use existing" ), tr( "Create new" ), + tr( "Cancel" ), 2, 2 ); + if ( i == 2 ) + return FALSE; + if ( i == 1 ) + createFormCode(); + } else { + if ( QMessageBox::Yes != QMessageBox::information( MainWindow::self, tr( "Creating ui.h file" ), + tr( "Do you want to create an new \"ui.h\" file?" ), + QMessageBox::Yes, QMessageBox::No ) ) + return FALSE; + createFormCode(); + } + setModified( TRUE ); + } + codeFileStat = FormFile::Ok; + return TRUE; +} + +SourceEditor *FormFile::showEditor( bool askForUih ) +{ + if ( !MainWindow::self ) + return 0; + showFormWindow(); + if ( !setupUihFile( askForUih ) ) + return 0; + SourceEditor *se = MainWindow::self->openSourceEditor(); + if ( !se ) + return 0; + se->setActiveWindow(); + se->setFocus(); + return se; +} + +static int ui_counter = 0; +QString FormFile::createUnnamedFileName() +{ + return QString( "unnamed" ) + QString::number( ++ui_counter ) + QString( ".ui" ); +} + +QString FormFile::codeExtension() const +{ + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( iface ) + return iface->formCodeExtension(); + return ""; +} + +QString FormFile::codeComment() const +{ + return QString( "/****************************************************************************\n" + "** ui.h extension file, included from the uic-generated form implementation.\n" + "**\n" + "** If you want to add, delete, or rename functions or slots, use\n" + "** Qt Designer to update this file, preserving your code.\n" + "**\n" + "** You should not define a constructor or destructor in this file.\n" + "** Instead, write your code in functions called init() and destroy().\n" + "** These will automatically be called by the form's constructor and\n" + "** destructor.\n" + "*****************************************************************************/\n" ); +} + +bool FormFile::hasFormCode() const +{ + return !cod.isEmpty() && cod != QString( codeComment() ); +} + +int FormFile::codeFileState() const +{ + return hasFormCode() ? codeFileStat : None; +} + +void FormFile::setCodeFileState( UihState s ) +{ + codeFileStat = s; +} + +void FormFile::createFormCode() +{ + if ( !formWindow() ) + return; + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( !iface ) + return; + if ( pro->isCpp() ) + cod = codeComment(); + QValueList functionList = MetaDataBase::functionList( formWindow() ); + for ( QValueList::Iterator it = functionList.begin(); it != functionList.end(); ++it ) { + cod += (!cod.isEmpty() ? "\n\n" : "") + + iface->createFunctionStart( formWindow()->name(), make_func_pretty((*it).function), + (*it).returnType.isEmpty() ? + QString( "void" ) : + (*it).returnType, (*it).access ) + + "\n" + iface->createEmptyFunction(); + } + parseCode( cod, FALSE ); +} + +void FormFile::load() +{ + showFormWindow(); + code(); +} + +bool FormFile::loadCode() +{ + QString fn = pro->makeAbsolute( codeFile() ); + if ( fn.isEmpty() ) + return FALSE; + + QFile f( fn ); + if ( !f.open( IO_ReadOnly ) ) { + cod = ""; + setCodeFileState( FormFile::None ); + return FALSE; + } + QTextStream ts( &f ); + cod = ts.read(); + parseCode( cod, FALSE ); + if ( hasFormCode() && codeFileStat != FormFile::Ok ) + setCodeFileState( FormFile::Deleted ); + timeStamp.update(); + return TRUE; +} + +bool FormFile::isCodeEdited() const +{ + return codeEdited; +} + +void FormFile::setCodeEdited( bool b ) +{ + codeEdited = b; +} + +void FormFile::parseCode( const QString &txt, bool allowModify ) +{ + if ( !formWindow() ) + return; + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( !iface ) + return; + QValueList functions; + QValueList newFunctions, oldFunctions; + oldFunctions = MetaDataBase::functionList( formWindow() ); + iface->functions( txt, &functions ); + QMap funcs; + for ( QValueList::Iterator it = functions.begin(); + it != functions.end(); ++it ) { + bool found = FALSE; + for ( QValueList::Iterator fit = oldFunctions.begin(); + fit != oldFunctions.end(); ++fit ) { + QString f( (*fit).function ); + if ( MetaDataBase::normalizeFunction( f ) == + MetaDataBase::normalizeFunction( (*it).name ) ) { + found = TRUE; + MetaDataBase::Function function; + function.function = make_func_pretty( (*it).name ); + function.specifier = (*fit).specifier; + function.type = (*fit).type; + if ( !pro->isCpp() ) + function.access = (*it).access; + else + function.access = (*fit).access; + function.language = (*fit).language; + function.returnType = (*it).returnType; + newFunctions << function; + funcs.insert( (*it).name, (*it).body ); + oldFunctions.remove( fit ); + break; + } + } + if ( !found ) { + MetaDataBase::Function function; + function.function = make_func_pretty( (*it).name ); + function.specifier = "virtual"; + function.access = "public"; + function.language = pro->language(); + function.returnType = (*it).returnType; + if ( function.returnType == "void" ) + function.type = "slot"; + else + function.type = "function"; + if ( function.function == "init()" || function.function == "destroy()" ) { + function.type = "function"; + function.access = "private"; + function.specifier = "non virtual"; + } + newFunctions << function; + funcs.insert( (*it).name, (*it).body ); + if ( allowModify ) + setFormWindowModified( TRUE ); + } + } + + if ( allowModify && oldFunctions.count() > 0 ) + setFormWindowModified( TRUE ); + + MetaDataBase::setFunctionList( formWindow(), newFunctions ); +} + +void FormFile::syncCode() +{ + if ( !editor() ) + return; + parseCode( editor()->editorInterface()->text(), TRUE ); + cod = editor()->editorInterface()->text(); +} + +void FormFile::checkTimeStamp() +{ + if ( timeStamp.isUpToDate() ) + return; + timeStamp.update(); + if ( codeEdited ) { + if ( QMessageBox::information( MainWindow::self, tr( "Qt Designer" ), + tr( "File '%1' has been changed outside Qt Designer.\n" + "Do you want to reload it?" ).arg( timeStamp.fileName() ), + tr( "&Yes" ), tr( "&No" ) ) == 0 ) { + QFile f( timeStamp.fileName() ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + editor()->editorInterface()->setText( ts.read() ); + editor()->save(); + if ( MainWindow::self ) + MainWindow::self->functionsChanged(); + } + } + } else { + loadCode(); + } +} + +bool FormFile::isUihFileUpToDate() +{ + if ( timeStamp.isUpToDate() ) + return TRUE; + if ( !editor() ) { + MainWindow::self->editSource(); + parseCode( editor()->editorInterface()->text(), TRUE ); + } + checkTimeStamp(); + return FALSE; +} + +void FormFile::addFunctionCode( MetaDataBase::Function function ) +{ + if ( pro->isCpp() && !hasFormCode() && !codeEdited ) + return; + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( !iface ) + return; + + QValueList funcs; + iface->functions( cod, &funcs ); + bool hasFunc = FALSE; + for ( QValueList::Iterator it = funcs.begin(); + it != funcs.end(); ++it ) { + if ( MetaDataBase::normalizeFunction( (*it).name ) == MetaDataBase::normalizeFunction( function.function ) ) { + hasFunc = TRUE; + break; + } + } + + if ( !hasFunc ) { + if ( !codeEdited && !timeStamp.isUpToDate() ) + loadCode(); + MetaDataBase::MetaInfo mi = MetaDataBase::metaInfo( formWindow() ); + QString cn; + if ( mi.classNameChanged ) + cn = mi.className; + if ( cn.isEmpty() ) + cn = formWindow()->name(); + QString body = "\n\n" + iface->createFunctionStart( cn, + make_func_pretty( function.function ), + function.returnType.isEmpty() ? + QString( "void" ) : + function.returnType, function.access ) + + "\n" + iface->createEmptyFunction(); + cod += body; + if ( codeEdited ) { + setModified( TRUE ); + emit somethingChanged( this ); + } + } +} + +void FormFile::removeFunctionCode( MetaDataBase::Function function ) +{ + if ( pro->isCpp() && !hasFormCode() && !codeEdited ) + return; + + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( !iface ) + return; + + checkTimeStamp(); + QString sourceCode = code(); + if ( sourceCode.isEmpty() ) + return; + QValueList functions; + iface->functions( sourceCode, &functions ); + QString fu = MetaDataBase::normalizeFunction( function.function ); + for ( QValueList::Iterator fit = functions.begin(); fit != functions.end(); ++fit ) { + if ( MetaDataBase::normalizeFunction( (*fit).name ) == fu ) { + int line = 0; + int start = 0; + while ( line < (*fit).start - 1 ) { + start = sourceCode.find( '\n', start ); + if ( start == -1 ) + return; + start++; + line++; + } + if ( start == -1 ) + return; + int end = start; + while ( line < (*fit).end + 1 ) { + end = sourceCode.find( '\n', end ); + if ( end == -1 ) { + if ( line <= (*fit).end ) + end = sourceCode.length() - 1; + else + return; + } + end++; + line++; + } + if ( end < start ) + return; + sourceCode.remove( start, end - start ); + setCode( sourceCode ); + } + } +} + +void FormFile::functionNameChanged( const QString &oldName, const QString &newName ) +{ + if ( !cod.isEmpty() ) { + QString funcStart = QString( formWindow()->name() ) + QString( "::" ); + int i = cod.find( funcStart + oldName ); + if ( i != -1 ) { + cod.remove( i + funcStart.length(), oldName.length() ); + cod.insert( i + funcStart.length(), newName ); + } + } +} + +void FormFile::functionRetTypeChanged( const QString &fuName, const QString &oldType, const QString &newType ) +{ + if ( !cod.isEmpty() ) { + QString oldFunct = oldType + " " + QString( formWindow()->name() ) + "::" + fuName; + QString newFunct = newType + " " + QString( formWindow()->name() ) + "::" + fuName; + + int i = cod.find( oldFunct ); + if ( i != -1 ) { + cod.remove( i, oldFunct.length() ); + cod.insert( i, newFunct ); + } + } +} + +QString FormFile::formName() const +{ + FormFile* that = (FormFile*) this; + if ( formWindow() ) { + that->cachedFormName = formWindow()->name(); + return cachedFormName; + } + if ( !cachedFormName.isNull() ) + return cachedFormName; + QFile f( pro->makeAbsolute( filename ) ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + QString line; + QString className; + while ( !ts.eof() ) { + line = ts.readLine(); + if ( !className.isEmpty() ) { + int end = line.find( "" ); + if ( end == -1 ) { + className += line; + } else { + className += line.left( end ); + break; + } + continue; + } + int start; + if ( ( start = line.find( "" ) ) != -1 ) { + int end = line.find( "" ); + if ( end == -1 ) { + className = line.mid( start + 7 ); + } else { + className = line.mid( start + 7, end - ( start + 7 ) ); + break; + } + } + } + that->cachedFormName = className; + } + if ( cachedFormName.isEmpty() ) + that->cachedFormName = filename; + return cachedFormName; +} + +void FormFile::formWindowChangedSomehow() +{ + emit somethingChanged( this ); +} + +bool FormFile::checkFileName( bool allowBreak ) +{ + FormFile *ff = pro->findFormFile( filename, this ); + if ( ff ) + QMessageBox::warning( MainWindow::self, tr( "Invalid Filename" ), + tr( "The project already contains a form with a\n" + "filename of '%1'. Please choose a new filename." ).arg( filename ) ); + if (!formWindow()) // We are starting up + return FALSE; + while ( ff ) { + QString fn; + while ( fn.isEmpty() ) { + fn = QFileDialog::getSaveFileName( pro->makeAbsolute( fileName() ), + tr( "Qt User-Interface Files (*.ui)" ) + ";;" + + tr( "All Files (*)" ), MainWindow::self, 0, + tr( "Save Form '%1' As ..."). + arg( formWindow()->name() ), + MainWindow::self ? &MainWindow::self->lastSaveFilter : 0 ); + if ( allowBreak && fn.isEmpty() ) + return FALSE; + } + filename = pro->makeRelative( fn ); + ff = pro->findFormFile( filename, this ); + } + return TRUE; +} + +void FormFile::addConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot ) +{ + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( iface ) + iface->addConnection( sender, signal, receiver, slot, &cod ); + if ( ed ) + ed->editorInterface()->setText( cod ); +} + +void FormFile::removeConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot ) +{ + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + if ( iface ) + iface->removeConnection( sender, signal, receiver, slot, &cod ); + if ( ed ) + ed->editorInterface()->setText( cod ); +} + +void FormFile::notifyFormWindowChange() +{ + if ( fw ) + pro->formOpened( fw ); +} diff --git a/tools/designer/designer/formfile.h b/tools/designer/designer/formfile.h new file mode 100644 index 0000000..73f7139 --- /dev/null +++ b/tools/designer/designer/formfile.h @@ -0,0 +1,153 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef FORMFILE_H +#define FORMFILE_H + +#include +#include "timestamp.h" +#include "metadatabase.h" + +class Project; +class FormWindow; +class SourceEditor; + +class FormFile : public QObject +{ + Q_OBJECT + friend class SourceEditor; + +public: + enum Who { + WFormWindow = 1, + WFormCode = 2, + WAnyOrAll = WFormWindow | WFormCode + }; + + enum UihState { None, Ok, Deleted }; + + FormFile( const QString &fn, bool temp, Project *p, const char *name = 0 ); + ~FormFile(); + + void setFormWindow( FormWindow *f ); + void setEditor( SourceEditor *e ); + void setFileName( const QString &fn ); + void setCode( const QString &c ); + void setModified( bool m, int who = WAnyOrAll ); + void setCodeEdited( bool b ); + + FormWindow *formWindow() const; + SourceEditor *editor() const; + QString fileName() const; + QString absFileName() const; + + bool supportsCodeFile() const { return !codeExtension().isEmpty(); } + QString codeComment() const; + QString codeFile() const; + QString code(); + bool isCodeEdited() const; + + bool loadCode(); + void load(); + bool save( bool withMsgBox = TRUE, bool ignoreModified = FALSE ); + bool saveAs( bool ignoreModified = FALSE ); + bool close(); + bool closeEvent(); + bool isModified( int who = WAnyOrAll ); + bool hasFormCode() const; + void createFormCode(); + void syncCode(); + void checkTimeStamp(); + bool isUihFileUpToDate(); + void addFunctionCode( MetaDataBase::Function function ); + void removeFunctionCode( MetaDataBase::Function function ); + void functionNameChanged( const QString &oldName, const QString &newName ); + void functionRetTypeChanged( const QString &fuName, const QString &oldType, const QString &newType ); + + void showFormWindow(); + SourceEditor *showEditor( bool askForUih = TRUE ); + + static QString createUnnamedFileName(); + QString formName() const; + + bool isFake() const { return fake; } + + void parseCode( const QString &txt, bool allowModify ); + + void addConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot ); + void removeConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot ); + + bool hasTempFileName() const { return fileNameTemp; } + void setCodeFileState( UihState ); + int codeFileState() const; + bool setupUihFile( bool askForUih = TRUE ); + + Project *project() const { return pro; } + +signals: + void somethingChanged( FormFile* ); + +private slots: + void formWindowChangedSomehow(); + void notifyFormWindowChange(); + +private: + bool isFormWindowModified() const; + bool isCodeModified() const; + void setFormWindowModified( bool m ); + void setCodeModified( bool m ); + QString codeExtension() const; + bool checkFileName( bool allowBreak ); + bool shouldOverwriteUi() const; + +private: + QString filename; + bool fileNameTemp; + Project *pro; + FormWindow *fw; + SourceEditor *ed; + QString cod; + TimeStamp timeStamp; + bool codeEdited; + QString cachedFormName; + bool fake; + bool pkg; + bool cm; + UihState codeFileStat; + + TimeStamp timeStampUi; +}; + +#endif diff --git a/tools/designer/designer/formsettings.ui b/tools/designer/designer/formsettings.ui new file mode 100644 index 0000000..a531acd --- /dev/null +++ b/tools/designer/designer/formsettings.ui @@ -0,0 +1,556 @@ + +FormSettingsBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + FormSettingsBase + + + + 0 + 0 + 597 + 458 + + + + Form Settings + + + true + + + <b>Form Settings</b><p>Change settings for the form. Settings like <b>Comment</b> and <b>Author</b> are for your own use and are not required.</p> + + + + unnamed + + + 11 + + + 6 + + + + ButtonGroup1 + + + Pixmaps + + + + unnamed + + + 11 + + + 6 + + + + radioPixmapInline + + + Save In&line + + + true + + + Save pixmaps in the .ui files + + + <b>Save Inline</b><p>Saves the pixmaps as binary data in the .ui files. Pixmaps saved like this are not shared between forms. We recommend using Project image files instead. + + + + + radioProjectImageFile + + + Project &Imagefile + + + Use the Project's Image file for pixmaps + + + <b>Use the Project's Image file for pixmaps</b> +<p>Each project may have a collection of pixmaps. If you use a project, we recommend that you use this option since it shares the images and is the fastest and most efficient way to use pixmaps in your forms.</p> + + + + + editPixmapFunction + + + false + + + Specify Pixmap-Loader function (only the function's name, no parentheses!) + + + <b>Specify Pixmap-Loader function</b><p>Specify the function which should be used for loading a pixmap in the generated code. <em>Only enter the function's name, with no parentheses.</em> + + + + + radioPixmapFunction + + + Use &Function: + + + Use the given function for pixmaps + + + <b>Use a given function for pixmaps</b><p>If you choose this option you must define a function in the line edit at the right which will be used in the generated code for loading pixmaps. When choosing a pixmap in <i>Qt Designer</i> you will be asked to specify the arguments which will be passed to the function in the generated code.<p> This approach makes it possible to use your own icon-loader function for loading pixmaps. <i>Qt Designer</i> can't preview the correct image if you use your own function. + + + + + + + GroupBox1 + + + Box + + + Sunken + + + Settings + + + + unnamed + + + 11 + + + 6 + + + + editClassName + + + Change class name + + + <b>Enter the name of the class that will be created.</b><p><em>classname.h</em> and <em>classname.cpp</em> will be generated as C++ output when it is compiled by uic.</p> + + + + + TextLabel1_2 + + + A&uthor: + + + editAuthor + + + + + editAuthor + + + Enter your name + + + Enter your name. + + + + + TextLabel1 + + + Class &Name: + + + editClassName + + + + + TextLabel2 + + + Co&mment: + + + editComment + + + + + editComment + + + Enter a comment about the form. + + + + + Spacer1 + + + Vertical + + + Expanding + + + + + + + GroupBox2 + + + La&youts + + + + unnamed + + + 11 + + + 6 + + + + spinMargin + + + 11 + + + + + Spacer3 + + + Horizontal + + + Expanding + + + + + TextLabel2_2 + + + D&efault Spacing: + + + spinSpacing + + + + + checkLayoutFunctions + + + Use Func&tions: + + + Use functions to get the margin and spacing + + + <b>Use a given function for margin and/or spacing</b><p>If you choose this option you must define functions in the line edit below which will be used in the generated code for getting the margin and spacing value. <i>Qt Designer</i> can't preview the correct margin or spacing if you use your own function. Instead, the default values will be used for preview. + + + + + spinSpacing + + + 6 + + + + + Spacer4 + + + Horizontal + + + Expanding + + + + + TextLabel1_3 + + + Default Mar&gin: + + + spinMargin + + + + + spaFuLabel + + + false + + + S&pacing: + + + editSpacingFunction + + + + + marFuLabel + + + false + + + + 5 + 5 + 0 + 0 + + + + Ma&rgin: + + + editMarginFunction + + + + + Spacer5 + + + Horizontal + + + Expanding + + + + + editSpacingFunction + + + false + + + Specify spacing function (only the function's name, no parentheses!) + + + <b>Specify spacing function</b><p>Specify the function which should be used for getting the spacing in the generated code. <em>Only enter the function's name, with no parentheses.</em> + + + + + editMarginFunction + + + false + + + + 5 + 0 + 0 + 0 + + + + Specify margin function (only the function's name, no parentheses!) + + + <b>Specify margin function</b><p>Specify the function which should be used for getting the margin in the generated code. <em>Only enter the function's name, with no parentheses.</em> + + + + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + + + buttonCancel + clicked() + FormSettingsBase + reject() + + + buttonOk + clicked() + FormSettingsBase + okClicked() + + + radioPixmapFunction + toggled(bool) + editPixmapFunction + setEnabled(bool) + + + checkLayoutFunctions + toggled(bool) + editSpacingFunction + setEnabled(bool) + + + checkLayoutFunctions + toggled(bool) + editMarginFunction + setEnabled(bool) + + + checkLayoutFunctions + toggled(bool) + marFuLabel + setEnabled(bool) + + + checkLayoutFunctions + toggled(bool) + spaFuLabel + setEnabled(bool) + + + + editClassName + editComment + editAuthor + radioPixmapInline + radioPixmapFunction + editPixmapFunction + radioProjectImageFile + spinMargin + spinSpacing + checkLayoutFunctions + editMarginFunction + editSpacingFunction + buttonOk + buttonCancel + buttonHelp + + + okClicked() + + + diff --git a/tools/designer/designer/formsettingsimpl.cpp b/tools/designer/designer/formsettingsimpl.cpp new file mode 100644 index 0000000..fa7c1bd --- /dev/null +++ b/tools/designer/designer/formsettingsimpl.cpp @@ -0,0 +1,125 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "formsettingsimpl.h" +#include "formwindow.h" +#include "metadatabase.h" +#include "command.h" +#include "asciivalidator.h" +#include "mainwindow.h" +#include "project.h" + +#include +#include +#include +#include +#include +#include +#include + +FormSettings::FormSettings( QWidget *parent, FormWindow *fw ) + : FormSettingsBase( parent, 0, TRUE ), formwindow( fw ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + MetaDataBase::MetaInfo info = MetaDataBase::metaInfo( fw ); + if ( info.classNameChanged && !info.className.isEmpty() ) + editClassName->setText( info.className ); + else + editClassName->setText( fw->name() ); + editComment->setText( info.comment ); + editAuthor->setText( info.author ); + + editClassName->setValidator( new AsciiValidator( QString( ":" ), editClassName ) ); + editPixmapFunction->setValidator( new AsciiValidator( QString( ":" ), editPixmapFunction ) ); + + if ( formwindow->savePixmapInline() ) + radioPixmapInline->setChecked( TRUE ); + else if ( formwindow->savePixmapInProject() ) + radioProjectImageFile->setChecked( TRUE ); + else + radioPixmapFunction->setChecked( TRUE ); + editPixmapFunction->setText( formwindow->pixmapLoaderFunction() ); + radioProjectImageFile->setEnabled( !fw->project()->isDummy() ); + spinSpacing->setValue( formwindow->layoutDefaultSpacing() ); + spinMargin->setValue( formwindow->layoutDefaultMargin() ); + editSpacingFunction->setValidator( new AsciiValidator( QString( ":" ), editSpacingFunction ) ); + editMarginFunction->setValidator( new AsciiValidator( QString( ":" ), editMarginFunction ) ); + checkLayoutFunctions->setChecked( formwindow->hasLayoutFunctions() ); + editSpacingFunction->setText( formwindow->spacingFunction() ); + editMarginFunction->setText( formwindow->marginFunction() ); +} + +void FormSettings::okClicked() +{ + MetaDataBase::MetaInfo info; + info.className = editClassName->text(); + info.classNameChanged = info.className != QString( formwindow->name() ); + info.comment = editComment->text(); + info.author = editAuthor->text(); + MetaDataBase::setMetaInfo( formwindow, info ); + + formwindow->commandHistory()->setModified( TRUE ); + + if ( formwindow->savePixmapInline() ) { + MetaDataBase::clearPixmapArguments( formwindow ); + MetaDataBase::clearPixmapKeys( formwindow ); + } else if ( formwindow->savePixmapInProject() ) { + MetaDataBase::clearPixmapArguments( formwindow ); + } else { + MetaDataBase::clearPixmapKeys( formwindow ); + } + + if ( radioPixmapInline->isChecked() ) { + formwindow->setSavePixmapInline( TRUE ); + formwindow->setSavePixmapInProject( FALSE ); + } else if ( radioProjectImageFile->isChecked() ){ + formwindow->setSavePixmapInline( FALSE ); + formwindow->setSavePixmapInProject( TRUE ); + } else { + formwindow->setSavePixmapInline( FALSE ); + formwindow->setSavePixmapInProject( FALSE ); + } + + if ( checkLayoutFunctions->isChecked() ) + formwindow->hasLayoutFunctions( TRUE ); + else + formwindow->hasLayoutFunctions( FALSE ); + + formwindow->setPixmapLoaderFunction( editPixmapFunction->text() ); + formwindow->setLayoutDefaultSpacing( spinSpacing->value() ); + formwindow->setSpacingFunction( editSpacingFunction->text() ); + formwindow->setLayoutDefaultMargin( spinMargin->value() ); + formwindow->setMarginFunction( editMarginFunction->text() ); + + accept(); +} diff --git a/tools/designer/designer/formsettingsimpl.h b/tools/designer/designer/formsettingsimpl.h new file mode 100644 index 0000000..cdda83c --- /dev/null +++ b/tools/designer/designer/formsettingsimpl.h @@ -0,0 +1,56 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef FORMSETTINGSIMPL_H +#define FORMSETTINGSIMPL_H + +#include "formsettings.h" + +class FormWindow; + +class FormSettings : public FormSettingsBase +{ + Q_OBJECT + +public: + FormSettings( QWidget *parent, FormWindow *fw ); + +protected slots: + void okClicked(); + +private: + FormWindow *formwindow; + +}; + +#endif diff --git a/tools/designer/designer/formwindow.cpp b/tools/designer/designer/formwindow.cpp new file mode 100644 index 0000000..ec620e7 --- /dev/null +++ b/tools/designer/designer/formwindow.cpp @@ -0,0 +1,2761 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "formwindow.h" +#include "defs.h" +#include "mainwindow.h" +#include "widgetfactory.h" +#include "sizehandle.h" +#include "metadatabase.h" +#include "resource.h" +#include "layout.h" +#include "connectiondialog.h" +#include +#include "pixmapchooser.h" +#include "orderindicator.h" +#include "hierarchyview.h" +#include "designerappiface.h" +#include "menubareditor.h" +#define NO_STATIC_COLORS +#include "globaldefs.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// FormWindow should be able to work to some limited degree +// (existance, loading) without a MainWindow. Functions which require +// a MainWindow in theory should never be called if no MainWindow +// exists. These macros are used to let us know if that happens anyway +// and to ensure that we don't crash +#define CHECK_MAINWINDOW Q_ASSERT( mainWindow() ); if ( !mainWindow() ) return +#define CHECK_MAINWINDOW_VALUE( v ) Q_ASSERT( mainWindow() ); if ( !mainWindow() ) return v + +static void setCursorToAll( const QCursor &c, QWidget *start ) +{ + start->setCursor( c ); + QObjectList *l = (QObjectList*)start->children(); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && !::qt_cast(o) ) + setCursorToAll( c, ( (QWidget*)o ) ); + } + } +} + +static void restoreCursors( QWidget *start, FormWindow *fw ) +{ + if ( fw->widgets()->find( start ) ) + start->setCursor( MetaDataBase::cursor( start ) ); + else + start->setCursor( Qt::ArrowCursor ); + QObjectList *l = (QObjectList*)start->children(); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && !::qt_cast(o) ) + restoreCursors( ( (QWidget*)o ), fw ); + } + } +} + +#if defined(Q_WS_WIN32) // #### needed for the workaround for repaint problem on windows +#include +static void flickerfree_update( QWidget *w ) +{ + InvalidateRect( w->winId(), 0, FALSE ); +} +#endif + +/*! + \class FormWindow formwindow.h + \brief Editor window for a form + + The FormWindow is the widget which is used as editor for forms. It + handles inserting, deleting, moving, resizing, etc. of widgets. + + Normally multiple formwindows are used at the same time in the + Designer. So each formwindow has its own undo/redo buffer, etc. + + Also the formwindow has some signals to inform e.g. about selection + changes which is interesting for the PropertyEditor. + + For handling the events of the child widgets (moving, etc.) the + handleMousePress(), etc. functions are called from the application + event filter which is implemented in MainWindow::eventFilter(). +*/ + +FormWindow::FormWindow( FormFile *f, MainWindow *mw, QWidget *parent, const char *name ) + : QWidget( parent, name, WDestructiveClose ), mainwindow( mw ), + commands( 100 ), pixInline( TRUE ), pixProject( FALSE ) +{ + ff = f; + init(); + initSlots(); +} + +FormWindow::FormWindow( FormFile *f, QWidget *parent, const char *name ) + : QWidget( parent, name, WDestructiveClose ), mainwindow( 0 ), + commands( 100 ), pixInline( TRUE ) +{ + ff = f; + init(); +} + +void FormWindow::init() +{ + fake = qstrcmp( name(), "qt_fakewindow" ) == 0; + MetaDataBase::addEntry( this ); + ff->setFormWindow( this ); + iface = 0; + proj = 0; + propertyWidget = 0; + toolFixed = FALSE; + checkedSelectionsForMove = FALSE; + mContainer = 0; + startWidget = endWidget = 0; + currTool = POINTER_TOOL; + unclippedPainter = 0; + widgetPressed = FALSE; + drawRubber = FALSE; + setFocusPolicy( ClickFocus ); + sizePreviewLabel = 0; + checkSelectionsTimer = new QTimer( this, "checkSelectionsTimer" ); + connect( checkSelectionsTimer, SIGNAL( timeout() ), + this, SLOT( invalidCheckedSelections() ) ); + updatePropertiesTimer = new QTimer( this ); + connect( updatePropertiesTimer, SIGNAL( timeout() ), + this, SLOT( updatePropertiesTimerDone() ) ); + showPropertiesTimer = new QTimer( this ); + connect( showPropertiesTimer, SIGNAL( timeout() ), + this, SLOT( showPropertiesTimerDone() ) ); + selectionChangedTimer = new QTimer( this ); + connect( selectionChangedTimer, SIGNAL( timeout() ), + this, SLOT( selectionChangedTimerDone() ) ); + windowsRepaintWorkaroundTimer = new QTimer( this ); + connect( windowsRepaintWorkaroundTimer, SIGNAL( timeout() ), + this, SLOT( windowsRepaintWorkaroundTimerTimeout() ) ); + insertParent = 0; + connect( &commands, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ), + this, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ) ); + propShowBlocked = FALSE; + + setIcon( QPixmap::fromMimeSource( "designer_form.png" ) ); + + connect( &commands, SIGNAL( modificationChanged( bool ) ), + this, SLOT( modificationChanged( bool ) ) ); + buffer = 0; + + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QFrame" ), this ); + setMainContainer( w ); + propertyWidget = w; + targetContainer = 0; + hadOwnPalette = FALSE; + + defSpacing = BOXLAYOUT_DEFAULT_SPACING; + defMargin = BOXLAYOUT_DEFAULT_MARGIN; + hasLayoutFunc = FALSE; +} + +void FormWindow::setMainWindow( MainWindow *w ) +{ + mainwindow = w; + MetaDataBase::addEntry( this ); + initSlots(); +} + +void FormWindow::initSlots() +{ + if ( isFake() ) + return; + Q_ASSERT( project() || MainWindow::self ); + if ( !project() && !MainWindow::self ) + return; + Project *p = project() ? project() : MainWindow::self->currProject(); + if ( p && p->isCpp() ) { + QString code = formFile()->code(); + if ( code.isEmpty() ) + formFile()->setCode( formFile()->codeComment() ); + } +} + +FormWindow::~FormWindow() +{ + if ( MainWindow::self && MainWindow::self->objectHierarchy()->formWindow() == this ) + MainWindow::self->objectHierarchy()->setFormWindow( 0, 0 ); + + MetaDataBase::clear( this ); + if ( ff ) + ff->setFormWindow( 0 ); + delete iface; +} + +void FormWindow::closeEvent( QCloseEvent *e ) +{ + QGuardedPtr that = this; + if ( ff->closeEvent() && ( !that || ( mainwindow && mainwindow->unregisterClient( this ) ) ) ) + e->accept(); + else + e->ignore(); +} + +void FormWindow::paintGrid( QWidget *w, QPaintEvent *e ) +{ + if ( !mainWindow() || !mainWindow()->showGrid() ) + return; + QPixmap grid; + QString grid_name; + grid_name.sprintf("FormWindowGrid_%d_%d", mainWindow()->grid().x(), mainWindow()->grid().y()); + if( !QPixmapCache::find( grid_name, grid ) ) { + grid = QPixmap( 350 + ( 350 % mainWindow()->grid().x() ), 350 + ( 350 % mainWindow()->grid().y() ) ); + grid.fill( colorGroup().color( QColorGroup::Foreground ) ); + QBitmap mask( grid.width(), grid.height() ); + mask.fill( color0 ); + QPainter p( &mask ); + p.setPen( color1 ); + for ( int y = 0; y < grid.width(); y += mainWindow()->grid().y()) { + for ( int x = 0; x < grid.height(); x += mainWindow()->grid().x() ) { + p.drawPoint( x, y ); + } + } + grid.setMask( mask ); + QPixmapCache::insert( grid_name, grid ); + } + QPainter p( w ); + p.setClipRegion( e->rect() ); + p.drawTiledPixmap( QRect( 0, 0, width(), height() ), grid ); +} + +/*! For operations like drawing a rubber band or drawing the rect + when inserting a new widget, a unclipped painter (which draws also + on child widgets) is needed. This method does all the initialization. +*/ + +void FormWindow::beginUnclippedPainter( bool doNot ) +{ + endUnclippedPainter(); + bool unclipped = testWFlags( WPaintUnclipped ); + setWFlags( WPaintUnclipped ); + unclippedPainter = new QPainter; + unclippedPainter->begin( this ); + if ( !unclipped ) + clearWFlags( WPaintUnclipped ); + if ( doNot ) { + unclippedPainter->setPen( QPen( color0, 2 ) ); + unclippedPainter->setRasterOp( NotROP ); + } +} + +/*! + Gets rid of an open unclipped painter. + + \sa beginUnclippedPainter() +*/ + +void FormWindow::endUnclippedPainter() +{ + if ( unclippedPainter ) + unclippedPainter->end(); + delete unclippedPainter; + unclippedPainter = 0; +} + +QPoint FormWindow::gridPoint( const QPoint &p ) +{ + return QPoint( ( p.x() / grid().x() ) * grid().x(), + ( p.y() / grid().y() ) * grid().y() ); +} + +void FormWindow::drawSizePreview( const QPoint &pos, const QString& text ) +{ + unclippedPainter->save(); + unclippedPainter->setPen( QPen( colorGroup().foreground(), 1 )); + unclippedPainter->setRasterOp( CopyROP ); + if ( !sizePreviewPixmap.isNull() ) + unclippedPainter->drawPixmap( sizePreviewPos, sizePreviewPixmap ); + if ( text.isNull() ) { + sizePreviewPixmap = QPixmap(); // set null again + unclippedPainter->restore(); + return; + } + QRect r = fontMetrics().boundingRect( 0, 0, 0, 0, AlignCenter, text ); + r = QRect( pos + QPoint( 10, 10 ), r.size() + QSize( 5, 5 ) ); + + checkPreviewGeometry( r ); + + sizePreviewPos = r.topLeft(); + sizePreviewPixmap = QPixmap::grabWindow( winId(), r.x(), r.y(), r.width(), r.height() ); + unclippedPainter->setBrush( QColor( 255, 255, 128 ) ); + unclippedPainter->drawRect( r ); + unclippedPainter->drawText( r, AlignCenter, text ); + unclippedPainter->restore(); +} + +void FormWindow::insertWidget() +{ + CHECK_MAINWINDOW; + if ( !insertParent ) + return; + + if ( currTool == POINTER_TOOL ) + return; + + bool useSizeHint = !oldRectValid || ( currRect.width() < 2 && currRect.height() < 2 ); + Orientation orient = Horizontal; + QString n = WidgetDatabase::className( currTool ); + if ( useSizeHint && ( n == "Spacer" || n == "QSlider" || n == "Line" || n == "QScrollBar" ) ) { + QPopupMenu m( mainWindow() ); + m.insertItem( tr( "&Horizontal" ) ); + int ver = m.insertItem( tr( "&Vertical" ) ); + int r = m.exec( QCursor::pos() ); + if ( r == ver ) + orient = Vertical; + } + + + QWidget *w = WidgetFactory::create( currTool, insertParent, 0, TRUE, &currRect, orient ); + if ( !w ) + return; + + if ( !savePixmapInline() && currTool == WidgetDatabase::idFromClassName( "PixmapLabel" ) ) { // ### what to do for pixmaps in project + QPixmap pix; + // we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that + pix.convertFromImage( QPixmap::fromMimeSource( "designer_image.png" ).convertToImage() ); + ( (QLabel*)w )->setPixmap( pix ); + } + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) ); + if ( WidgetDatabase::isCustomWidget( id ) ) { + QWhatsThis::add( w, tr("A %1 (custom widget) " + "

Click Edit Custom Widgets... in the Tools|Custom " + "menu to add and change custom widgets. You can add " + "properties as well as signals and slots to integrate custom widgets into " + "Qt Designer, and provide a pixmap which will be used to represent " + "the widget on the form.

") + .arg(WidgetDatabase::toolTip( id )) ); + QToolTip::add( w, tr("A %1 (custom widget)").arg(WidgetDatabase::toolTip( id )) ); + } else { + QString tt = WidgetDatabase::toolTip( id ); + QString wt = WidgetDatabase::whatsThis( id ); + if ( !wt.isEmpty() && !tt.isEmpty() ) + QWhatsThis::add( w, QString("A %1

%2

").arg( tt ).arg( wt ) ); + } + + QString s = w->name(); + unify( w, s, TRUE ); + w->setName( s ); + insertWidget( w ); + QRect r( currRect ); + if ( !oldRectValid || + ( currRect.width() < 2 && currRect.height() < 2 ) ) + r = QRect( rectAnchor, QSize( 0, 0 ) ); + + QPoint p = r.topLeft(); + p = mapToGlobal( p ); + p = insertParent->mapFromGlobal( p ); + r = QRect( p, r.size() ); + + if ( useSizeHint ) { + if ( n == "Spacer" ) { + if ( orient == Vertical ) { + r.setWidth( 20 ); + r.setHeight( 40 ); + } else { + r.setWidth( 40 ); + r.setHeight( 20 ); + } + } else { + r.setWidth( w->sizeHint().width() ); + r.setHeight( w->sizeHint().height() ); + } + } + + if ( r.width() < 2 * grid().x() ) + r.setWidth( 2 * grid().x() ); + if ( r.height() < 2 * grid().y() ) + r.setHeight( 2 * grid().y() ); + + const QObjectList *l = insertParent->children(); + QObjectListIt it( *l ); + QWidgetList lst; + if ( WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) { + for ( ; it.current(); ) { + QObject *o = it.current(); + ++it; + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) && o != w ) { + QRect r2( ( (QWidget*)o )->pos(), + ( (QWidget*)o )->size() ); + if ( r.contains( r2 ) ) + lst.append( (QWidget*)o ); + } + } + } + + if ( !lst.isEmpty() ) { + QWidget *pw = WidgetFactory::containerOfWidget( w ); + if (pw) { + QValueList op, np; + for ( QWidget *i = lst.first(); i; i = lst.next() ) { + op.append( i->pos() ); + QPoint pos = pw->mapFromGlobal( i->mapToGlobal( QPoint( 0, 0 ) ) ); + pos -= r.topLeft(); + np.append( pos ); + } + + MoveCommand *mv = new MoveCommand( tr( "Reparent Widgets" ), this, + lst, op, np, insertParent, pw ); + + if ( !toolFixed ) + mainwindow->resetTool(); + else + setCursorToAll( CrossCursor, w ); + + InsertCommand *cmd = new InsertCommand( tr( "Insert %1" ).arg( w->name() ), this, w, r ); + + QPtrList commands; + commands.append( mv ); + commands.append( cmd ); + + MacroCommand *mc = new MacroCommand( tr( "Insert %1" ).arg( w->name() ), this, commands ); + commandHistory()->addCommand( mc ); + mc->execute(); + } + } else { + if ( !toolFixed ) + mainwindow->resetTool(); + else + setCursorToAll( CrossCursor, w ); + + InsertCommand *cmd = new InsertCommand( tr( "Insert %1" ).arg( w->name() ), this, w, r ); + commandHistory()->addCommand( cmd ); + cmd->execute(); + } + + TemplateWizardInterface *iface = mainWindow()->templateWizardInterface( w->className() ); + if ( iface ) { + iface->setup( w->className(), w, iFace(), mainWindow()->designerInterface() ); + iface->release(); + } +} + +void FormWindow::insertWidget( QWidget *w, bool checkName ) +{ + if ( !w ) + return; + if ( checkName ) { + QString s = w->name(); + unify( w, s, TRUE ); + w->setName( s ); + } + + MetaDataBase::addEntry( w ); + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) ); + if ( WidgetDatabase::isCustomWidget( id ) ) { + QWhatsThis::add( w, tr("A %1 (custom widget) " + "

Click Edit Custom Widgets... in the Tools|Custom " + "menu to add and change custom widgets. You can add " + "properties as well as signals and slots to integrate custom widgets into " + "Qt Designer, and provide a pixmap which will be used to represent " + "the widget on the form.

") + .arg(WidgetDatabase::toolTip( id )) ); + QToolTip::add( w, tr("A %1 (custom widget)").arg(WidgetDatabase::toolTip( id )) ); + } else { + QString tt = WidgetDatabase::toolTip( id ); + QString wt = WidgetDatabase::whatsThis( id ); + if ( !wt.isEmpty() && !tt.isEmpty() ) + QWhatsThis::add( w, QString("A %1

%2

").arg( tt ).arg( wt ) ); + } + + restoreCursors( w, this ); + widgets()->insert( w, w ); + w->show(); +} + +void FormWindow::removeWidget( QWidget *w ) +{ + MetaDataBase::removeEntry( w ); + widgets()->take( w ); +} + +void FormWindow::handleContextMenu( QContextMenuEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + switch ( currTool ) { + case POINTER_TOOL: { + if ( !isMainContainer( w ) && qstrcmp( w->name(), "central widget" ) != 0 ) { // press on a child widget + raiseChildSelections( w ); // raise selections and select widget + selectWidget( w ); + // if widget is laid out, find the first non-laid out super-widget + QWidget *realWidget = w; // but store the original one + while ( w->parentWidget() && + ( WidgetFactory::layoutType( w->parentWidget()) != WidgetFactory::NoLayout || + !insertedWidgets.find(w) ) ) + w = w->parentWidget(); + if ( ::qt_cast(mainContainer()) && ((QMainWindow*)mainContainer())->centralWidget() == realWidget ) { + e->accept(); + mainwindow->popupFormWindowMenu( e->globalPos(), this ); + } else { + e->accept(); + mainwindow->popupWidgetMenu( e->globalPos(), this, realWidget); + } + } else { + e->accept(); + clearSelection(); + mainwindow->popupFormWindowMenu( e->globalPos(), this ); + } + break; } + default: + break; + } +} + +void FormWindow::handleMousePress( QMouseEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + checkedSelectionsForMove = FALSE; + checkSelectionsTimer->stop(); + if ( !sizePreviewLabel ) { + sizePreviewLabel = new QLabel( this ); + sizePreviewLabel->hide(); + sizePreviewLabel->setBackgroundColor( QColor( 255, 255, 128 ) ); + sizePreviewLabel->setFrameStyle( QFrame::Plain | QFrame::Box ); + } + + switch ( currTool ) { + case POINTER_TOOL: + if ( !isMainContainer( w ) && qstrcmp( w->name(), "central widget" ) != 0 ) { // press on a child widget + // if the clicked widget is not in a layout, raise it + if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) + w->raise(); + if ( ( e->state() & ControlButton ) ) { // with control pressed, always start rubber band selection + drawRubber = TRUE; + currRect = QRect( 0, 0, -1, -1 ); + startRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber ); + break; + } + + bool sel = isWidgetSelected( w ); + if ( !( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) ) { // control not pressed... + if ( !sel ) { // ...and widget no selectted: unselect all + clearSelection( FALSE ); + } else { // ...widget selected + // only if widget has a layout (it is a layout meta widget or a laid out container!), unselect its childs + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout ) { + QObjectList *l = w->queryList( "QWidget" ); + setPropertyShowingBlocked( TRUE ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( !o->isWidgetType() ) + continue; + if ( insertedWidgets.find( (QWidget*)o ) ) + selectWidget( (QWidget*)o, FALSE ); + } + setPropertyShowingBlocked( FALSE ); + delete l; + } + } + qApp->processEvents(); + } + if ( ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) && + sel && e->button() == LeftButton ) { // control pressed and selected, unselect widget + selectWidget( w, FALSE ); + break; + } + + raiseChildSelections( w ); // raise selections and select widget + selectWidget( w ); + + // if widget is laid out, find the first non-laid out super-widget + while ( w->parentWidget() && + ( WidgetFactory::layoutType( w->parentWidget()) != WidgetFactory::NoLayout || !insertedWidgets.find(w) ) ) + w = w->parentWidget(); + + if ( e->button() == LeftButton ) { // left button: store original geometry and more as the widget might start moving + widgetPressed = TRUE; + widgetGeom = QRect( w->pos(), w->size() ); + oldPressPos = w->mapFromGlobal( e->globalPos() ); + origPressPos = oldPressPos; + checkedSelectionsForMove = FALSE; + moving.clear(); + if ( w->parentWidget() && !isMainContainer( w->parentWidget() ) && !isCentralWidget( w->parentWidget() ) ) { + targetContainer = w->parentWidget(); + hadOwnPalette = w->parentWidget()->ownPalette(); + restorePalette = w->parentWidget()->palette(); + } + } + } else { // press was on the formwindow + if ( e->button() == LeftButton ) { // left button: start rubber selection and show formwindow properties + drawRubber = TRUE; + if ( !( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) ) ) { + clearSelection( FALSE ); + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + } + currRect = QRect( 0, 0, -1, -1 ); + startRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber ); + } + } + break; + case CONNECT_TOOL: + case BUDDY_TOOL: + if ( e->button() != LeftButton ) + break; + validForBuddy = FALSE; + if ( currTool == BUDDY_TOOL ) { + if ( !::qt_cast(w) ) + break; + clearSelection( FALSE ); + validForBuddy = TRUE; + mainWindow()->statusBar()->message( tr( "Set buddy for '%1' to..." ).arg( w->name() ) ); + } else { + mainWindow()->statusBar()->message( tr( "Connect '%1' with..." ).arg( w->name() ) ); + } + saveBackground(); + startPos = mapFromGlobal( e->globalPos() ); + currentPos = startPos; + startWidget = designerWidget( w ); + endWidget = startWidget; + beginUnclippedPainter( FALSE ); + drawConnectionLine(); + break; + case ORDER_TOOL: + if ( !isMainContainer( w ) ) { // press on a child widget + orderedWidgets.removeRef( w ); + orderedWidgets.append( w ); + for ( QWidget *wid = orderedWidgets.last(); wid; wid = orderedWidgets.prev() ) { + int i = stackedWidgets.findRef( wid ); + if ( i != -1 ) { + stackedWidgets.removeRef( wid ); + stackedWidgets.insert( 0, wid ); + } + } + QWidgetList oldl = MetaDataBase::tabOrder( this ); + TabOrderCommand *cmd = new TabOrderCommand( tr( "Change Tab Order" ), this, oldl, stackedWidgets ); + cmd->execute(); + commandHistory()->addCommand( cmd, TRUE ); + updateOrderIndicators(); + } + break; + default: // any insert widget tool + if ( e->button() == LeftButton ) { + insertParent = WidgetFactory::containerOfWidget( mainContainer() ); // default parent for new widget is the formwindow + if ( !isMainContainer( w ) ) { // press was not on formwindow, check if we can find another parent + QWidget *wid = w; + for (;;) { + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( wid ) ); + if ( ( WidgetDatabase::isContainer( id ) || wid == mainContainer() ) && + !::qt_cast(wid) && !::qt_cast(wid) ) { + insertParent = WidgetFactory::containerOfWidget( wid ); // found another parent, store it + break; + } else { + wid = wid->parentWidget(); + if ( !wid ) + break; + } + } + } + startRectDraw( w->mapFromGlobal( e->globalPos() ), e->globalPos(), w, Insert ); + } + break; + } +} + +void FormWindow::handleMouseDblClick( QMouseEvent *, QWidget *w ) +{ + CHECK_MAINWINDOW; + switch ( currTool ) { + case ORDER_TOOL: + if ( !isMainContainer( w ) ) { // press on a child widget + orderedWidgets.clear(); + orderedWidgets.append( w ); + for ( QWidget *wid = orderedWidgets.last(); wid; wid = orderedWidgets.prev() ) { + int i = stackedWidgets.findRef( wid ); + if ( i != -1 ) { + stackedWidgets.removeRef( wid ); + stackedWidgets.insert( 0, wid ); + } + } + QWidgetList oldl = MetaDataBase::tabOrder( this ); + TabOrderCommand *cmd = new TabOrderCommand( tr( "Change Tab Order" ), this, oldl, stackedWidgets ); + cmd->execute(); + commandHistory()->addCommand( cmd, TRUE ); + updateOrderIndicators(); + } + default: + if ( !WidgetFactory::isPassiveInteractor( w ) && + ( isMainContainer( w ) || w == this ) ) + mainWindow()->editSource(); + break; + } +} + +void FormWindow::handleMouseMove( QMouseEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + if ( ( e->state() & LeftButton ) != LeftButton ) + return; + + QWidget *newendWidget = endWidget, *oldendWidget = endWidget, *wid; + bool drawRecRect; + switch ( currTool ) { + case POINTER_TOOL: + if ( widgetPressed && allowMove( w ) ) { // we are prepated for a move + + // if widget is laid out, find the first non-laid out super-widget + while ( w->parentWidget() && + ( WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout || !insertedWidgets.find(w ) ) ) + w = w->parentWidget(); + + // calc correct position + QPoint pos = w->mapFromGlobal( e->globalPos() ); + +#if 0 + QPoint mpos = w->mapToParent( pos ); + // check if we are not outside the visible area, else correct coords + if ( mpos.x() < 0 ) + pos.setX( w->mapFromParent( QPoint( 0, mpos.y() ) ).x() ); + if ( mpos.y() < 0 ) + pos.setY( w->mapFromParent( QPoint( mpos.x(), 0 ) ).y() ); + if ( mpos.x() > w->parentWidget()->width() ) + pos.setX( w->mapFromParent( QPoint( w->parentWidget()->width(), mpos.y() ) ).x() ); + if ( mpos.y() > w->parentWidget()->height() ) + pos.setY( w->mapFromParent( QPoint( mpos.x(), w->parentWidget()->height() ) ).y() ); +#endif + + // calc move distance and store it + QPoint d = oldPressPos - pos; + if ( QABS( d.x() ) < grid().x() ) + d.setX( 0 ); + if ( QABS( d.y() ) < grid().y() ) + d.setY( 0 ); + if ( d.x() == 0 ) + pos.setX( oldPressPos.x() ); + if ( d.y() == 0 ) + pos.setY( oldPressPos.y() ); + oldPressPos = pos; + + // snap to grid + int x = widgetGeom.x() - d.x(); + widgetGeom.setX( x ); + x = ( x / grid().x() ) * grid().x(); + int y = widgetGeom.y() - d.y(); + widgetGeom.setY( y ); + y = ( y / grid().y() ) * grid().y(); + QPoint p = w->pos(); + + if ( x - p.x() != 0 || y - p.y() != 0 ) { // if we actually have to move + if ( !checkedSelectionsForMove ) { // if not checked yet, check if the correct widget are selected... + if ( !isWidgetSelected( w ) ) { // and unselect others. Only siblings can be moved at the same time + setPropertyShowingBlocked( TRUE ); + selectWidget( w ); + setPropertyShowingBlocked( FALSE ); + } + checkSelectionsForMove( w ); + } + + // check whether we would have to reparent the selection and highlight the possible new parent container + QMapConstIterator it = moving.begin(); + QWidget* wa = containerAt( e->globalPos(), it.key() ); + if ( wa && !isMainContainer( wa ) && !isCentralWidget( wa ) ) { + wa = WidgetFactory::containerOfWidget( wa ); + // ok, looks like we moved onto a container + + if ( wa != targetContainer ) { + if ( targetContainer ) { + if ( hadOwnPalette ) + targetContainer->setPalette( restorePalette ); + else + targetContainer->unsetPalette(); + } + targetContainer = wa; + hadOwnPalette = wa->ownPalette(); + restorePalette = wa->palette(); + wa->setPaletteBackgroundColor( wa->colorGroup().midlight() ); + } + } + else if ( targetContainer ) { + if( hadOwnPalette ) + targetContainer->setPalette( restorePalette ); + else + targetContainer->unsetPalette(); + targetContainer = 0; + } + + // finally move the selected widgets and show/update preview label + moveSelectedWidgets( x - p.x(), y - p.y() ); + sizePreviewLabel->setText( tr( "%1/%2" ).arg( w->pos().x() ).arg( w->pos().y() ) ); + sizePreviewLabel->adjustSize(); + QRect lg( mapFromGlobal( e->globalPos() ) + QPoint( 16, 16 ), sizePreviewLabel->size() ); + checkPreviewGeometry( lg ); + sizePreviewLabel->setGeometry( lg ); + sizePreviewLabel->raise(); + sizePreviewLabel->show(); +#if defined(Q_WS_WIN32) + windowsRepaintWorkaroundTimer->start( 100, TRUE ); +#endif + } else { // if we don't need to move, do some indication + QRect lg( mapFromGlobal( e->globalPos() ) + QPoint( 16, 16 ), sizePreviewLabel->size() ); + checkPreviewGeometry( lg ); + sizePreviewLabel->move( lg.x(), lg.y() ); + } + + oldPressPos += ( p - w->pos() ); + } else if ( drawRubber ) { // draw rubber if we are in rubber-selection mode + continueRectDraw( mapFromGlobal( e->globalPos() ), e->globalPos(), this, Rubber ); + } + break; + case CONNECT_TOOL: + restoreConnectionLine(); + wid = qApp->widgetAt( e->globalPos(), TRUE ); + if ( wid ) + wid = designerWidget( wid ); + if ( wid && ( isMainContainer( wid ) || insertedWidgets.find( wid ) ) && wid->isVisibleTo( this ) ) + newendWidget = wid; + if ( ::qt_cast(newendWidget) || ::qt_cast(newendWidget) ) + newendWidget = (QWidget*)endWidget; + drawRecRect = newendWidget != endWidget; + if ( newendWidget && + ( isMainContainer( newendWidget ) || insertedWidgets.find( newendWidget ) ) && !isCentralWidget( newendWidget ) ) + endWidget = newendWidget; + mainWindow()->statusBar()->message( tr( "Connect '%1' to '%2'" ).arg( startWidget->name() ). + arg( endWidget->name() ) ); + currentPos = mapFromGlobal( e->globalPos() ); + qApp->processEvents(); + if ( drawRecRect ) + restoreRect( QRect( mapToForm( ( (QWidget*)oldendWidget )->parentWidget(), ( (QWidget*)oldendWidget )->pos() ), + ( (QWidget*)oldendWidget )->size() ) ); + drawConnectionLine(); + break; + case BUDDY_TOOL: + if ( !validForBuddy ) + break; + restoreConnectionLine(); + wid = qApp->widgetAt( e->globalPos(), TRUE ); + if ( wid ) + wid = designerWidget( wid ); + if ( wid && canBeBuddy( wid ) && wid->isVisibleTo( this ) ) + newendWidget = wid; + else + newendWidget = 0; + if ( ::qt_cast(newendWidget) || ::qt_cast(newendWidget) ) + newendWidget = (QWidget*)endWidget; + drawRecRect = newendWidget != endWidget; + if ( !newendWidget ) + endWidget = newendWidget; + else if ( insertedWidgets.find( newendWidget ) && !isCentralWidget( newendWidget ) ) + endWidget = newendWidget; + if ( endWidget ) + mainWindow()->statusBar()->message( tr( "Set buddy '%1' to '%2'" ).arg( startWidget->name() ). + arg( endWidget->name() ) ); + else + mainWindow()->statusBar()->message( tr( "Set buddy '%1' to ..." ).arg( startWidget->name() ) ); + currentPos = mapFromGlobal( e->globalPos() ); + qApp->processEvents(); + if ( drawRecRect && oldendWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)oldendWidget )->parentWidget(), ( (QWidget*)oldendWidget )->pos() ), + ( (QWidget*)oldendWidget )->size() ) ); + drawConnectionLine(); + break; + case ORDER_TOOL: + break; + default: // we are in an insert-widget tool + if ( insertParent ) // draw insert rect + continueRectDraw( w->mapFromGlobal( e->globalPos() ), e->globalPos(), w, Insert ); + break; + } +} + +void FormWindow::handleMouseRelease( QMouseEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + if ( e->button() != LeftButton ) + return; + + switch ( currTool ) { + case POINTER_TOOL: + if ( widgetPressed && allowMove( w ) ) { // we moved the widget + sizePreviewLabel->hide(); + + if ( moving.isEmpty() || w->pos() == *moving.find(w) ) + break; + + // restore targetContainer + if ( targetContainer ) { + if( hadOwnPalette ) + targetContainer->setPalette( restorePalette ); + else + targetContainer->unsetPalette(); + } + + // tell property editor to update + if ( propertyWidget && propertyWidget->isWidgetType() && !isMainContainer( propertyWidget ) ) + emitUpdateProperties( propertyWidget ); + + QMapConstIterator it = moving.begin(); + QWidget *oldParent = it.key()->parentWidget(); + QWidget *newParent = oldParent; + // check whether we have to reparent the selection + QWidget* wa = containerAt( e->globalPos(), it.key() ); + if ( wa ) { + wa = WidgetFactory::containerOfWidget( wa ); + // ok, looks like we moved onto a container + + // check whether we really have different parents. + if ( wa == it.key()->parentWidget() ) + goto make_move_command; + + // break layout if necessary + if ( WidgetFactory::layoutType( wa ) != WidgetFactory::NoLayout ) { + if ( QMessageBox::information( mainWindow(), tr( "Inserting a Widget" ), + tr( "You tried to insert a widget into the " + "layout Container Widget '%1'.\n" + "This is not possible. " + "In order to insert the widget, the layout of '%1'\n" + "must first be broken.\n" + "Break the layout or cancel the operation?" ). + arg( wa->name() ). + arg( wa->name() ), tr( "&Break Layout" ), tr( "&Cancel" ) ) ) + goto make_move_command; // cancel + breakLayout( wa ); + } + + // doesn't need to be a command, the MoveCommand does reparenting too + bool emitSelChanged = FALSE; + for ( QMap::Iterator it = moving.begin(); it != moving.end(); ++it ) { + QWidget *i = it.key(); + if ( !emitSelChanged && ::qt_cast(i) ) { + if ( ::qt_cast(i->parentWidget()) || ::qt_cast(wa) ) + emitSelChanged = TRUE; + if ( !::qt_cast(wa) ) { + MetaDataBase::setPropertyChanged( i, "buttonGroupId", FALSE ); + if ( ::qt_cast(i->parentWidget()) ) + ( (QButtonGroup*)i->parentWidget() )->remove( (QButton*)i ); + } + } + QPoint pos = wa->mapFromGlobal( i->mapToGlobal( QPoint(0,0) ) ); + i->reparent( wa, pos, TRUE ); + raiseSelection( i ); + raiseChildSelections( i ); + widgetChanged( i ); + mainWindow()->objectHierarchy()->widgetRemoved( i ); + mainWindow()->objectHierarchy()->widgetInserted( i ); + } + if ( emitSelChanged ) { + emit showProperties( wa ); + emit showProperties( propertyWidget ); + } + newParent = wa; + } + + make_move_command: + QWidgetList widgets; // collect the widgets and its old and new positions which have been moved + QValueList oldPos, newPos; + for ( it = moving.begin(); it != moving.end(); ++it ) { + widgets.append( it.key() ); + oldPos.append( *it ); + newPos.append( it.key()->pos() ); + } + // add move command, don't execute it, this is just a summary of the operations we did during the move-event handling + commandHistory()->addCommand( new MoveCommand( tr( "Move" ), + this, widgets, + oldPos, newPos, oldParent, newParent ) ); + } else if ( drawRubber ) { // we were drawing a rubber selection + endRectDraw(); // get rid of the rectangle + blockSignals( TRUE ); + selectWidgets(); // select widgets which intersect the rect + blockSignals( FALSE ); + emitSelectionChanged(); // inform about selection changes + if ( propertyWidget ) + emitShowProperties( propertyWidget ); + } + break; + case CONNECT_TOOL: + case BUDDY_TOOL: + restoreConnectionLine(); + if ( startWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)startWidget )->parentWidget(), + ( (QWidget*)startWidget )->pos() ), + ((QWidget*)startWidget )->size() ) ); + if ( endWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)endWidget )->parentWidget(), + ( (QWidget*)endWidget )->pos() ), + ( (QWidget*)endWidget )->size() ) ); + endUnclippedPainter(); + qApp->processEvents(); + + if ( startWidget && endWidget ) { + if ( currTool == CONNECT_TOOL ) + editConnections(); + else if ( currTool == BUDDY_TOOL && validForBuddy && startWidget != endWidget ) { + QString oldBuddy = startWidget->property( "buddy" ).toString(); + if ( oldBuddy.isNull() ) + oldBuddy = ""; + SetPropertyCommand *cmd = new SetPropertyCommand( tr( "Set buddy for " + QString( startWidget->name() ) ), + this, startWidget, mainWindow()->propertyeditor(), + "buddy", startWidget->property( "buddy" ), + endWidget->name(), endWidget->name(), + oldBuddy ); + commandHistory()->addCommand( cmd, TRUE ); + cmd->execute(); + emitUpdateProperties( startWidget ); + } + } + if ( !toolFixed ) + mainwindow->resetTool(); + startWidget = endWidget = 0; + mainWindow()->statusBar()->clear(); + break; + case ORDER_TOOL: + break; + default: // any insert widget tool is active + if ( insertParent ) { // we should insert the new widget now + endRectDraw(); + if ( WidgetFactory::layoutType( insertParent ) != WidgetFactory::NoLayout ) { + if ( QMessageBox::information( mainWindow(), tr( "Inserting a Widget" ), + tr( "You tried to insert a widget into the " + "layout Container Widget '%1'.\n" + "This is not possible. " + "In order to insert the widget, the layout of '%1'\n" + "must first be broken.\n" + "Break the layout or cancel the operation?" ). + arg( insertParent->name() ). + arg( insertParent->name() ), tr( "&Break Layout" ), tr( "&Cancel" ) ) == 0 ) { + breakLayout( insertParent ); + } else { + if ( !toolFixed ) + mainWindow()->resetTool(); + break; + } + } + insertWidget(); // so do it + } + break; + } + widgetPressed = FALSE; + drawRubber = FALSE; + insertParent = 0; + delete buffer; + buffer = 0; +} + +void FormWindow::handleKeyPress( QKeyEvent *e, QWidget *w ) +{ + CHECK_MAINWINDOW; + e->ignore(); + checkSelectionsTimer->stop(); + if ( !checkedSelectionsForMove && + ( e->key() == Key_Left || + e->key() == Key_Right || + e->key() == Key_Up || + e->key() == Key_Down ) && + propertyWidget->isWidgetType() ) + checkSelectionsForMove( (QWidget*)propertyWidget ); + checkSelectionsTimer->start( 1000, TRUE ); + if ( e->key() == Key_Left || e->key() == Key_Right || + e->key() == Key_Up || e->key() == Key_Down ) { + QWidgetList widgets; + QValueList oldPos, newPos; + for ( WidgetSelection *s = selections.first(); s; s = selections.next() ) { + if ( s->isUsed() ) { + int dx = 0, dy = 0; + bool control = e->state() & ControlButton; + + switch ( e->key() ) { + case Key_Left: { + e->accept(); + if ( control ) + dx = -1; + else + dx = -grid().x(); + } break; + case Key_Right: { + e->accept(); + if ( control ) + dx = 1; + else + dx = grid().x(); + } break; + case Key_Up: { + e->accept(); + if ( control ) + dy = -1; + else + dy = -grid().y(); + } break; + case Key_Down: { + e->accept(); + if ( control ) + dy = 1; + else + dy = grid().y(); + } break; + default: + break; + } + + widgets.append( s->widget() ); + oldPos.append( s->widget()->pos() ); + newPos.append( s->widget()->pos() + QPoint( dx, dy ) ); + } + } + if ( !widgets.isEmpty() ) { + MoveCommand *cmd = new MoveCommand( tr( "Move" ), this, + widgets, oldPos, newPos, 0, 0 ); + commandHistory()->addCommand( cmd, TRUE ); + cmd->execute(); + } + } + if ( !e->isAccepted() ) { + QObjectList *l = queryList( "QWidget" ); + if ( !l ) + return; + if ( l->find( w ) != -1 ) + e->accept(); + delete l; + } + +} + +void FormWindow::handleKeyRelease( QKeyEvent *e, QWidget * ) +{ + e->ignore(); +} + +void FormWindow::selectWidget( QObject *o, bool select ) +{ + CHECK_MAINWINDOW; + if ( !o->isWidgetType() ) { + // ########### do QObject stuff + return; + } + + QWidget *w = (QWidget*)o; + + if ( isMainContainer( w ) ) { + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + emitShowProperties( propertyWidget ); + return; + } + + if ( ::qt_cast(mainContainer()) && w == ( (QMainWindow*)mainContainer() )->centralWidget() ) { + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + emitShowProperties( propertyWidget ); + return; + } + + if ( ::qt_cast(o) ) + return; + + if ( select ) { + QObject *opw = propertyWidget; + propertyWidget = w; + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + if ( !isPropertyShowingBlocked() ) + emitShowProperties( propertyWidget ); + WidgetSelection *s = usedSelections.find( w ); + if ( s ) { + s->show(); + return; + } + + for ( WidgetSelection *s2 = selections.first(); s2; s2 = selections.next() ) { + if ( !s2->isUsed() ) { + s = s2; + } + } + + if ( !s ) { + s = new WidgetSelection( this, &usedSelections ); + selections.append( s ); + } + + s->setWidget( w ); + emitSelectionChanged(); + } else { + WidgetSelection *s = usedSelections.find( w ); + if ( s ) + s->setWidget( 0 ); + QObject *opw = propertyWidget; + if ( !usedSelections.isEmpty() ) + propertyWidget = QPtrDictIterator( usedSelections ).current()->widget(); + else + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + if ( !isPropertyShowingBlocked() ) + emitShowProperties( propertyWidget ); + emitSelectionChanged(); + } +} + +QPoint FormWindow::grid() const +{ + if ( !mainWindow() || !mainWindow()->snapGrid() ) + return QPoint( 1, 1 ); + return mainWindow()->grid(); +} + +void FormWindow::updateSelection( QWidget *w ) +{ + WidgetSelection *s = usedSelections.find( w ); + if ( !w->isVisibleTo( this ) ) + selectWidget( w, FALSE ); + else if ( s ) + s->updateGeometry(); +} + +void FormWindow::raiseSelection( QWidget *w ) +{ + WidgetSelection *s = usedSelections.find( w ); + if ( s ) + s->show(); +} + +void FormWindow::repaintSelection( QWidget *w ) +{ + WidgetSelection *s = usedSelections.find( w ); + if ( s ) + s->update(); +} + +void FormWindow::clearSelection( bool changePropertyDisplay ) +{ + QPtrDictIterator it( usedSelections ); + for ( ; it.current(); ++it ) + it.current()->setWidget( 0, FALSE ); + + usedSelections.clear(); + if ( changePropertyDisplay ) { + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + emitShowProperties( propertyWidget ); + } + emitSelectionChanged(); +} + +void FormWindow::startRectDraw( const QPoint &p, const QPoint &global, QWidget *, RectType t ) +{ + QPoint pos( p ); + pos = mapFromGlobal( global ); + oldRectValid = FALSE; + beginUnclippedPainter( TRUE ); + if ( t == Rubber ) + unclippedPainter->setPen( QPen( color0, 1 ) ); + if ( t == Insert ) + rectAnchor = gridPoint( pos ); + else if ( t == Rubber ) + rectAnchor = pos; + currRect = QRect( rectAnchor, QPoint( 0, 0 ) ); + if ( t == Insert ) + drawSizePreview( pos, tr("Use Size Hint") ); +} + +void FormWindow::continueRectDraw( const QPoint &p, const QPoint &global, QWidget *, RectType t ) +{ + QPoint pos =p; + pos = mapFromGlobal( global ); + QPoint p2; + if ( t == Insert ) + p2 = gridPoint( pos ); + else if ( t == Rubber ) + p2 = pos; + QRect r( rectAnchor, p2 ); + r = r.normalize(); + + if ( currRect == r ) { + QString t = tr( "%1/%2" ); + t = t.arg( r.width() - 1 ).arg( r.height() - 1 ); + drawSizePreview( pos, t ); + return; + } + + if ( oldRectValid ) + unclippedPainter->drawRect( currRect ); + if ( r.width() > 1 || r.height() > 1 ) { + oldRectValid = TRUE; + currRect = r; + if ( t == Insert ) { + QString t = tr( "%1/%2" ); + t = t.arg( r.width() - 1 ).arg( r.height() - 1 ); + drawSizePreview( pos, t ); + } + unclippedPainter->setClipRegion( QRegion( rect() ).subtract( QRect( sizePreviewPos, sizePreviewPixmap.size() ) ) ); + unclippedPainter->drawRect( currRect ); + unclippedPainter->setClipping( FALSE ); + } else { + oldRectValid = FALSE; + if ( t == Insert ) + drawSizePreview( pos, tr("Use Size Hint") ); + } +} + +void FormWindow::endRectDraw() +{ + if ( !unclippedPainter ) + return; + + if ( oldRectValid ) + unclippedPainter->drawRect( currRect ); + drawSizePreview( QPoint(-1,-1), QString::null ); + endUnclippedPainter(); +} + +void FormWindow::selectWidgets() +{ + QObjectList *l = mainContainer()->queryList( "QWidget" ); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets[ (void*)o ] ) { + QPoint p = ( (QWidget*)o )->mapToGlobal( QPoint(0,0) ); + p = mapFromGlobal( p ); + QRect r( p, ( (QWidget*)o )->size() ); + if ( r.intersects( currRect ) && !r.contains( currRect ) ) + selectWidget( (QWidget*)o ); + } + } + delete l; + } + emitSelectionChanged(); +} + +bool FormWindow::isWidgetSelected( QObject *w ) +{ + if ( w->isWidgetType() ) + return usedSelections.find( (QWidget*)w ) != 0; + return FALSE; // #### do stuff for QObjects +} + +void FormWindow::moveSelectedWidgets( int dx, int dy ) +{ + QPtrDictIterator it( usedSelections ); + for ( ; it.current(); ++it ) { + WidgetSelection *s = it.current(); + QWidget *w = s->widget(); + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + continue; + w->move( w->x() + dx, w->y() + dy ); + s->updateGeometry(); + updateChildSelections( w ); + } +} + +CommandHistory *FormWindow::commandHistory() +{ + return &commands; +} + +void FormWindow::undo() +{ + commandHistory()->undo(); +} + +void FormWindow::redo() +{ + commandHistory()->redo(); +} + +void FormWindow::raiseChildSelections( QWidget *w ) +{ + QObjectList *l = w->queryList( "QWidget" ); + if ( !l || !l->first() ) { + delete l; + return; + } + + QPtrDictIterator it( usedSelections ); + for ( ; it.current(); ++it ) { + if ( l->findRef( it.current()->widget() ) != -1 ) + it.current()->show(); + } + delete l; +} + +void FormWindow::updateChildSelections( QWidget *w ) +{ + QObjectList *l = w->queryList( "QWidget" ); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + insertedWidgets.find( (QWidget*)o ) ) + updateSelection( (QWidget*)o ); + } + delete l; + } +} + +void FormWindow::checkSelectionsForMove( QWidget *w ) +{ + checkedSelectionsForMove = TRUE; + + QObjectList *l = w->parentWidget()->queryList( "QWidget", 0, FALSE, FALSE ); + moving.clear(); + if ( l ) { + QPtrDictIterator it( usedSelections ); + WidgetSelection *sel; + while ( ( sel = it.current() ) != 0 ) { + if ( it.current()->widget() == mainContainer() ) + continue; + ++it; + if ( l->find( sel->widget() ) == -1 ) { + if ( WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) + sel->setWidget( 0 ); + } else { + if ( WidgetFactory::layoutType( sel->widget()->parentWidget() ) == WidgetFactory::NoLayout ) { + moving.insert( sel->widget(), sel->widget()->pos() ); + sel->widget()->raise(); + raiseChildSelections( sel->widget() ); + raiseSelection( sel->widget() ); + } + } + } + delete l; + } +} + +void FormWindow::deleteWidgets() +{ + CHECK_MAINWINDOW; + QWidgetList widgets; + QPtrDictIterator it( usedSelections ); + for ( ; it.current(); ++it ) { + QWidget *tb = 0; + if ( !( tb = mainWindow()->isAToolBarChild( it.current()->widget() ) ) ) + widgets.append( it.current()->widget() ); + else + ( (QDesignerToolBar*)tb )->removeWidget( it.current()->widget() ); + } + + if ( widgets.isEmpty() ) + return; + + DeleteCommand *cmd = new DeleteCommand( tr( "Delete" ), this, widgets ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::editAdjustSize() +{ + QPtrList commands; + QWidgetList widgets = selectedWidgets(); + if ( widgets.isEmpty() ) { + QRect oldr = geometry(); + mainContainer()->adjustSize(); + resize( mainContainer()->size() ); + // check whether our own size constraint hit us + if ( size() != mainContainer()->size() ) + mainContainer()->resize( size() ); + QRect nr = geometry(); + if ( oldr != nr ) { + ResizeCommand *cmd = new ResizeCommand( tr( "Adjust Size" ), this, this, oldr, nr ); + commandHistory()->addCommand( cmd ); + } + return; + } + for ( QWidget* w = widgets.first(); w; w = widgets.next() ) { + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + continue; + QRect oldr = w->geometry(); + w->adjustSize(); + QRect nr = w->geometry(); + if ( oldr != nr ) + commands.append( new ResizeCommand( tr("Adjust Size"), this, w, oldr, nr ) ); + } + + if ( commands.isEmpty() ) + return; + for ( WidgetSelection *s = selections.first(); s; s = selections.next() ) + s->updateGeometry(); + + MacroCommand *cmd = new MacroCommand( tr( "Adjust Size" ), this, commands ); + commandHistory()->addCommand( cmd ); +} + + +QWidgetList FormWindow::selectedWidgets() const +{ + QWidgetList widgets; + QPtrDictIterator it( usedSelections ); + for ( ; it.current(); ++it ) + widgets.append( it.current()->widget() ); + return widgets; +} + +void FormWindow::widgetChanged( QObject *w ) +{ + if ( w->isWidgetType() ) + updateSelection( (QWidget*)w ); + // ########## do QObject stuff +} + +QLabel *FormWindow::sizePreview() const +{ + if ( !sizePreviewLabel ) { + ( (FormWindow*)this )->sizePreviewLabel = new QLabel( (FormWindow*)this ); + ( (FormWindow*)this )->sizePreviewLabel->hide(); + ( (FormWindow*)this )->sizePreviewLabel->setBackgroundColor( QColor( 255, 255, 128 ) ); + ( (FormWindow*)this )->sizePreviewLabel->setFrameStyle( QFrame::Plain | QFrame::Box ); + } + return sizePreviewLabel; +} + +void FormWindow::invalidCheckedSelections() +{ + checkedSelectionsForMove = FALSE; +} + +void FormWindow::checkPreviewGeometry( QRect &r ) +{ + if ( !rect().contains( r ) ) { + if ( r.left() < rect().left() ) + r.moveTopLeft( QPoint( 0, r.top() ) ); + if ( r.right() > rect().right() ) + r.moveBottomRight( QPoint( rect().right(), r.bottom() ) ); + if ( r.top() < rect().top() ) + r.moveTopLeft( QPoint( r.left(), rect().top() ) ); + if ( r.bottom() > rect().bottom() ) + r.moveBottomRight( QPoint( r.right(), rect().bottom() ) ); + } +} + +void FormWindow::focusInEvent( QFocusEvent * ){ + + if (ff) + ff->checkTimeStamp(); +} + +void FormWindow::focusOutEvent( QFocusEvent * ) +{ + if ( propertyWidget && !isMainContainer( propertyWidget ) && !isWidgetSelected( propertyWidget ) ) { + QObject *opw = propertyWidget; + propertyWidget = mainContainer(); + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + } +} + +void FormWindow::resizeEvent( QResizeEvent *e ) +{ + QWidget::resizeEvent( e ); + if ( currTool == ORDER_TOOL ) + repositionOrderIndicators(); + if ( isVisible() ) + formFile()->setModified( TRUE, FormFile::WFormWindow ); + +#if defined(Q_WS_WIN32) + windowsRepaintWorkaroundTimer->start( 100, TRUE ); +#endif +} + +void FormWindow::windowsRepaintWorkaroundTimerTimeout() +{ +#if defined(Q_WS_WIN32) + QObjectList *l = queryList( "QWidget" ); + for ( QObject *o = l->first(); o; o = l->next() ) { + flickerfree_update( (QWidget*)o ); + } + flickerfree_update( this ); + delete l; +#endif +} + +QPtrDict *FormWindow::widgets() +{ + return &insertedWidgets; +} + +QWidget *FormWindow::designerWidget( QObject *o ) const +{ + if ( !o || !o->isWidgetType() ) + return 0; + QWidget *w = (QWidget*)o; + while ( w && !isMainContainer( w ) && !insertedWidgets[ (void*)w ] || isCentralWidget( w ) ) + w = (QWidget*)w->parent(); + return w; +} + +void FormWindow::emitShowProperties( QObject *w ) +{ + if ( w ) { + QObject *opw = propertyWidget; + propertyWidget = w; + if ( opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + } + showPropertiesTimer->stop(); + showPropertiesTimer->start( 0, TRUE ); +} + +void FormWindow::emitUpdateProperties( QObject *w ) +{ + if ( w == propertyWidget ) { + updatePropertiesTimer->stop(); + updatePropertiesTimer->start( 0, TRUE ); + } +} + +void FormWindow::emitSelectionChanged() +{ + selectionChangedTimer->stop(); + selectionChangedTimer->start( 0, TRUE ); +} + +void FormWindow::updatePropertiesTimerDone() +{ + CHECK_MAINWINDOW; + if ( propertyWidget && mainWindow()->formWindow() == this ) + emit updateProperties( propertyWidget ); +} + +void FormWindow::showPropertiesTimerDone() +{ + CHECK_MAINWINDOW; + if ( propertyWidget && mainWindow()->formWindow() == this ) + emit showProperties( propertyWidget ); +} + +void FormWindow::selectionChangedTimerDone() +{ + emit selectionChanged(); +} + +void FormWindow::currentToolChanged() +{ + CHECK_MAINWINDOW; + toolFixed = FALSE; + int t = mainwindow->currentTool(); + if ( currTool == t && t != ORDER_TOOL ) + return; + + // tool cleanup + switch ( currTool ) { + case ORDER_TOOL: + hideOrderIndicators(); + break; + case CONNECT_TOOL: + case BUDDY_TOOL: + restoreConnectionLine(); + if ( startWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)startWidget )->parentWidget(), + ( (QWidget*)startWidget )->pos() ), + ( (QWidget*)startWidget )->size() ) ); + if ( endWidget ) + restoreRect( QRect( mapToForm( ( (QWidget*)endWidget )->parentWidget(), + ( (QWidget*)endWidget )->pos() ), + ( (QWidget*)endWidget )->size() ) ); + endUnclippedPainter(); + break; + case POINTER_TOOL: + break; + default: + if ( insertParent ) + endRectDraw(); + break; + } + + startWidget = endWidget = 0; + widgetPressed = FALSE; + drawRubber = FALSE; + insertParent = 0; + delete buffer; + buffer = 0; + + currTool = t; + + if ( hasFocus() ) + clearSelection( FALSE ); + + mainWindow()->statusBar()->clear(); + + // tool setup + switch ( currTool ) { + case POINTER_TOOL: + if ( propertyWidget && !isMainContainer( propertyWidget ) && !isWidgetSelected( propertyWidget ) ) + emitShowProperties( mainContainer() ); + restoreCursors( this, this ); + break; + case ORDER_TOOL: + if ( mainWindow()->formWindow() == this ) { + mainWindow()->statusBar()->message( tr( "Click widgets to change the tab order...") ); + orderedWidgets.clear(); + showOrderIndicators(); + if ( mainWindow()->formWindow() == this ) + emitShowProperties( mainContainer() ); + setCursorToAll( ArrowCursor, this ); + } + break; + case CONNECT_TOOL: + case BUDDY_TOOL: + if ( currTool == CONNECT_TOOL ) + mainWindow()->statusBar()->message( tr( "Drag a line to create a connection...") ); + else + mainWindow()->statusBar()->message( tr( "Drag a line to set a buddy...") ); + setCursorToAll( CrossCursor, this ); + if ( mainWindow()->formWindow() == this ) + emitShowProperties( mainContainer() ); + break; + default: + mainWindow()->statusBar()->message( tr( "Click on the form to insert a %1..." ).arg( WidgetDatabase::toolTip( currTool ).lower() ) ); + setCursorToAll( CrossCursor, this ); + if ( mainWindow()->formWindow() == this ) + emitShowProperties( mainContainer() ); + break; + } +} + +void FormWindow::showOrderIndicators() +{ + hideOrderIndicators(); + orderIndicators.setAutoDelete( TRUE ); + QObjectList *l = mainContainer()->queryList( "QWidget" ); + stackedWidgets = MetaDataBase::tabOrder( this ); + if ( l ) { + int order = 1; + for ( QObject *o = l->first(); o; o = l->next() ) { + QWidget* w = (QWidget*) o; + if ( w->isShown() && + insertedWidgets[ (void*)w ] && + w->focusPolicy() != NoFocus ) { + OrderIndicator* ind = new OrderIndicator( order++, w, this ); + orderIndicators.append( ind ); + if ( stackedWidgets.findRef( w ) == -1 ) + stackedWidgets.append( w ); + } + } + delete l; + } + updateOrderIndicators(); +} + +void FormWindow::hideOrderIndicators() +{ + orderIndicators.clear(); +} + +void FormWindow::updateOrderIndicators() +{ + int order = 1; + for ( QWidget *w = stackedWidgets.first(); w; w = stackedWidgets.next() ) { + for ( OrderIndicator* i = orderIndicators.first(); i; i = orderIndicators.next() ) + i->setOrder( order, w ); + order++; + } +} + +void FormWindow::repositionOrderIndicators() +{ + for ( OrderIndicator* i = orderIndicators.first(); i; i = orderIndicators.next() ) + i->reposition(); +} + + +void FormWindow::updateUndoInfo() +{ + commandHistory()->emitUndoRedo(); +} + +bool FormWindow::checkCustomWidgets() +{ + QStringList missingCustomWidgets; + QPtrDictIterator it( insertedWidgets ); + for ( ; it.current(); ++it ) { + if ( it.current()->isA( "CustomWidget" ) ) { + QString className = WidgetFactory::classNameOf( it.current() ); + if ( !MetaDataBase::hasCustomWidget( className ) ) + missingCustomWidgets << className; + } + } + + if ( !missingCustomWidgets.isEmpty() ) { + QString txt = tr( "The following custom widgets are used in '%1',\n" + "but are not known to Qt Designer:\n" ).arg( name() ); + for ( QStringList::Iterator sit = missingCustomWidgets.begin(); sit != missingCustomWidgets.end(); ++sit ) + txt += " " + *sit + "\n"; + txt += "If you save this form and generate code for it using uic, \n" + "the generated code will not compile.\n" + "Do you want to save this form now?"; + if ( QMessageBox::information( mainWindow(), tr( "Save Form" ), txt ) == 1 ) + return FALSE; + } + return TRUE; +} + +void FormWindow::setPropertyShowingBlocked( bool b ) +{ + propShowBlocked = b; +} + +bool FormWindow::isPropertyShowingBlocked() const +{ + return propShowBlocked; +} + +int FormWindow::numSelectedWidgets() const +{ + return usedSelections.count(); +} + +QString FormWindow::copy() +{ + CHECK_MAINWINDOW_VALUE( QString::null ); + Resource resource( mainWindow() ); + resource.setWidget( this ); + return resource.copy(); +} + +void FormWindow::lowerWidgets() +{ + QWidgetList widgets; + QPtrDictIterator it( usedSelections ); + for ( ; it.current(); ++it ) + widgets.append( it.current()->widget() ); + + LowerCommand *cmd = new LowerCommand( tr( "Lower" ), this, widgets ); + cmd->execute(); + commandHistory()->addCommand( cmd ); +} + +void find_accel( const QString &txt, QMap &accels, QWidget *w ) +{ + int i = txt.find( "&" ); + if ( i == -1 ) + return; + QChar c = txt[ i + 1 ]; + if ( c.isNull() || c == '&' ) + return; + c = c.lower(); + QMap::Iterator it = accels.find( c ); + if ( it == accels.end() ) { + QWidgetList wl; + wl.append( w ); + accels.insert( c, wl ); + } else { + QWidgetList *wl = &*it; + wl->append( w ); + } +} + +void FormWindow::checkAccels() +{ + CHECK_MAINWINDOW; + QMap accels; + QObjectList *l = mainContainer()->queryList( "QWidget" ); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets[ (void*)o ] ) { + QWidget *w = (QWidget*)o; + const QMetaProperty* text = + w->metaObject()->property( w->metaObject()->findProperty( "text", TRUE ), TRUE ); + const QMetaProperty* title = + w->metaObject()->property( w->metaObject()->findProperty( "title", TRUE ), TRUE ); + const QMetaProperty* pageTitle = + w->metaObject()->property( w->metaObject()->findProperty( "pageTitle", TRUE ), TRUE ); + if ( text ) + find_accel( w->property( "text" ).toString(), accels, w ); + if ( title ) + find_accel( w->property( "title" ).toString(), accels, w ); + if ( pageTitle ) + find_accel( w->property( "pageTitle" ).toString(), accels, w ); + } else if ( ::qt_cast(o) ) { + ((MenuBarEditor *)o)->checkAccels( accels ); + } + } + delete l; + } + + bool ok = TRUE; + QWidget *wid; + for ( QMap::Iterator it = accels.begin(); it != accels.end(); ++it ) { + if ( (*it).count() > 1 ) { + ok = FALSE; + switch ( QMessageBox::information( mainWindow(), tr( "Check Accelerators" ), + tr( "Accelerator '%1' is used %2 times." + ).arg( it.key().upper() ).arg( (*it).count() ), + tr( "&Select" ), + tr( "&Cancel" ), QString::null, 2 ) ) { + case 0: // select + clearSelection( FALSE ); + for ( wid = (*it).first(); wid; wid = (*it).next() ) + selectWidget( wid, TRUE ); + return; + case 1: // cancel + return; + } + } + } + + if ( ok ) + QMessageBox::information( mainWindow(), tr( "Check Accelerators" ), + tr( "No accelerator is used more than once." ) ); +} + +void FormWindow::raiseWidgets() +{ + QWidgetList widgets; + QPtrDictIterator it( usedSelections ); + for ( ; it.current(); ++it ) + widgets.append( it.current()->widget() ); + + RaiseCommand *cmd = new RaiseCommand( tr( "Raise" ), this, widgets ); + cmd->execute(); + commandHistory()->addCommand( cmd ); +} + +void FormWindow::paste( const QString &cb, QWidget *parent ) +{ + CHECK_MAINWINDOW; + Resource resource( mainWindow() ); + resource.setWidget( this ); + resource.paste( cb, parent ); +} + +void FormWindow::selectAll() +{ + checkedSelectionsForMove = FALSE; + blockSignals( TRUE ); + QObjectList *l = mainContainer()->queryList( "QWidget" ); + if ( l ) { + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets[ (void*)o ] ) { + selectWidget( (QWidget*)o ); + } + } + delete l; + } + + blockSignals( FALSE ); + emitSelectionChanged(); + if ( propertyWidget ) + emitShowProperties( propertyWidget ); + emitSelectionChanged(); +} + +void FormWindow::layoutHorizontal() +{ + QWidgetList widgets( selectedWidgets() ); + LayoutHorizontalCommand *cmd = new LayoutHorizontalCommand( tr( "Lay out horizontally" ), + this, mainContainer(), 0, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutVertical() +{ + QWidgetList widgets( selectedWidgets() ); + LayoutVerticalCommand *cmd = new LayoutVerticalCommand( tr( "Lay out vertically" ), + this, mainContainer(), 0, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutHorizontalSplit() +{ + QWidgetList widgets( selectedWidgets() ); + LayoutHorizontalSplitCommand *cmd = new LayoutHorizontalSplitCommand( tr( "Lay out horizontally (in splitter)" ), + this, mainContainer(), 0, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutVerticalSplit() +{ + QWidgetList widgets( selectedWidgets() ); + LayoutVerticalSplitCommand *cmd = new LayoutVerticalSplitCommand( tr( "Lay out vertically (in splitter)" ), + this, mainContainer(), 0, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutGrid() +{ + int xres = grid().x(); + int yres = grid().y(); + + QWidgetList widgets( selectedWidgets() ); + LayoutGridCommand *cmd = new LayoutGridCommand( tr( "Lay out in a grid" ), + this, mainContainer(), 0, widgets, xres, yres ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutHorizontalContainer( QWidget *w ) +{ + if ( w == this ) + w = mainContainer(); + QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children(); + if ( !l ) + return; + QWidgetList widgets; + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) ) + widgets.append( (QWidget*)o ); + } + LayoutHorizontalCommand *cmd = new LayoutHorizontalCommand( tr( "Lay out children horizontally" ), + this, mainContainer(), w, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutVerticalContainer( QWidget *w ) +{ + if ( w == this ) + w = mainContainer(); + QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children(); + if ( !l ) + return; + QWidgetList widgets; + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) ) + widgets.append( (QWidget*)o ); + } + LayoutVerticalCommand *cmd = new LayoutVerticalCommand( tr( "Lay out children vertically" ), + this, mainContainer(), w, widgets ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::layoutGridContainer( QWidget *w ) +{ + if ( w == this ) + w = mainContainer(); + int xres = grid().x(); + int yres = grid().y(); + + QObjectList *l = (QObjectList*)WidgetFactory::containerOfWidget(w)->children(); + if ( !l ) + return; + QWidgetList widgets; + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) ) + widgets.append( (QWidget*)o ); + } + LayoutGridCommand *cmd = new LayoutGridCommand( tr( "Lay out children in a grid" ), + this, mainContainer(), w, widgets, xres, yres ); + clearSelection( FALSE ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void FormWindow::breakLayout( QWidget *w ) +{ + if ( w == this ) + w = mainContainer(); + w = WidgetFactory::containerOfWidget( w ); + QPtrList commands; + + for (;;) { + if ( !w || w == this ) + break; + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout && + WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) { + Command *cmd = breakLayoutCommand( w ); + if ( cmd ) + commands.insert( 0, cmd ); + if ( !::qt_cast(w) && !::qt_cast(w) ) + break; + } + w = w->parentWidget(); + } + + if ( commands.isEmpty() ) + return; + + clearSelection( FALSE ); + MacroCommand *cmd = new MacroCommand( tr( "Break Layout" ), this, commands ); + commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +BreakLayoutCommand *FormWindow::breakLayoutCommand( QWidget *w ) +{ + CHECK_MAINWINDOW_VALUE( 0 ); + QObjectList *l = (QObjectList*)w->children(); + if ( !l ) + return 0; + + QWidgetList widgets; + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + !mainWindow()->isAToolBarChild( (QWidget*)o ) && + ( (QWidget*)o )->isVisibleTo( this ) && + insertedWidgets.find( (QWidget*)o ) ) + widgets.append( (QWidget*)o ); + } + return new BreakLayoutCommand( tr( "Break Layout" ), this, WidgetFactory::widgetOfContainer( w ), widgets ); +} + +int FormWindow::numVisibleWidgets() const +{ + QPtrDictIterator it( insertedWidgets ); + int visible = 0; + for ( ; it.current(); ++it ) { + if ( it.current()->isVisibleTo( (FormWindow*)this ) ) + visible++; + } + return visible; +} + +bool FormWindow::hasInsertedChildren( QWidget *w ) const +{ + if ( !w ) + return FALSE; + w = WidgetFactory::containerOfWidget( w ); + if ( !w ) + return FALSE; + QObjectList *l = w->queryList( "QWidget" ); + if ( !l || !l->first() ) { + delete l; + return FALSE; + } + + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o->isWidgetType() && + ( (QWidget*)o )->isVisibleTo( (FormWindow*)this ) && + insertedWidgets.find( (QWidget*)o ) ) { + delete l; + return TRUE; + } + } + + delete l; + return FALSE; +} + +bool FormWindow::allowMove( QWidget *w ) +{ + w = w->parentWidget(); + while ( w ) { + if ( ( isMainContainer( w ) || insertedWidgets.find( w ) ) && WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) + return TRUE; + w = w->parentWidget(); + } + return FALSE; +} + + +void FormWindow::editConnections() +{ + CHECK_MAINWINDOW; + buffer = 0; + if ( !startWidget || !endWidget ) + return; + + ConnectionDialog dlg( mainwindow ); + mainWindow()->statusBar()->message( tr( "Edit connections...") ); + dlg.addConnection( startWidget, endWidget, QString::null, QString::null ); + QTimer::singleShot( 0, &dlg, SLOT(ensureConnectionVisible()) ); + dlg.exec(); +} + +void FormWindow::saveBackground() +{ + if ( buffer ) + delete buffer; + buffer = new QPixmap( width(), height() ); + *buffer = QPixmap::grabWindow( winId() ); +} + +void FormWindow::restoreConnectionLine() +{ + if (!unclippedPainter || !buffer) // designer will occasionally crash if buffer is not tested to be non-zero + return; + + int a =QABS( startPos.x() - currentPos.x() ); + int b = QABS( startPos.y() - currentPos.y() ); + QRect r( startPos, currentPos ); + + if ( a < 32 || b < 32 ) { // special case: vertical or horizontal line + r = r.normalize(); + unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer, + r.x() - 2, r.y() - 2, r.width() + 4, r.height() + 4 ); + return; + } + + if ( a <= 0 ) + a = 1; + if ( b <= 0 ) + b = 1; + int w, h; + if ( b > a ) { + h = 64; + w = ( a * h ) / b; + } else { + w = 64; + h = ( b * w ) / a; + } + + int dx = 2 * w / 3; + int dy = 2 * h / 3; + QPoint p( startPos ); + + if ( r.x() > r.right() ) { + dx = dx * -1; + p.setX( p.x() - 64 ); + r.moveBy( -64, 0 ); + } + if ( r.y() > r.bottom() ) { + dy = dy * -1; + p.setY( p.y() - 64 ); + r.moveBy( 0, -64 ); + } + + w = h = 64; + r = r.normalize(); + while ( r.contains( p ) ) { + unclippedPainter->drawPixmap( p, *buffer, QRect( p, QSize( w, h ) ) ); + unclippedPainter->setPen( red ); + p.setX( p.x() + dx ); + p.setY( p.y() + dy ); + } + + unclippedPainter->drawPixmap( startPos.x() - 10, startPos.y() - 10, *buffer, + startPos.x() - 10, startPos.y() - 10, 20, 20 ); +} + +void FormWindow::restoreRect( const QRect &rect ) +{ + if (!unclippedPainter || !buffer) + return; + + QRect r( rect ); + r = r.normalize(); + + r = QRect( r.x() + 2, r.y() + 2, r.width() - 4, r.height() - 4 ); + + unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer, r.x() - 2, r.y() - 2, r.width() + 4, 4 ); + unclippedPainter->drawPixmap( r.x() - 2, r.y() - 2, *buffer, r.x() - 2, r.y() - 2, 4, r.height() + 4 ); + unclippedPainter->drawPixmap( r.x() - 2, r.y() + r.height() - 3, *buffer, r.x() - 2, r.y() + r.height() - 3, r.width() + 4, 5 ); + unclippedPainter->drawPixmap( r.x() + r.width() - 2, r.y(), *buffer, r.x() + r.width() - 2, r.y(), 4, r.height() + 4 ); +} + +void FormWindow::drawConnectionLine() +{ + if ( !unclippedPainter ) + return; + + unclippedPainter->setPen( QPen( white, 2 ) ); + unclippedPainter->drawLine( startPos, currentPos ); + if ( validForBuddy ) + unclippedPainter->setPen( QPen( darkRed, 1 ) ); + else + unclippedPainter->setPen( QPen( darkCyan, 1 ) ); + unclippedPainter->drawLine( startPos, currentPos ); + + if ( validForBuddy ) + unclippedPainter->setPen( QPen( darkGreen, 1 ) ); + else + unclippedPainter->setPen( QPen( magenta, 1 ) ); + if ( startWidget ) { + QWidget *s = (QWidget*)startWidget; + QPoint p = mapToForm( s, QPoint(0,0) ); + unclippedPainter->drawRect( QRect( p + QPoint( 2, 2 ), s->size() - QSize( 4, 4 ) ) ); + } + if ( endWidget ) { + QWidget *e = (QWidget*)endWidget; + QPoint p = mapToForm( e, QPoint(0,0) ); + unclippedPainter->drawRect( QRect( p + QPoint( 2, 2 ), e->size() - QSize( 4, 4 ) ) ); + } +} + +QString FormWindow::fileName() const +{ + return ff->absFileName(); +} + +void FormWindow::setFileName( const QString &fn ) +{ + ff->setFileName( fn ); + emit fileNameChanged( ff->fileName(), this ); +} + +void FormWindow::modificationChanged( bool m ) +{ + emit modificationChanged( m, this ); + emit modificationChanged( m, ff->fileName() ); +} + +bool FormWindow::unify( QObject *w, QString &s, bool changeIt ) +{ + bool found = !isMainContainer( w ) && qstrcmp( name(), s.latin1() ) == 0; + if ( !found ) { + QString orig = s; + int num = 1; + QPtrDictIterator it( insertedWidgets ); + for ( ; it.current();) { + if ( it.current() != w && + qstrcmp( it.current()->name(), s.latin1() ) == 0 ) { + found = TRUE; + if ( !changeIt ) + break; + s = orig + "_" + QString::number( ++num ); + it.toFirst(); + } else { + ++it; + } + } + if ( !found ) { + QPtrList al; + QAction *a = 0; + for ( a = actions.first(); a; a = actions.next() ) { + QObjectList *l = a->queryList( "QAction" ); + al.append( a ); + for ( QObject *ao = l->first(); ao; ao = l->next() ) + al.append( (QAction*)ao ); + delete l; + } + for ( a = al.first(); a; a = al.next() ) { + if ( a != w && + qstrcmp( a->name(), s.latin1() ) == 0 ) { + found = TRUE; + if ( !changeIt ) + break; + s = orig + "_" + QString::number( ++num ); + a = actions.first(); + } + } + } + if ( ::qt_cast(mainContainer()) && !found ) { + QObjectList *l = mainContainer()->queryList( "PopupMenuEditor" ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o != w && + qstrcmp ( o->name(), s.latin1() ) == 0 ) { + found = TRUE; + if ( !changeIt ) + break; + s = orig + "_" + QString::number( ++num ); + o = l->first(); + } + } + delete l; + } + if ( ::qt_cast(mainContainer()) ) { + if ( !found ) { + QObjectList *l = mainContainer()->queryList( "QDockWindow", 0, TRUE ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o != w && + qstrcmp( o->name(), s.latin1() ) == 0 ) { + found = TRUE; + if ( !changeIt ) + break; + s = orig + "_" + QString::number( ++num ); + o = l->first(); + } + } + delete l; + } + } + } + + if ( !found ) + return TRUE; + return FALSE; +} + +bool FormWindow::isCustomWidgetUsed( MetaDataBase::CustomWidget *w ) +{ + QPtrDictIterator it( insertedWidgets ); + for ( ; it.current(); ++it ) { + if ( it.current()->isA( "CustomWidget" ) ) { + if ( qstrcmp( WidgetFactory::classNameOf( it.current() ), w->className.utf8() ) == 0 ) + return TRUE; + } + } + + return FALSE; +} + +bool FormWindow::isDatabaseWidgetUsed() const +{ +#ifndef QT_NO_SQL + QStringList dbClasses; + dbClasses << "QDataTable"; // add more here + QPtrDictIterator it( insertedWidgets ); + for ( ; it.current(); ++it ) { + QString c( it.current()->className() ); + if ( dbClasses.contains( c ) > 0 ) { + return TRUE; + } + } +#endif + return FALSE; +} + +bool FormWindow::isDatabaseAware() const +{ +#ifndef QT_NO_SQL + if ( QString(mContainer->className()) == "QDesignerDataBrowser" || QString(mContainer->className()) == "QDesignerDataView" ) + return TRUE; + return isDatabaseWidgetUsed(); +#else + return FALSE; +#endif +} + +void FormWindow::visibilityChanged() +{ + if ( currTool != ORDER_TOOL ) { + emitUpdateProperties( currentWidget() ); + } else { + updateOrderIndicators(); + repositionOrderIndicators(); + } +} + + +/*! + Maps \a pos in \a w's coordinates to the form's coordinate system. + + This is the equivalent to mapFromGlobal(w->mapToGlobal(pos) ) but + avoids the two roundtrips to the X-Server on Unix/X11. + */ +QPoint FormWindow::mapToForm( const QWidget* w, const QPoint& pos ) const +{ + QPoint p = pos; + const QWidget* i = w; + while ( i && !i->isTopLevel() && !isMainContainer( (QWidget*)i ) ) { + p = i->mapToParent( p ); + i = i->parentWidget(); + } + return mapFromGlobal( w->mapToGlobal( pos ) ); +} + +static int widgetDepth( QWidget *w ) +{ + int d = -1; + while ( w && !w->isTopLevel() ) { + d++; + w = w->parentWidget(); + } + + return d; +} + +static bool isChildOf( QWidget *c, QWidget *p ) +{ + while ( c && !c->isTopLevel() ) { + if ( c == p ) + return TRUE; + c = c->parentWidget(); + } + return FALSE; +} + +QWidget *FormWindow::containerAt( const QPoint &pos, QWidget *notParentOf ) +{ + QPtrDictIterator it( insertedWidgets ); + QWidget *container = 0; + int depth = -1; + QWidgetList selected = selectedWidgets(); + if ( rect().contains( mapFromGlobal( pos ) ) ) { + container = mainContainer(); + depth = widgetDepth( container ); + } + + for ( ; it.current(); ++it ) { + if ( ::qt_cast(it.current()) + || ::qt_cast(it.current()) ) + continue; + if ( !it.current()->isVisibleTo( this ) ) + continue; + if ( selected.find( it.current() ) != -1 ) + continue; + if ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( it.current() ) ) ) && + it.current() != mainContainer() ) + continue; + + // the rectangles of all ancestors of the container must contain the insert position + QWidget *w = it.current(); + while ( w && !w->isTopLevel() ) { + if ( !w->rect().contains( ( w->mapFromGlobal( pos ) ) ) ) + break; + w = w->parentWidget(); + } + if ( !( w == 0 || w->isTopLevel() ) ) continue; // we did not get through the full while loop + + int wd = widgetDepth( it.current() ); + if ( wd == depth && container ) { + if ( ( (QObjectList*)it.current()->parentWidget()->children() )->find( it.current() ) > + ( (QObjectList*)container->parentWidget()->children() )->find( container ) ) + wd++; + } + if ( wd > depth && !isChildOf( it.current(), notParentOf ) ) { + depth = wd; + container = it.current(); + } + } + + return container; +} + +bool FormWindow::isMainContainer( QObject *w ) const +{ + return w && w->isWidgetType() && ( w == (QWidget*)this || w == mainContainer() ); +} + +void FormWindow::setMainContainer( QWidget *w ) +{ + bool resetPropertyWidget = isMainContainer( propertyWidget ); + if ( mContainer ) + insertedWidgets.remove( mContainer ); + if ( propertyWidget == mContainer ) + propertyWidget = 0; + delete mContainer; + mContainer = w; + insertedWidgets.insert( mContainer, mContainer ); + delete layout(); + QHBoxLayout *l = new QHBoxLayout( this ); + l->addWidget( w ); + if ( resetPropertyWidget ) { + QObject *opw = propertyWidget; + propertyWidget = mContainer; + if ( opw && opw->isWidgetType() ) + repaintSelection( (QWidget*)opw ); + } + if ( project() ) { + LanguageInterface *iface = MetaDataBase::languageInterface( project()->language() ); + if ( iface && !project()->isCpp() && !isFake() ) { + if ( !MetaDataBase::hasFunction( this, "init()" ) ) + MetaDataBase::addFunction( this, "init()", "", "private", "function", + project()->language(), "void" ); + if ( !MetaDataBase::hasFunction( this, "destroy()" ) ) + MetaDataBase::addFunction( this, "destroy()", "", "private", "function", + project()->language(), "void" ); + if ( !MetaDataBase::hasConnection( this, mainContainer(), "shown()", mainContainer(), "init" ) ) + MetaDataBase::addConnection( this, mainContainer(), "shown()", mainContainer(), "init" ); + if ( !MetaDataBase::hasConnection( this, mainContainer(), "destroyed()", mainContainer(), "destroy" ) ) + MetaDataBase::addConnection( this, mainContainer(), "destroyed()", + mainContainer(), "destroy" ); + } + } +} + +bool FormWindow::savePixmapInline() const +{ + return pixInline; +} + +bool FormWindow::savePixmapInProject() const +{ + return pixProject; +} + +QString FormWindow::pixmapLoaderFunction() const +{ + return pixLoader; +} + +void FormWindow::setSavePixmapInline( bool b ) +{ + pixInline = b; + if ( b ) + pixProject = FALSE; +} + +void FormWindow::setSavePixmapInProject( bool b ) +{ + pixProject = b; + if ( b ) + pixInline = FALSE; +} + +void FormWindow::setPixmapLoaderFunction( const QString &func ) +{ + pixLoader = func; +} + +void FormWindow::setActiveObject( QObject *o ) +{ + emitShowProperties( o ); + propertyWidget = o; +} + +void FormWindow::setProject( Project *pro ) +{ + proj = pro; +} + +Project *FormWindow::project() const +{ + return proj; +} + +QAction *FormWindow::findAction( const QString &name ) +{ + for ( QAction *a = actionList().first(); a; a = actionList().next() ) { + if ( QString( a->name() ) == name ) + return a; + QAction *ac = (QAction*)a->child( name.latin1(), "QAction" ); + if ( ac ) + return ac; + } + return 0; +} + +void FormWindow::killAccels( QObject *top ) +{ + QObjectList *l = top->queryList( "QAccel" ); + if ( !l ) + return; + for ( QObject *o = l->first(); o; o = l->next() ) + ( (QAccel*)o )->setEnabled( FALSE ); + delete l; +} + +DesignerFormWindow *FormWindow::iFace() +{ + if ( !iface ) + iface = new DesignerFormWindowImpl( this ); + return iface; +} + +bool FormWindow::isCentralWidget( QObject *w ) const +{ + if ( !::qt_cast(mainContainer()) ) + return FALSE; + return w == ( (QMainWindow*)mainContainer() )->centralWidget(); +} + +int FormWindow::layoutDefaultSpacing() const +{ + return defSpacing; +} + +int FormWindow::layoutDefaultMargin() const +{ + return defMargin; +} + +void FormWindow::setLayoutDefaultSpacing( int s ) +{ + defSpacing = s; +} + +void FormWindow::setLayoutDefaultMargin( int s ) +{ + defMargin = s; +} + +void FormWindow::setSpacingFunction( const QString &funct ) +{ + spacFunction = funct; +} + +QString FormWindow::spacingFunction() const +{ + return spacFunction; +} + +void FormWindow::hasLayoutFunctions( bool b ) +{ + hasLayoutFunc = b; +} + +bool FormWindow::hasLayoutFunctions() const +{ + return hasLayoutFunc; +} + +void FormWindow::setMarginFunction( const QString &funct ) +{ + margFunction = funct; +} + +QString FormWindow::marginFunction() const +{ + return margFunction; +} + +FormFile *FormWindow::formFile() const +{ + return ff; +} + +void FormWindow::setFormFile( FormFile *f ) +{ + ff = f; + if ( ff ) + connect( this, SIGNAL( modificationChanged(bool, const QString&) ), ff, SLOT( formWindowChangedSomehow() ) ); +} + +bool FormWindow::canBeBuddy( const QWidget *w ) const +{ + return w->focusPolicy() != QWidget::NoFocus; +} diff --git a/tools/designer/designer/formwindow.h b/tools/designer/designer/formwindow.h new file mode 100644 index 0000000..85dc3bf --- /dev/null +++ b/tools/designer/designer/formwindow.h @@ -0,0 +1,328 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef FORMWINDOW_H +#define FORMWINDOW_H + +#include "command.h" +#include "metadatabase.h" +#include "sizehandle.h" +#include "actiondnd.h" + +#include +#include +#include +#include +#include + +class QPaintEvent; +class QMouseEvent; +class QKeyEvent; +class QPainter; +class QLabel; +class MainWindow; +class QTimer; +class QFocusEvent; +class QCloseEvent; +class Resource; +class QResizeEvent; +class BreakLayoutCommand; +class QPixmap; +class QSizeGrip; +class Project; +struct DesignerFormWindow; +class FormFile; + +#if defined(Q_CC_MSVC) || defined(Q_FULL_TEMPLATE_INSTANTIATION) +#include "orderindicator.h" +#else +class OrderIndicator; +#endif + +class FormWindow : public QWidget +{ + Q_OBJECT + Q_PROPERTY( QString fileName READ fileName WRITE setFileName ) + +public: + FormWindow( FormFile *f, MainWindow *mw, QWidget *parent, const char *name = 0 ); + FormWindow( FormFile *f, QWidget *parent, const char *name = 0 ); + ~FormWindow(); + + void init(); + virtual void setMainWindow( MainWindow *w ); + + virtual QString fileName() const; + virtual void setFileName( const QString &fn ); + + virtual QPoint grid() const; + virtual QPoint gridPoint( const QPoint &p ); + + virtual CommandHistory *commandHistory(); + + virtual void undo(); + virtual void redo(); + virtual QString copy(); + virtual void paste( const QString &cb, QWidget *parent ); + virtual void lowerWidgets(); + virtual void raiseWidgets(); + virtual void checkAccels(); + + virtual void layoutHorizontal(); + virtual void layoutVertical(); + virtual void layoutHorizontalSplit(); + virtual void layoutVerticalSplit(); + virtual void layoutGrid(); + + virtual void layoutHorizontalContainer( QWidget *w ); + virtual void layoutVerticalContainer( QWidget *w ); + virtual void layoutGridContainer( QWidget *w ); + + virtual void breakLayout( QWidget *w ); + + virtual void selectWidget( QObject *w, bool select = TRUE ); + virtual void selectAll(); + virtual void updateSelection( QWidget *w ); + virtual void raiseSelection( QWidget *w ); + virtual void repaintSelection( QWidget *w ); + virtual void clearSelection( bool changePropertyDisplay = TRUE ); + virtual void selectWidgets(); + bool isWidgetSelected( QObject *w ); + virtual void updateChildSelections( QWidget *w ); + virtual void raiseChildSelections( QWidget *w ); + + virtual void emitUpdateProperties( QObject *w ); + virtual void emitShowProperties( QObject *w = 0 ); + virtual void emitSelectionChanged(); + + virtual void setPropertyShowingBlocked( bool b ); + bool isPropertyShowingBlocked() const; + + virtual QLabel *sizePreview() const; + virtual void checkPreviewGeometry( QRect &r ); + + virtual QPtrDict *widgets(); + virtual QWidgetList selectedWidgets() const; + + virtual QWidget *designerWidget( QObject *o ) const; + + virtual void handleContextMenu( QContextMenuEvent *e, QWidget *w ); + virtual void handleMousePress( QMouseEvent *e, QWidget *w ); + virtual void handleMouseRelease( QMouseEvent *e, QWidget *w ); + virtual void handleMouseDblClick( QMouseEvent *e, QWidget *w ); + virtual void handleMouseMove( QMouseEvent *e, QWidget *w ); + virtual void handleKeyPress( QKeyEvent *e, QWidget *w ); + virtual void handleKeyRelease( QKeyEvent *e, QWidget *w ); + + virtual void updateUndoInfo(); + + virtual MainWindow *mainWindow() const { return mainwindow; } + + bool checkCustomWidgets(); + virtual void insertWidget( QWidget *w, bool checkName = FALSE ); + virtual void removeWidget( QWidget *w ); + virtual void deleteWidgets(); + virtual void editAdjustSize(); + virtual void editConnections(); + + virtual int numSelectedWidgets() const; + virtual int numVisibleWidgets() const; + + virtual bool hasInsertedChildren( QWidget *w ) const; + + virtual QWidget *currentWidget() const { return propertyWidget && propertyWidget->isWidgetType() ? (QWidget*)propertyWidget : 0; } // ##### + virtual bool unify( QObject *w, QString &s, bool changeIt ); + + virtual bool isCustomWidgetUsed( MetaDataBase::CustomWidget *w ); + virtual bool isDatabaseWidgetUsed() const; + virtual bool isDatabaseAware() const; + + virtual QPoint mapToForm( const QWidget* w, const QPoint& ) const; + + bool isMainContainer( QObject *w ) const; + bool isCentralWidget( QObject *w ) const; + QWidget *mainContainer() const { return mContainer; } + void setMainContainer( QWidget *w ); + + void paintGrid( QWidget *w, QPaintEvent *e ); + + bool savePixmapInline() const; + QString pixmapLoaderFunction() const; + void setSavePixmapInline( bool b ); + void setPixmapLoaderFunction( const QString &func ); + + bool savePixmapInProject() const; + void setSavePixmapInProject( bool b ); + + void setToolFixed() { toolFixed = TRUE; } + + void setActiveObject( QObject *o ); + + QPtrList &actionList() { return actions; } + QAction *findAction( const QString &name ); + + void setProject( Project *pro ); + Project *project() const; + + void killAccels( QObject *top ); + + DesignerFormWindow *iFace(); + + int layoutDefaultSpacing() const; + int layoutDefaultMargin() const; + void setLayoutDefaultSpacing( int s ); + void setLayoutDefaultMargin( int s ); + QString spacingFunction() const; + QString marginFunction() const; + void setSpacingFunction( const QString &func ); + void setMarginFunction( const QString &func ); + bool hasLayoutFunctions() const; + void hasLayoutFunctions( bool b ); + + void initSlots(); + FormFile *formFile() const; + void setFormFile( FormFile *f ); + + bool isFake() const { return fake; } + bool canBeBuddy( const QWidget* ) const; + +public slots: + virtual void widgetChanged( QObject *w ); + virtual void currentToolChanged(); + virtual void visibilityChanged(); + virtual void modificationChanged( bool m ); + +signals: + void showProperties( QObject *w ); + void updateProperties( QObject *w ); + void undoRedoChanged( bool undoAvailable, bool redoAvailable, + const QString &undoCmd, const QString &redoCmd ); + void selectionChanged(); + void modificationChanged( bool m, FormWindow *fw ); + void modificationChanged( bool m, const QString &s ); + void fileNameChanged( const QString &s, FormWindow *fw ); + +protected: + virtual void closeEvent( QCloseEvent *e ); + virtual void focusInEvent( QFocusEvent *e ); + virtual void focusOutEvent( QFocusEvent *e ); + virtual void resizeEvent( QResizeEvent *e ); + void mouseDoubleClickEvent( QMouseEvent *e ) { handleMouseDblClick( e, mainContainer() ); } + +private: + enum RectType { Insert, Rubber }; + + void beginUnclippedPainter( bool doNot ); + void endUnclippedPainter(); + void drawConnectionLine(); + void drawSizePreview( const QPoint &pos, const QString& text ); + + void insertWidget(); + void moveSelectedWidgets( int dx, int dy ); + + void startRectDraw( const QPoint &p, const QPoint &global, QWidget *w, RectType t ); + void continueRectDraw( const QPoint &p, const QPoint &global, QWidget *w, RectType t ); + void endRectDraw(); + + void checkSelectionsForMove( QWidget *w ); + BreakLayoutCommand *breakLayoutCommand( QWidget *w ); + + bool allowMove( QWidget *w ); + + void saveBackground(); + void restoreConnectionLine(); + void restoreRect( const QRect &rect ) ; + + void showOrderIndicators(); + void updateOrderIndicators(); + void repositionOrderIndicators(); + void hideOrderIndicators(); + + QWidget *containerAt( const QPoint &pos, QWidget *notParentOf ); + +private slots: + void invalidCheckedSelections(); + void updatePropertiesTimerDone(); + void showPropertiesTimerDone(); + void selectionChangedTimerDone(); + void windowsRepaintWorkaroundTimerTimeout(); + +private: + int currTool; + bool oldRectValid, widgetPressed, drawRubber, checkedSelectionsForMove; + bool validForBuddy; + QRect currRect; + QPoint rectAnchor; + QPainter *unclippedPainter; + QPoint sizePreviewPos; + QPixmap sizePreviewPixmap; + MainWindow *mainwindow; + QPtrList selections; + QPtrDict usedSelections; + QRect widgetGeom, rubber; + QPoint oldPressPos, origPressPos; + CommandHistory commands; + QMap moving; + QWidget *insertParent; + QObject *propertyWidget; + QLabel *sizePreviewLabel; + QTimer *checkSelectionsTimer; + QPtrDict insertedWidgets; + bool propShowBlocked; + QTimer* updatePropertiesTimer, *showPropertiesTimer, *selectionChangedTimer, + *windowsRepaintWorkaroundTimer; + QPoint startPos, currentPos; + QWidget *startWidget, *endWidget; + QPixmap *buffer; + QPtrList orderIndicators; + QWidgetList orderedWidgets; + QWidgetList stackedWidgets; + QWidget *mContainer; + bool pixInline, pixProject; + QString pixLoader; + bool toolFixed; + QPtrList actions; + Project *proj; + DesignerFormWindow *iface; + QWidget* targetContainer; + QPalette restorePalette; + bool hadOwnPalette; + int defSpacing, defMargin; + QString spacFunction, margFunction; + bool hasLayoutFunc; + FormFile *ff; + bool fake; + +}; + +#endif diff --git a/tools/designer/designer/gotolinedialog.ui b/tools/designer/designer/gotolinedialog.ui new file mode 100644 index 0000000..a171812 --- /dev/null +++ b/tools/designer/designer/gotolinedialog.ui @@ -0,0 +1,176 @@ + +GotoLineDialog +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* +../interfaces/editorinterface.h +gotolinedialog.ui.h +struct EditorInterface; +EditorInterface *editor; + + + + GotoLineDialog + + + + 0 + 0 + 243 + 85 + + + + Goto Line + + + + unnamed + + + 11 + + + 6 + + + + TextLabel1 + + + &Line: + + + spinLine + + + + + spinLine + + + + 7 + 0 + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + PushButton2 + + + &Goto + + + true + + + + + PushButton1 + + + &Close + + + + + + + Spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + PushButton1 + clicked() + GotoLineDialog + reject() + + + PushButton2 + clicked() + GotoLineDialog + gotoLine() + + init() + destroy() + gotoLine() + setEditor( EditorInterface * e ) + + diff --git a/tools/designer/designer/gotolinedialog.ui.h b/tools/designer/designer/gotolinedialog.ui.h new file mode 100644 index 0000000..72ce7a1 --- /dev/null +++ b/tools/designer/designer/gotolinedialog.ui.h @@ -0,0 +1,57 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +void GotoLineDialog::init() +{ + editor = 0; +} + +void GotoLineDialog::destroy() +{ + if ( editor ) + editor->release(); +} + +void GotoLineDialog::gotoLine() +{ + if ( editor ) + editor->gotoLine( spinLine->value() - 1 ); + accept(); +} + +void GotoLineDialog::setEditor( EditorInterface *e ) +{ + editor = e; + editor->addRef(); +} + diff --git a/tools/designer/designer/hierarchyview.cpp b/tools/designer/designer/hierarchyview.cpp new file mode 100644 index 0000000..b4c68cc --- /dev/null +++ b/tools/designer/designer/hierarchyview.cpp @@ -0,0 +1,1500 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "hierarchyview.h" +#include "formwindow.h" +#include "globaldefs.h" +#include "mainwindow.h" +#include "command.h" +#include "widgetfactory.h" +#include "widgetdatabase.h" +#include "project.h" +#include "sourceeditor.h" +#include "propertyeditor.h" +#include "editfunctionsimpl.h" +#include "listeditor.h" +#include "actiondnd.h" +#include "actioneditorimpl.h" +#include "variabledialogimpl.h" +#include "popupmenueditor.h" +#include "menubareditor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../interfaces/languageinterface.h" +#include +#include +#include + +#include + +QListViewItem *newItem = 0; + +static QPluginManager *classBrowserInterfaceManager = 0; + +HierarchyItem::HierarchyItem( Type type, QListViewItem *parent, QListViewItem *after, + const QString &txt1, const QString &txt2, const QString &txt3 ) + : QListViewItem( parent, after, txt1, txt2, txt3 ), typ( type ) +{ +} + +HierarchyItem::HierarchyItem( Type type, QListView *parent, QListViewItem *after, + const QString &txt1, const QString &txt2, const QString &txt3 ) + : QListViewItem( parent, after, txt1, txt2, txt3 ), typ( type ) +{ +} + +void HierarchyItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Base, backgroundColor() ); + g.setColor( QColorGroup::Foreground, Qt::black ); + g.setColor( QColorGroup::Text, Qt::black ); + QString txt = text( 0 ); + if ( rtti() == Function && + MainWindow::self->currProject()->isCpp() && + ( txt == "init()" || txt == "destroy()" ) ) { + listView()->setUpdatesEnabled( FALSE ); + if ( txt == "init()" ) + setText( 0, txt + " " + "(Constructor)" ); + else + setText( 0, txt + " " + "(Destructor)" ); + QListViewItem::paintCell( p, g, column, width, align ); + setText( 0, txt ); + listView()->setUpdatesEnabled( TRUE ); + } else { + QListViewItem::paintCell( p, g, column, width, align ); + } + p->save(); + p->setPen( QPen( cg.dark(), 1 ) ); + if ( column == 0 ) + p->drawLine( 0, 0, 0, height() - 1 ); + if ( listView()->firstChild() != this ) { + if ( nextSibling() != itemBelow() && itemBelow()->depth() < depth() ) { + int d = depth() - itemBelow()->depth(); + p->drawLine( -listView()->treeStepSize() * d, height() - 1, 0, height() - 1 ); + } + } + p->drawLine( 0, height() - 1, width, height() - 1 ); + p->drawLine( width - 1, 0, width - 1, height() ); + p->restore(); +} + +QColor HierarchyItem::backgroundColor() +{ + updateBackColor(); + return backColor; +} + +void HierarchyItem::updateBackColor() +{ + if ( listView()->firstChild() == this ) { + backColor = *backColor1; + return; + } + + QListViewItemIterator it( this ); + --it; + if ( it.current() ) { + if ( ( ( HierarchyItem*)it.current() )->backColor == *backColor1 ) + backColor = *backColor2; + else + backColor = *backColor1; + } else { + backColor = *backColor1; + } +} + +void HierarchyItem::setObject( QObject *o ) +{ + obj = o; +} + +QObject *HierarchyItem::object() const +{ + return obj; +} + +void HierarchyItem::okRename( int col ) +{ + if ( newItem == this ) + newItem = 0; + QListViewItem::okRename( col ); +} + +void HierarchyItem::cancelRename( int col ) +{ + if ( newItem == this ) { + newItem = 0; + QListViewItem::cancelRename( col ); + delete this; + return; + } + QListViewItem::cancelRename( col ); +} + + + + +HierarchyList::HierarchyList( QWidget *parent, FormWindow *fw, bool doConnects ) + : QListView( parent ), formWindow( fw ) +{ + init_colors(); + + setDefaultRenameAction( Accept ); + header()->setMovingEnabled( FALSE ); + header()->setStretchEnabled( TRUE ); + normalMenu = 0; + tabWidgetMenu = 0; + addColumn( tr( "Name" ) ); + addColumn( tr( "Class" ) ); + QPalette p( palette() ); + p.setColor( QColorGroup::Base, QColor( *backColor2 ) ); + (void)*selectedBack; // hack + setPalette( p ); + disconnect( header(), SIGNAL( sectionClicked( int ) ), + this, SLOT( changeSortColumn( int ) ) ); + setSorting( -1 ); + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOn ); + if ( doConnects ) { + connect( this, SIGNAL( clicked( QListViewItem * ) ), + this, SLOT( objectClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( doubleClicked( QListViewItem * ) ), + this, SLOT( objectDoubleClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( returnPressed( QListViewItem * ) ), + this, SLOT( objectClicked( QListViewItem * ) ) ); + connect( this, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint&, int ) ), + this, SLOT( showRMBMenu( QListViewItem *, const QPoint & ) ) ); + } + deselect = TRUE; + setColumnWidthMode( 1, Manual ); +} + +void HierarchyList::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Key_Shift || e->key() == Key_Control ) + deselect = FALSE; + else + deselect = TRUE; + QListView::keyPressEvent( e ); +} + +void HierarchyList::keyReleaseEvent( QKeyEvent *e ) +{ + deselect = TRUE; + QListView::keyReleaseEvent( e ); +} + +void HierarchyList::viewportMousePressEvent( QMouseEvent *e ) +{ + if ( e->state() & ShiftButton || e->state() & ControlButton ) + deselect = FALSE; + else + deselect = TRUE; + QListView::viewportMousePressEvent( e ); +} + +void HierarchyList::viewportMouseReleaseEvent( QMouseEvent *e ) +{ + QListView::viewportMouseReleaseEvent( e ); +} + +QObject *HierarchyList::handleObjectClick( QListViewItem *i ) +{ + if ( !i ) + return 0; + + QObject *o = findObject( i ); + if ( !o ) + return 0; + if ( formWindow == o ) { + if ( deselect ) + formWindow->clearSelection( FALSE ); + formWindow->emitShowProperties( formWindow ); + return 0; + } + if ( o->isWidgetType() ) { + QWidget *w = (QWidget*)o; + if ( !formWindow->widgets()->find( w ) ) { + if ( ::qt_cast(w->parent()) ) { + if (::qt_cast(w->parent()->parent()) ) { + ((QTabWidget*)w->parent()->parent())->showPage( w ); + o = (QWidget*)w->parent()->parent(); + formWindow->emitUpdateProperties( formWindow->currentWidget() ); + } else if ( ::qt_cast(w->parent()->parent()) ) { + ((QDesignerWizard*)w->parent()->parent())-> + setCurrentPage( ( (QDesignerWizard*)w->parent()->parent() )->pageNum( w ) ); + o = (QWidget*)w->parent()->parent(); + formWindow->emitUpdateProperties( formWindow->currentWidget() ); + } else { + ( (QWidgetStack*)w->parent() )->raiseWidget( w ); + if ( (QWidgetStack*)w->parent()->isA( "QDesignerWidgetStack" ) ) + ( (QDesignerWidgetStack*)w->parent() )->updateButtons(); + } + } else if ( ::qt_cast(w) || ::qt_cast(w) ) { + formWindow->setActiveObject( w ); + } else if ( ::qt_cast(w) ) { + return 0; // ### we could try to find our menu bar and change the currentMenu to our index + } else { + return 0; + } + } + } else if ( ::qt_cast(o) ) { + MainWindow::self->actioneditor()->setCurrentAction( (QAction*)o ); + deselect = TRUE; + } + + if ( deselect ) + formWindow->clearSelection( FALSE ); + + return o; +} + + +void HierarchyList::objectDoubleClicked( QListViewItem *i ) +{ + QObject *o = handleObjectClick( i ); + if ( !o ) + return; + if ( o->isWidgetType() && ( (QWidget*)o )->isVisibleTo( formWindow ) ) { + QWidget *w = (QWidget*)o; + if ( !w->parentWidget() || + WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) + w->raise(); + formWindow->selectWidget( w, TRUE ); + } +} + +void HierarchyList::objectClicked( QListViewItem *i ) +{ + QObject *o = handleObjectClick( i ); + if ( !o ) + return; + if ( o->isWidgetType() && ( (QWidget*)o )->isVisibleTo( formWindow ) ) { + QWidget *w = (QWidget*)o; + formWindow->selectWidget( w, TRUE ); + } +} + +QObject *HierarchyList::findObject( QListViewItem *i ) +{ + return ( (HierarchyItem*)i )->object(); +} + +QListViewItem *HierarchyList::findItem( QObject *o ) +{ + QListViewItemIterator it( this ); + while ( it.current() ) { + if ( ( (HierarchyItem*)it.current() )->object() == o ) + return it.current(); + ++it; + } + return 0; +} + +QObject *HierarchyList::current() const +{ + if ( currentItem() ) + return ( (HierarchyItem*)currentItem() )->object(); + return 0; +} + +void HierarchyList::changeNameOf( QObject *o, const QString &name ) +{ + QListViewItem *item = findItem( o ); + if ( !item ) + return; + item->setText( 0, name ); +} + + +void HierarchyList::changeDatabaseOf( QObject *o, const QString &info ) +{ +#ifndef QT_NO_SQL + if ( !formWindow->isDatabaseAware() ) + return; + QListViewItem *item = findItem( o ); + if ( !item ) + return; + item->setText( 2, info ); +#endif +} + +static QPtrList *widgetStacks = 0; + +void HierarchyList::setup() +{ + if ( !formWindow || formWindow->isFake() ) + return; + clear(); + QWidget *w = formWindow->mainContainer(); +#ifndef QT_NO_SQL + if ( formWindow->isDatabaseAware() ) { + if ( columns() == 2 ) { + addColumn( tr( "Database" ) ); + header()->resizeSection( 0, 1 ); + header()->resizeSection( 1, 1 ); + header()->resizeSection( 2, 1 ); + header()->adjustHeaderSize(); + } + } else { + if ( columns() == 3 ) { + removeColumn( 2 ); + } + } +#endif + if ( !widgetStacks ) + widgetStacks = new QPtrList; + if ( w ) + insertObject( w, 0 ); + widgetStacks->clear(); +} + +void HierarchyList::setOpen( QListViewItem *i, bool b ) +{ + QListView::setOpen( i, b ); +} + +void HierarchyList::insertObject( QObject *o, QListViewItem *parent ) +{ + if ( QString( o->name() ).startsWith( "qt_dead_widget_" ) ) + return; + bool fakeMainWindow = FALSE; + if ( ::qt_cast(o) ) { + QObject *cw = ( (QMainWindow*)o )->centralWidget(); + if ( cw ) { + o = cw; + fakeMainWindow = TRUE; + } + } + QListViewItem *item = 0; + QString className = WidgetFactory::classNameOf( o ); + if ( ::qt_cast(o) ) { + switch ( WidgetFactory::layoutType( (QWidget*)o ) ) { + case WidgetFactory::HBox: + className = "HBox"; + break; + case WidgetFactory::VBox: + className = "VBox"; + break; + case WidgetFactory::Grid: + className = "Grid"; + break; + default: + break; + } + } + + QString dbInfo; +#ifndef QT_NO_SQL + dbInfo = MetaDataBase::fakeProperty( o, "database" ).toStringList().join("."); +#endif + + QString name = o->name(); + if ( ::qt_cast(o->parent()) ) { + if ( ::qt_cast(o->parent()->parent()) ) + name = ( (QTabWidget*)o->parent()->parent() )->tabLabel( (QWidget*)o ); + else if ( ::qt_cast(o->parent()->parent()) ) + name = ( (QWizard*)o->parent()->parent() )->title( (QWidget*)o ); + } + + QToolBox *tb; + if ( o->parent() && o->parent()->parent() && + (tb = ::qt_cast(o->parent()->parent()->parent())) ) + name = tb->itemLabel( tb->indexOf((QWidget*)o) ); + + if ( fakeMainWindow ) { + name = o->parent()->name(); + className = "QMainWindow"; + } + + if ( !parent ) + item = new HierarchyItem( HierarchyItem::Widget, this, 0, name, className, dbInfo ); + else + item = new HierarchyItem( HierarchyItem::Widget, parent, 0, name, className, dbInfo ); + item->setOpen( TRUE ); + if ( !parent ) + item->setPixmap( 0, QPixmap::fromMimeSource( "designer_form.png" ) ); + else if ( ::qt_cast(o) ) + item->setPixmap( 0, QPixmap::fromMimeSource( "designer_layout.png" )); + else + item->setPixmap( 0, WidgetDatabase::iconSet( + WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( o ) ) ). + pixmap( QIconSet::Small, QIconSet::Normal ) ); + if ( ::qt_cast(o) ) + item->setPixmap( 0, ( (QAction*)o )->iconSet().pixmap() ); + + ( (HierarchyItem*)item )->setObject( o ); + const QObjectList *l = o->children(); + if ( ::qt_cast(o) ) + l = 0; + if ( l ) { + QObjectListIt it( *l ); + it.toLast(); + for ( ; it.current(); --it ) { + if ( !it.current()->isWidgetType() || + ( (QWidget*)it.current() )->isHidden() ) + continue; + if ( !formWindow->widgets()->find( (QWidget*)it.current() ) ) { + if ( ::qt_cast(it.current()->parent()) || + ::qt_cast(it.current()) ) { + QObject *obj = it.current(); + QDesignerTabWidget *tw = ::qt_cast(it.current()->parent()); + QDesignerWizard *dw = ::qt_cast(it.current()->parent()); + QWidgetStack *stack = 0; + if ( dw || tw || ::qt_cast(obj) ) + stack = (QWidgetStack*)obj; + else + stack = (QWidgetStack*)obj->parent(); + if ( widgetStacks->findRef( stack ) != -1 ) + continue; + widgetStacks->append( stack ); + QObjectList *l2 = stack->queryList( "QWidget", 0, TRUE, FALSE ); + for ( obj = l2->last(); obj; obj = l2->prev() ) { + if ( qstrcmp( obj->className(), + "QWidgetStackPrivate::Invisible" ) == 0 || + ( tw && !tw->tabBar()->tab( stack->id( (QWidget*)obj ) ) ) || + ( dw && dw->isPageRemoved( (QWidget*)obj ) ) ) + continue; + if ( qstrcmp( obj->name(), "designer_wizardstack_button" ) == 0 ) + continue; + if ( stack->id( (QWidget*)obj ) == -1 ) + continue; + insertObject( obj, item ); + } + delete l2; + } else if ( ::qt_cast(it.current()->parent()) ) { + if ( !::qt_cast(it.current()) ) + continue; + QToolBox *tb = (QToolBox*)it.current()->parent(); + for ( int i = tb->count() - 1; i >= 0; --i ) + insertObject( tb->item( i ), item ); + } + continue; + } + insertObject( it.current(), item ); + } + } + + if ( fakeMainWindow ) { + QObjectList *l = o->parent()->queryList( "QDesignerToolBar" ); + QObject *obj; + for ( obj = l->first(); obj; obj = l->next() ) + insertObject( obj, item ); + delete l; + l = o->parent()->queryList( "MenuBarEditor" ); + for ( obj = l->first(); obj; obj = l->next() ) + insertObject( obj, item ); + delete l; + } else if ( ::qt_cast(o) || ::qt_cast(o) ) { + QPtrList actions; + if ( ::qt_cast(o) ) + actions = ( (QDesignerToolBar*)o )->insertedActions(); + else + ( (PopupMenuEditor*)o )->insertedActions( actions ); + + QPtrListIterator it( actions ); + it.toLast(); + while ( it.current() ) { + QAction *a = it.current(); + if ( ::qt_cast(a) ) { + QDesignerAction *da = (QDesignerAction*)a; + if ( da->supportsMenu() ) + insertObject( da, item ); + else + insertObject( da->widget(), item ); + } else if ( ::qt_cast(a) ) { + insertObject( a, item ); + } + --it; + } + } else if ( ::qt_cast(o) && o->children() ) { + QObjectList *l = (QObjectList*)o->children(); + for ( QObject *obj = l->last(); obj; obj = l->prev() ) { + if ( ::qt_cast(obj) ) { + QDesignerAction *da = (QDesignerAction*)obj; + if ( da->supportsMenu() ) + insertObject( da, item ); + else + insertObject( da->widget(), item ); + } else if ( ::qt_cast(obj) ) { + insertObject( obj, item ); + } + } + } else if ( ::qt_cast(o) ) { + MenuBarEditor *mb = (MenuBarEditor*)o; + for ( int i = mb->count() -1; i >= 0; --i ) { + MenuBarEditorItem *md = mb->item( i ); + if ( !md || !md->menu() ) + continue; + insertObject( md->menu(), item ); + } + } +} + +void HierarchyList::setCurrent( QObject *o ) +{ + QListViewItemIterator it( this ); + while ( it.current() ) { + if ( ( (HierarchyItem*)it.current() )->object() == o ) { + blockSignals( TRUE ); + setCurrentItem( it.current() ); + ensureItemVisible( it.current() ); + blockSignals( FALSE ); + return; + } + ++it; + } +} + +void HierarchyList::showRMBMenu( QListViewItem *i, const QPoint & p ) +{ + if ( !i ) + return; + + QObject *o = findObject( i ); + if ( !o ) + return; + + if ( !o->isWidgetType() || + ( o != formWindow && !formWindow->widgets()->find( (QWidget*)o ) ) ) + return; + + QWidget *w = (QWidget*)o; + if ( w->isVisibleTo( formWindow ) ) { + if ( !::qt_cast(w) && !::qt_cast(w) ) { + if ( !normalMenu ) + normalMenu = formWindow->mainWindow()->setupNormalHierarchyMenu( this ); + normalMenu->popup( p ); + } else { + if ( !tabWidgetMenu ) + tabWidgetMenu = + formWindow->mainWindow()->setupTabWidgetHierarchyMenu( + this, SLOT( addTabPage() ), + SLOT( removeTabPage() ) ); + tabWidgetMenu->popup( p ); + } + } +} + +void HierarchyList::addTabPage() +{ + QObject *o = current(); + if ( !o || !o->isWidgetType() ) + return; + QWidget *w = (QWidget*)o; + if ( ::qt_cast(w) ) { + QTabWidget *tw = (QTabWidget*)w; + AddTabPageCommand *cmd = new AddTabPageCommand( tr( "Add Page to %1" ). + arg( tw->name() ), formWindow, + tw, "Tab" ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( ::qt_cast(w) ) { + QWizard *wiz = (QWizard*)formWindow->mainContainer(); + AddWizardPageCommand *cmd = new AddWizardPageCommand( tr( "Add Page to %1" ). + arg( wiz->name() ), formWindow, + wiz, "Page" ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void HierarchyList::removeTabPage() +{ + QObject *o = current(); + if ( !o || !o->isWidgetType() ) + return; + QWidget *w = (QWidget*)o; + if ( ::qt_cast(w) ) { + QTabWidget *tw = (QTabWidget*)w; + if ( tw->currentPage() ) { + QDesignerTabWidget *dtw = (QDesignerTabWidget*)tw; + DeleteTabPageCommand *cmd = + new DeleteTabPageCommand( tr( "Delete Page %1 of %2" ). + arg( dtw->pageTitle() ).arg( tw->name() ), + formWindow, tw, tw->currentPage() ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } else if ( ::qt_cast(w) ) { + QWizard *wiz = (QWizard*)formWindow->mainContainer(); + if ( wiz->currentPage() ) { + QDesignerWizard *dw = (QDesignerWizard*)wiz; + DeleteWizardPageCommand *cmd = + new DeleteWizardPageCommand( tr( "Delete Page %1 of %2" ). + arg( dw->pageTitle() ).arg( wiz->name() ), + formWindow, wiz, + wiz->indexOf( wiz->currentPage() ), TRUE ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } +} + +// ------------------------------------------------------------ + +FormDefinitionView::FormDefinitionView( QWidget *parent, FormWindow *fw ) + : HierarchyList( parent, fw, TRUE ) +{ + header()->hide(); + removeColumn( 1 ); + connect( this, SIGNAL( itemRenamed( QListViewItem *, int, const QString & ) ), + this, SLOT( renamed( QListViewItem * ) ) ); + popupOpen = FALSE; +} + +void FormDefinitionView::setup() +{ + if ( popupOpen || !formWindow ) + return; + if ( !formWindow->project()->isCpp() ) + return; + QListViewItem *i = firstChild(); + while ( i ) { + if ( i->rtti() == HierarchyItem::DefinitionParent ) { + QListViewItem *a = i; + i = i->nextSibling(); + delete a; + continue; + } + i = i->nextSibling(); + } + + LanguageInterface *lIface = MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( lIface ) { + QStringList defs = lIface->definitions(); + for ( QStringList::Iterator dit = defs.begin(); dit != defs.end(); ++dit ) { + HierarchyItem *itemDef = new HierarchyItem( HierarchyItem::DefinitionParent, this, 0, + tr( *dit ), QString::null, QString::null ); + itemDef->setPixmap( 0, QPixmap::fromMimeSource( "designer_folder.png" ) ); + itemDef->setOpen( TRUE ); + QStringList entries = + lIface->definitionEntries( *dit, formWindow->mainWindow()->designerInterface() ); + HierarchyItem *item = 0; + for ( QStringList::Iterator eit = entries.begin(); eit != entries.end(); ++eit ) { + item = new HierarchyItem( HierarchyItem::Definition, + itemDef, item, *eit, QString::null, QString::null ); + item->setRenameEnabled( 0, TRUE ); + } + } + lIface->release(); + } + setupVariables(); + refresh(); +} + +void FormDefinitionView::setupVariables() +{ + bool pubOpen, protOpen, privOpen; + pubOpen = protOpen = privOpen = TRUE; + QListViewItem *i = firstChild(); + while ( i ) { + if ( i->rtti() == HierarchyItem::VarParent ) { + QListViewItem *a = i; + i = i->firstChild(); + while ( i ) { + if ( i->rtti() == HierarchyItem::VarPublic ) + pubOpen = i->isOpen(); + else if ( i->rtti() == HierarchyItem::VarProtected ) + protOpen = i->isOpen(); + else if ( i->rtti() == HierarchyItem::VarPrivate ) + privOpen = i->isOpen(); + i = i->nextSibling(); + } + delete a; + break; + } + i = i->nextSibling(); + } + + HierarchyItem *itemVar = new HierarchyItem( HierarchyItem::VarParent, this, 0, tr( "Class Variables" ), + QString::null, QString::null ); + itemVar->setPixmap( 0, QPixmap::fromMimeSource( "designer_folder.png" ) ); + itemVar->setOpen( TRUE ); + + itemVarPriv = new HierarchyItem( HierarchyItem::VarPrivate, itemVar, 0, tr( "private" ), + QString::null, QString::null ); + itemVarProt = new HierarchyItem( HierarchyItem::VarProtected, itemVar, 0, tr( "protected" ), + QString::null, QString::null ); + itemVarPubl = new HierarchyItem( HierarchyItem::VarPublic, itemVar, 0, tr( "public" ), + QString::null, QString::null ); + + QValueList varList = MetaDataBase::variables( formWindow ); + QValueList::Iterator it = --( varList.end() ); + if ( !varList.isEmpty() && itemVar ) { + for (;;) { + QListViewItem *item = 0; + if ( (*it).varAccess == "public" ) + item = new HierarchyItem( HierarchyItem::Variable, itemVarPubl, 0, (*it).varName, + QString::null, QString::null ); + else if ( (*it).varAccess == "private" ) + item = new HierarchyItem( HierarchyItem::Variable, itemVarPriv, 0, (*it).varName, + QString::null, QString::null ); + else // default is protected + item = new HierarchyItem( HierarchyItem::Variable, itemVarProt, 0, (*it).varName, + QString::null, QString::null ); + item->setPixmap( 0, QPixmap::fromMimeSource( "designer_editslots.png" ) ); + if ( it == varList.begin() ) + break; + --it; + } + } + itemVar->setOpen( TRUE ); + itemVarPriv->setOpen( privOpen ); + itemVarProt->setOpen( protOpen ); + itemVarPubl->setOpen( pubOpen ); +} + +void FormDefinitionView::refresh() +{ + if ( popupOpen || !formWindow || !formWindow->project()->isCpp() ) + return; + + bool fuPub, fuProt, fuPriv, slPub, slProt, slPriv; + fuPub = fuProt = fuPriv = slPub = slProt = slPriv = TRUE; + QListViewItem *i = firstChild(); + while ( i ) { + if ( i->rtti() == HierarchyItem::SlotParent || + i->rtti() == HierarchyItem::FunctParent ) { + QListViewItem *a = i; + i = i->firstChild(); + while ( i ) { + switch( i->rtti() ) { + case HierarchyItem::FunctPublic: + fuPub = i->isOpen(); + case HierarchyItem::FunctProtected: + fuProt = i->isOpen(); + break; + case HierarchyItem::FunctPrivate: + fuPriv = i->isOpen(); + break; + case HierarchyItem::SlotPublic: + slPub = i->isOpen(); + if ( slPub ) + break; + case HierarchyItem::SlotProtected: + slProt = i->isOpen(); + break; + case HierarchyItem::SlotPrivate: + slPriv = i->isOpen(); + } + i = i->nextSibling(); + } + i = a->nextSibling(); + delete a; + continue; + } + i = i->nextSibling(); + } + + + itemFunct = new HierarchyItem( HierarchyItem::FunctParent, + this, 0, tr( "Functions" ), QString::null, QString::null ); + itemFunct->moveItem( i ); + itemFunct->setPixmap( 0, QPixmap::fromMimeSource( "designer_folder.png" ) ); + itemFunctPriv = new HierarchyItem( HierarchyItem::FunctPrivate, itemFunct, 0, + tr( "private" ), QString::null, QString::null ); + itemFunctProt = new HierarchyItem( HierarchyItem::FunctProtected, itemFunct, 0, + tr( "protected" ), QString::null, QString::null ); + itemFunctPubl = new HierarchyItem( HierarchyItem::FunctPublic, itemFunct, 0, + tr( "public" ), QString::null, QString::null ); + + itemSlots = new HierarchyItem( HierarchyItem::SlotParent, + this, 0, tr( "Slots" ), QString::null, QString::null ); + itemSlots->setPixmap( 0, QPixmap::fromMimeSource( "designer_folder.png" ) ); + itemPrivate = new HierarchyItem( HierarchyItem::SlotPrivate, itemSlots, 0, tr( "private" ), + QString::null, QString::null ); + itemProtected = new HierarchyItem( HierarchyItem::SlotProtected, itemSlots, 0, tr( "protected" ), + QString::null, QString::null ); + itemPublic = new HierarchyItem( HierarchyItem::SlotPublic, itemSlots, 0, tr( "public" ), + QString::null, QString::null ); + + QValueList functionList = MetaDataBase::functionList( formWindow ); + QValueList::Iterator it = --( functionList.end() ); + if ( !functionList.isEmpty() && itemFunct ) { + for (;;) { + QListViewItem *item = 0; + if ( (*it).type == "slot" ) { + if ( (*it).access == "protected" ) + item = new HierarchyItem( HierarchyItem::Slot, itemProtected, 0, (*it).function, + QString::null, QString::null ); + else if ( (*it).access == "private" ) + item = new HierarchyItem( HierarchyItem::Slot, itemPrivate, 0, (*it).function, + QString::null, QString::null ); + else // default is public + item = new HierarchyItem( HierarchyItem::Slot, itemPublic, 0, (*it).function, + QString::null, QString::null ); + } else { + if ( (*it).access == "protected" ) + item = new HierarchyItem( HierarchyItem::Function, itemFunctProt, 0, (*it).function, + QString::null, QString::null ); + else if ( (*it).access == "private" ) + item = new HierarchyItem( HierarchyItem::Function, itemFunctPriv, 0, (*it).function, + QString::null, QString::null ); + else // default is public + item = new HierarchyItem( HierarchyItem::Function, itemFunctPubl, 0, (*it).function, + QString::null, QString::null ); + } + item->setPixmap( 0, QPixmap::fromMimeSource( "designer_editslots.png" ) ); + if ( it == functionList.begin() ) + break; + --it; + } + } + + itemFunct->setOpen( TRUE ); + itemFunctPubl->setOpen( fuPub ); + itemFunctProt->setOpen( fuProt ); + itemFunctPriv->setOpen( fuPriv ); + + itemSlots->setOpen( TRUE ); + itemPublic->setOpen( slPub ); + itemProtected->setOpen( slProt ); + itemPrivate->setOpen( slPriv ); +} + + +void FormDefinitionView::setCurrent( QWidget * ) +{ +} + +void FormDefinitionView::objectClicked( QListViewItem *i ) +{ + if ( !i ) + return; + if ( (i->rtti() == HierarchyItem::Slot) || (i->rtti() == HierarchyItem::Function) ) + formWindow->mainWindow()->editFunction( i->text( 0 ) ); +} + +static HierarchyItem::Type getChildType( int type ) +{ + switch ( (HierarchyItem::Type)type ) { + case HierarchyItem::Widget: + qWarning( "getChildType: Inserting childs dynamically to Widget or SlotParent is not allowed!" ); + break; + case HierarchyItem::SlotParent: + case HierarchyItem::SlotPublic: + case HierarchyItem::SlotProtected: + case HierarchyItem::SlotPrivate: + case HierarchyItem::Slot: + return HierarchyItem::Slot; + case HierarchyItem::DefinitionParent: + case HierarchyItem::Definition: + return HierarchyItem::Definition; + case HierarchyItem::Event: + case HierarchyItem::EventFunction: + return HierarchyItem::Event; + case HierarchyItem::FunctParent: + case HierarchyItem::FunctPublic: + case HierarchyItem::FunctProtected: + case HierarchyItem::FunctPrivate: + case HierarchyItem::Function: + return HierarchyItem::Function; + case HierarchyItem::VarParent: + case HierarchyItem::VarPublic: + case HierarchyItem::VarProtected: + case HierarchyItem::VarPrivate: + case HierarchyItem::Variable: + return HierarchyItem::Variable; + } + return (HierarchyItem::Type)type; +} + +void HierarchyList::insertEntry( QListViewItem *i, const QPixmap &pix, const QString &s ) +{ + QListViewItem *after = i->firstChild(); + while ( after && after->nextSibling() ) + after = after->nextSibling(); + HierarchyItem *item = new HierarchyItem( getChildType( i->rtti() ), i, after, s, + QString::null, QString::null ); + if ( !pix.isNull() ) + item->setPixmap( 0, pix ); + item->setRenameEnabled( 0, TRUE ); + setCurrentItem( item ); + ensureItemVisible( item ); + qApp->processEvents(); + newItem = item; + item->startRename( 0 ); +} + +void FormDefinitionView::contentsMouseDoubleClickEvent( QMouseEvent *e ) +{ + QListViewItem *i = itemAt( contentsToViewport( e->pos() ) ); + if ( !i ) + return; + + if ( i->rtti() == HierarchyItem::SlotParent || i->rtti() == HierarchyItem::FunctParent || + i->rtti() == HierarchyItem::VarParent ) + return; + + HierarchyItem::Type t = getChildType( i->rtti() ); + if ( (int)t == i->rtti() ) + i = i->parent(); + + if ( formWindow->project()->isCpp() ) + switch( i->rtti() ) { + case HierarchyItem::FunctPublic: + execFunctionDialog( "public", "function", TRUE ); + break; + case HierarchyItem::FunctProtected: + execFunctionDialog( "protected", "function", TRUE ); + break; + case HierarchyItem::FunctPrivate: + execFunctionDialog( "private", "function", TRUE ); + break; + case HierarchyItem::SlotPublic: + execFunctionDialog( "public", "slot", TRUE ); + break; + case HierarchyItem::SlotProtected: + execFunctionDialog( "protected", "slot", TRUE ); + break; + case HierarchyItem::SlotPrivate: + execFunctionDialog( "private", "slot", TRUE ); + break; + case HierarchyItem::VarPublic: + case HierarchyItem::VarProtected: + case HierarchyItem::VarPrivate: { + VariableDialog varDia( formWindow, this ); + QListViewItem *i = selectedItem(); + if ( i ) + varDia.setCurrentItem( i->text( 0 ) ); + varDia.exec(); + break; + } + default: + insertEntry( i ); + } else + insertEntry( i ); +} + +void FormDefinitionView::execFunctionDialog( const QString &access, const QString &type, bool addFunc ) +{ + FormFile *formFile = formWindow->formFile(); + if ( !formFile || !formFile->isUihFileUpToDate() ) + return; + + // refresh the functions list in the metadatabase + SourceEditor *editor = formFile->editor(); + if ( editor ) + editor->refresh( TRUE ); + + EditFunctions dlg( this, formWindow ); + if ( addFunc ) + dlg.functionAdd( access, type ); + dlg.exec(); +} + +void FormDefinitionView::showRMBMenu( QListViewItem *i, const QPoint &pos ) +{ + if ( !i ) + return; + + const int EDIT = 1; + const int NEW = 2; + const int DEL = 3; + const int PROPS = 4; + const int GOIMPL = 5; + + QPopupMenu menu; + bool insertDelete = FALSE; + + if ( i->rtti() == HierarchyItem::FunctParent || i->rtti() == HierarchyItem::SlotParent || + i->rtti() == HierarchyItem::VarParent ) { + menu.insertItem( QPixmap::fromMimeSource( "designer_editslots.png" ), tr( "Edit..." ), EDIT ); + } else + menu.insertItem( QPixmap::fromMimeSource( "designer_filenew.png" ), tr( "New" ), NEW ); + if ( i->rtti() == HierarchyItem::DefinitionParent || i->rtti() == HierarchyItem::Variable || + i->rtti() == HierarchyItem::Definition ) { + menu.insertItem( QPixmap::fromMimeSource( "designer_editslots.png" ), tr( "Edit..." ), EDIT ); + } + if ( i->rtti() == HierarchyItem::Function || i->rtti() == HierarchyItem::Slot ) { + if ( formWindow->project()->isCpp() ) + menu.insertItem( QPixmap::fromMimeSource( "designer_editslots.png" ), tr( "Properties..." ), PROPS ); + if ( MetaDataBase::hasEditor( formWindow->project()->language() ) ) + menu.insertItem( tr( "Goto Implementation" ), GOIMPL ); + insertDelete = TRUE; + } + if ( insertDelete || i->rtti() == HierarchyItem::Variable || + i->rtti() == HierarchyItem::Function || i->rtti() == HierarchyItem::Slot || + i->rtti() == HierarchyItem::Definition ) { + menu.insertSeparator(); + menu.insertItem( QPixmap::fromMimeSource( "designer_editcut.png" ), tr( "Delete..." ), DEL ); + } + popupOpen = TRUE; + int res = menu.exec( pos ); + popupOpen = FALSE; + if ( res == -1 ) + return; + + if ( res == EDIT ) { + switch( i->rtti() ) { + case HierarchyItem::FunctParent: + execFunctionDialog( "public", "function", FALSE ); + break; + case HierarchyItem::SlotParent: + execFunctionDialog( "public", "slot", FALSE ); + break; + case HierarchyItem::VarParent: + case HierarchyItem::VarPublic: + case HierarchyItem::VarProtected: + case HierarchyItem::VarPrivate: + case HierarchyItem::Variable: { + VariableDialog varDia( formWindow, this ); + QListViewItem *i = selectedItem(); + if ( i ) + varDia.setCurrentItem( i->text( 0 ) ); + if ( varDia.exec() == QDialog::Accepted ) + formWindow->commandHistory()->setModified( TRUE ); + break; + } + case HierarchyItem::Definition: + case HierarchyItem::DefinitionParent: + LanguageInterface *lIface = MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( !lIface ) + return; + if ( i->rtti() == HierarchyItem::Definition ) + i = i->parent(); + ListEditor dia( this, 0, TRUE ); + dia.setCaption( tr( "Edit %1" ).arg( i->text( 0 ) ) ); + QStringList entries = lIface->definitionEntries( i->text( 0 ), MainWindow::self->designerInterface() ); + dia.setList( entries ); + dia.exec(); + Command *cmd = new EditDefinitionsCommand( tr( "Edit " ) + i->text( 0 ), formWindow, + lIface, i->text( 0 ), dia.items() ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } else if ( res == NEW ) { + HierarchyItem::Type t = getChildType( i->rtti() ); + if ( (int)t == i->rtti() ) + i = i->parent(); + switch( i->rtti() ) { + case HierarchyItem::SlotPublic: + execFunctionDialog( "public", "slot", TRUE ); + break; + case HierarchyItem::SlotProtected: + execFunctionDialog( "protected", "slot", TRUE ); + break; + case HierarchyItem::SlotPrivate: + execFunctionDialog( "private" , "slot", TRUE ); + break; + case HierarchyItem::FunctPublic: + execFunctionDialog( "public", "function", TRUE ); + break; + case HierarchyItem::FunctProtected: + execFunctionDialog( "protected", "function", TRUE ); + break; + case HierarchyItem::FunctPrivate: + execFunctionDialog( "private" , "function", TRUE ); + break; + default: + insertEntry( i ); + } + } else if ( res == DEL ) { + if ( i->rtti() == HierarchyItem::Slot || i->rtti() == HierarchyItem::Function ) { + + QCString funct( MetaDataBase::normalizeFunction( i->text( 0 ) ).latin1() ); + Command *cmd = new RemoveFunctionCommand( tr( "Remove function" ), formWindow, funct, + QString::null, QString::null, QString::null, + QString::null, formWindow->project()->language() ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + formWindow->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + } else if ( i->rtti() == HierarchyItem::Variable ) { + Command *cmd = new RemoveVariableCommand( tr( "Remove variable" ), formWindow, + i->text( 0 ) ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else { + QListViewItem *p = i->parent(); + delete i; + save( p, 0 ); + } + } else if ( res == PROPS ) { + if ( i->rtti() == HierarchyItem::Slot || + i->rtti() == HierarchyItem::Function ) { + EditFunctions dlg( this, formWindow ); + dlg.setCurrentFunction( MetaDataBase::normalizeFunction( i->text( 0 ) ) ); + dlg.exec(); + } + } else if ( res == GOIMPL ) { + if ( i->rtti() == HierarchyItem::Slot || + i->rtti() == HierarchyItem::Function ) { + formWindow->mainWindow()->editFunction( i->text( 0 ) ); + } + } +} + +void FormDefinitionView::renamed( QListViewItem *i ) +{ + if ( newItem == i ) + newItem = 0; + if ( !i->parent() ) + return; + save( i->parent(), i ); +} + + +void FormDefinitionView::save( QListViewItem *p, QListViewItem *i ) +{ + if ( i && i->text( 0 ).isEmpty() ) { + delete i; + return; + } + + if ( i && i->rtti() == HierarchyItem::Variable ) { + i->setRenameEnabled( 0, FALSE ); + QString varName = i->text( 0 ); + varName = varName.simplifyWhiteSpace(); + if ( varName[(int)varName.length() - 1] != ';' ) + varName += ";"; + if ( MetaDataBase::hasVariable( formWindow, varName ) ) { + QMessageBox::information( this, tr( "Edit Variables" ), + tr( "This variable has already been declared!" ) ); + } else { + if ( p->rtti() == HierarchyItem::VarPublic ) + addVariable( varName, "public" ); + else if ( p->rtti() == HierarchyItem::VarProtected ) + addVariable( varName, "protected" ); + else if ( p->rtti() == HierarchyItem::VarPrivate ) + addVariable( varName, "private" ); + } + } else { + LanguageInterface *lIface = MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( !lIface ) + return; + QStringList lst; + i = p->firstChild(); + while ( i ) { + lst << i->text( 0 ); + i = i->nextSibling(); + } + Command *cmd = new EditDefinitionsCommand( tr( "Edit " ) + p->text( 0 ), formWindow, + lIface, p->text( 0 ), lst ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void FormDefinitionView::addVariable( const QString &varName, const QString &access ) +{ + Command *cmd = new AddVariableCommand( tr( "Add variable" ), formWindow, + varName, access ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +// ------------------------------------------------------------ + +HierarchyView::HierarchyView( QWidget *parent ) + : QTabWidget( parent, 0, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | + WStyle_Tool |WStyle_MinMax | WStyle_SysMenu ) +{ + formwindow = 0; + editor = 0; + listview = new HierarchyList( this, formWindow() ); + fView = new FormDefinitionView( this, formWindow() ); + if ( !MainWindow::self->singleProjectMode() ) { + addTab( listview, tr( "Objects" ) ); + setTabToolTip( listview, tr( "List of all widgets and objects of the current form in hierarchical order" ) ); + addTab( fView, tr( "Members" ) ); + setTabToolTip( fView, tr( "List of all members of the current form" ) ); + } else { + listview->hide(); + fView->hide(); + } + + if ( !classBrowserInterfaceManager ) { + classBrowserInterfaceManager = + new QPluginManager( IID_ClassBrowser, QApplication::libraryPaths(), + MainWindow::self->pluginDirectory() ); + } + + classBrowsers = new QMap(); + QStringList langs = MetaDataBase::languages(); + for ( QStringList::Iterator it = langs.begin(); it != langs.end(); ++it ) { + QInterfacePtr ciface = 0; + classBrowserInterfaceManager->queryInterface( *it, &ciface ); + if ( ciface ) { + ClassBrowser cb( ciface->createClassBrowser( this ), ciface ); + addTab( cb.lv, tr( "Class Declarations" ) ); + setTabToolTip( cb.lv, tr( "List of all classes and its declarations of the current source file" ) ); + ciface->onClick( this, SLOT( jumpTo( const QString &, const QString &, int ) ) ); + classBrowsers->insert( *it, cb ); + setTabEnabled( cb.lv, FALSE ); + } + } +} + +HierarchyView::~HierarchyView() +{ +} + +void HierarchyView::clear() +{ + listview->clear(); + fView->clear(); + for ( QMap::Iterator it = classBrowsers->begin(); + it != classBrowsers->end(); ++it ) { + (*it).iface->clear(); + } +} + +void HierarchyView::setFormWindow( FormWindow *fw, QObject *o ) +{ + bool fake = fw && qstrcmp( fw->name(), "qt_fakewindow" ) == 0; + if ( fw == 0 || o == 0 ) { + listview->clear(); + fView->clear(); + listview->setFormWindow( fw ); + fView->setFormWindow( fw ); + formwindow = 0; + editor = 0; + } + + setTabEnabled( listview, TRUE ); + setTabEnabled( fView, fw && fw->project()->isCpp() ); + + if ( fw == formwindow ) { + if ( fw ) { + if ( !fake ) + listview->setCurrent( (QWidget*)o ); + else + listview->clear(); + if ( MainWindow::self->qWorkspace()->activeWindow() == fw ) + showPage( listview ); + else if ( fw->project()->isCpp() ) + showPage( fView ); + else + showClasses( fw->formFile()->editor() ); + } + } + + formwindow = fw; + if ( !fake ) { + listview->setFormWindow( fw ); + } else { + listview->setFormWindow( 0 ); + listview->clear(); + } + + fView->setFormWindow( fw ); + if ( !fake ) { + listview->setup(); + listview->setCurrent( (QWidget*)o ); + } + fView->setup(); + + for ( QMap::Iterator it = classBrowsers->begin(); + it != classBrowsers->end(); ++it ) { + (*it).iface->clear(); + setTabEnabled( (*it).lv, fw && !fw->project()->isCpp() ); + } + + if ( MainWindow::self->qWorkspace()->activeWindow() == fw ) + showPage( listview ); + else if ( fw && fw->project()->isCpp() ) + showPage( fView ); + else if ( fw ) + showClasses( fw->formFile()->editor() ); + + editor = 0; +} + +void HierarchyView::showClasses( SourceEditor *se ) +{ + if ( !se->object() ) + return; + + lastSourceEditor = se; + QTimer::singleShot( 100, this, SLOT( showClassesTimeout() ) ); +} + +void HierarchyView::showClassesTimeout() +{ + if ( !lastSourceEditor ) + return; + SourceEditor *se = (SourceEditor*)lastSourceEditor; + if ( !se->object() ) + return; + if ( se->formWindow() && se->formWindow()->project()->isCpp() ) { + setFormWindow( se->formWindow(), se->formWindow()->currentWidget() ); + MainWindow::self->propertyeditor()->setWidget( se->formWindow()->currentWidget(), + se->formWindow() ); + return; + } + + setTabEnabled( listview, !!se->formWindow() && !se->formWindow()->isFake() ); + setTabEnabled( fView, FALSE ); + + formwindow = 0; + listview->setFormWindow( 0 ); + fView->setFormWindow( 0 ); + listview->clear(); + fView->clear(); + if ( !se->formWindow() ) + MainWindow::self->propertyeditor()->setWidget( 0, 0 ); + editor = se; + + for ( QMap::Iterator it = classBrowsers->begin(); + it != classBrowsers->end(); ++it ) { + if ( it.key() == se->project()->language() ) { + (*it).iface->update( se->text() ); + setTabEnabled( (*it).lv, TRUE ); + showPage( (*it).lv ); + } else { + setTabEnabled( (*it).lv, FALSE ); + (*it).iface->clear(); + } + } +} + +void HierarchyView::updateClassBrowsers() +{ + if ( !editor ) + return; + for ( QMap::Iterator it = classBrowsers->begin(); + it != classBrowsers->end(); ++it ) { + if ( it.key() == editor->project()->language() ) + (*it).iface->update( editor->text() ); + else + (*it).iface->clear(); + } +} + +FormWindow *HierarchyView::formWindow() const +{ + return formwindow; +} + +void HierarchyView::closeEvent( QCloseEvent *e ) +{ + emit hidden(); + e->accept(); +} + +void HierarchyView::widgetInserted( QWidget * ) +{ + listview->setup(); +} + +void HierarchyView::widgetRemoved( QWidget * ) +{ + listview->setup(); +} + +void HierarchyView::widgetsInserted( const QWidgetList & ) +{ + listview->setup(); +} + +void HierarchyView::widgetsRemoved( const QWidgetList & ) +{ + listview->setup(); +} + +void HierarchyView::namePropertyChanged( QWidget *w, const QVariant & ) +{ + QWidget *w2 = w; + if ( ::qt_cast(w) ) + w2 = ( (QMainWindow*)w )->centralWidget(); + listview->changeNameOf( w2, w->name() ); +} + + +void HierarchyView::databasePropertyChanged( QWidget *w, const QStringList& info ) +{ +#ifndef QT_NO_SQL + QString i = info.join( "." ); + listview->changeDatabaseOf( w, i ); +#endif +} + + +void HierarchyView::tabsChanged( QTabWidget * ) +{ + listview->setup(); +} + +void HierarchyView::pagesChanged( QWizard * ) +{ + listview->setup(); +} + +void HierarchyView::rebuild() +{ + listview->setup(); +} + +void HierarchyView::closed( FormWindow *fw ) +{ + if ( fw == formwindow ) { + listview->clear(); + fView->clear(); + } +} + +void HierarchyView::updateFormDefinitionView() +{ + fView->setup(); +} + +void HierarchyView::jumpTo( const QString &func, const QString &clss, int type ) +{ + if ( !editor ) + return; + if ( type == ClassBrowserInterface::Class ) + editor->setClass( func ); + else + editor->setFunction( func, clss ); +} + +HierarchyView::ClassBrowser::ClassBrowser( QListView *l, ClassBrowserInterface *i ) + : lv( l ), iface( i ) +{ +} + +HierarchyView::ClassBrowser::~ClassBrowser() +{ +} diff --git a/tools/designer/designer/hierarchyview.h b/tools/designer/designer/hierarchyview.h new file mode 100644 index 0000000..39a13a4 --- /dev/null +++ b/tools/designer/designer/hierarchyview.h @@ -0,0 +1,251 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef HIRARCHYVIEW_H +#define HIRARCHYVIEW_H + +#include +#include +#include +#include +#include +#include "../interfaces/classbrowserinterface.h" + +class FormWindow; +class QCloseEvent; +class QPopupMenu; +class QKeyEvent; +class QMouseEvent; +class QWizard; +class SourceEditor; + +class HierarchyItem : public QListViewItem +{ +public: + enum Type { + Widget, + SlotParent, + SlotPublic, + SlotProtected, + SlotPrivate, + Slot, + DefinitionParent, + Definition, + Event, + EventFunction, + FunctParent, + FunctPublic, + FunctProtected, + FunctPrivate, + Function, + VarParent, + VarPublic, + VarProtected, + VarPrivate, + Variable + }; + + HierarchyItem( Type type, QListViewItem *parent, QListViewItem *after, + const QString &txt1, const QString &txt2, const QString &txt3 ); + HierarchyItem( Type type, QListView *parent, QListViewItem *after, + const QString &txt1, const QString &txt2, const QString &txt3 ); + + void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ); + void updateBackColor(); + + void setObject( QObject *o ); + QObject *object() const; + + void setText( int col, const QString &txt ) { if ( !txt.isEmpty() ) QListViewItem::setText( col, txt ); } + + int rtti() const { return (int)typ; } + +private: + void okRename( int col ); + void cancelRename( int col ); + +private: + QColor backgroundColor(); + QColor backColor; + QObject *obj; + Type typ; + +}; + +class HierarchyList : public QListView +{ + Q_OBJECT + +public: + HierarchyList( QWidget *parent, FormWindow *fw, bool doConnects = TRUE ); + + virtual void setup(); + virtual void setCurrent( QObject *o ); + void setOpen( QListViewItem *i, bool b ); + void changeNameOf( QObject *o, const QString &name ); + void changeDatabaseOf( QObject *o, const QString &info ); + void setFormWindow( FormWindow *fw ) { formWindow = fw; } + void drawContentsOffset( QPainter *p, int ox, int oy, + int cx, int cy, int cw, int ch ) { + setUpdatesEnabled( FALSE ); + triggerUpdate(); + setUpdatesEnabled( TRUE ); + QListView::drawContentsOffset( p, ox, oy, cx, cy, cw, ch ); + } + + void insertEntry( QListViewItem *i, const QPixmap &pix = QPixmap(), const QString &s = QString::null ); + +protected: + void keyPressEvent( QKeyEvent *e ); + void keyReleaseEvent( QKeyEvent *e ); + void viewportMousePressEvent( QMouseEvent *e ); + void viewportMouseReleaseEvent( QMouseEvent *e ); + +public slots: + void addTabPage(); + void removeTabPage(); + +private: + void insertObject( QObject *o, QListViewItem *parent ); + QObject *findObject( QListViewItem *i ); + QListViewItem *findItem( QObject *o ); + QObject *current() const; + QObject *handleObjectClick( QListViewItem *i ); + +private slots: + virtual void objectClicked( QListViewItem *i ); + virtual void objectDoubleClicked( QListViewItem *i ); + virtual void showRMBMenu( QListViewItem *, const QPoint & ); + +protected: + FormWindow *formWindow; + QPopupMenu *normalMenu, *tabWidgetMenu; + bool deselect; + +}; + +class FormDefinitionView : public HierarchyList +{ + Q_OBJECT + +public: + FormDefinitionView( QWidget *parent, FormWindow *fw ); + + void setup(); + void setupVariables(); + void refresh(); + void setCurrent( QWidget *w ); + +protected: + void contentsMouseDoubleClickEvent( QMouseEvent *e ); + +private: + void save( QListViewItem *p, QListViewItem *i ); + void execFunctionDialog( const QString &access, const QString &type, bool addFunc ); + void addVariable( const QString &varName, const QString &access ); + +private slots: + void objectClicked( QListViewItem *i ); + void showRMBMenu( QListViewItem *, const QPoint & ); + void renamed( QListViewItem *i ); + +private: + bool popupOpen; + HierarchyItem *itemSlots, *itemPrivate, *itemProtected, *itemPublic; + HierarchyItem *itemFunct, *itemFunctPriv, *itemFunctProt, *itemFunctPubl; + HierarchyItem *itemVar, *itemVarPriv, *itemVarProt, *itemVarPubl; +}; + + +class HierarchyView : public QTabWidget +{ + Q_OBJECT + +public: + HierarchyView( QWidget *parent ); + ~HierarchyView(); + + void setFormWindow( FormWindow *fw, QObject *o ); + FormWindow *formWindow() const; + SourceEditor *sourceEditor() const { return editor; } + void clear(); + + void showClasses( SourceEditor *se ); + void updateClassBrowsers(); + + void widgetInserted( QWidget *w ); + void widgetRemoved( QWidget *w ); + void widgetsInserted( const QWidgetList &l ); + void widgetsRemoved( const QWidgetList &l ); + void namePropertyChanged( QWidget *w, const QVariant &old ); + void databasePropertyChanged( QWidget *w, const QStringList& info ); + void tabsChanged( QTabWidget *w ); + void pagesChanged( QWizard *w ); + void rebuild(); + void closed( FormWindow *fw ); + void updateFormDefinitionView(); + + FormDefinitionView *formDefinitionView() const { return fView; } + HierarchyList *hierarchyList() const { return listview; } + +protected slots: + void jumpTo( const QString &func, const QString &clss,int type ); + void showClassesTimeout(); + +protected: + void closeEvent( QCloseEvent *e ); + +signals: + void hidden(); + +private: + struct ClassBrowser + { + ClassBrowser( QListView * = 0, ClassBrowserInterface * = 0 ); + ~ClassBrowser(); + QListView *lv; + QInterfacePtr iface; + + Q_DUMMY_COMPARISON_OPERATOR( ClassBrowser ) + }; + FormWindow *formwindow; + HierarchyList *listview; + FormDefinitionView *fView; + SourceEditor *editor; + QMap *classBrowsers; + QGuardedPtr lastSourceEditor; + +}; + + +#endif diff --git a/tools/designer/designer/iconvieweditor.ui b/tools/designer/designer/iconvieweditor.ui new file mode 100644 index 0000000..fe75dab --- /dev/null +++ b/tools/designer/designer/iconvieweditor.ui @@ -0,0 +1,464 @@ + +IconViewEditorBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + IconViewEditorBase + + + + 0 + 0 + 567 + 321 + + + + Edit Iconview + + + true + + + <b>Edit Iconview</b><p>Add, edit or delete items in the icon view.</p><p>Click the <b>New Item</b>-button to create a new item, then enter text and choose a pixmap.</p><p>Select an item from the view and click the <b>Delete Item</b>-button to remove the item from the iconview.</p> + + + + unnamed + + + 11 + + + 6 + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + preview + + + All items in the iconview. + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + itemNew + + + &New Item + + + Add an item + + + Create a new item for the iconview. + + + + + itemDelete + + + &Delete Item + + + Delete item + + + Delete the selected item. + + + + + Vertical Spacing1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + GroupBox1 + + + + 0 + 5 + 0 + 0 + + + + &Item Properties + + + + unnamed + + + 11 + + + 6 + + + + Label1 + + + &Text: + + + itemText + + + + + itemText + + + + 0 + 0 + + + + Change text + + + Change the text for the selected item. + + + + + Label2 + + + &Pixmap: + + + itemChoosePixmap + + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + itemPixmap + + + Label4 + + + + + itemDeletePixmap + + + + 30 + 22 + + + + + + + designer_s_editcut.png + + + Delete Pixmap + + + Delete the selected item's pixmap. + + + + + itemChoosePixmap + + + + 30 + 22 + + + + ... + + + Select a Pixmap + + + Select a pixmap file for the current item. + + + + + + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonApply + + + &Apply + + + true + + + Apply all changes. + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + + + itemNew + clicked() + IconViewEditorBase + insertNewItem() + + + itemDelete + clicked() + IconViewEditorBase + deleteCurrentItem() + + + itemText + textChanged( const QString & ) + IconViewEditorBase + currentTextChanged(const QString&) + + + buttonOk + clicked() + IconViewEditorBase + okClicked() + + + buttonApply + clicked() + IconViewEditorBase + applyClicked() + + + buttonCancel + clicked() + IconViewEditorBase + cancelClicked() + + + itemChoosePixmap + clicked() + IconViewEditorBase + choosePixmap() + + + preview + selectionChanged(QIconViewItem*) + IconViewEditorBase + currentItemChanged(QIconViewItem*) + + + preview + currentChanged(QIconViewItem*) + IconViewEditorBase + currentItemChanged(QIconViewItem*) + + + itemDeletePixmap + clicked() + IconViewEditorBase + deletePixmap() + + + + buttonOk + buttonCancel + preview + itemNew + itemDelete + itemText + itemDeletePixmap + itemChoosePixmap + buttonHelp + buttonApply + + + init() + destroy() + applyClicked() + cancelClicked() + choosePixmap() + currentItemChanged( QIconViewItem * ) + currentTextChanged( const QString & ) + deleteCurrentItem() + insertNewItem() + deletePixmap() + okClicked() + + + + diff --git a/tools/designer/designer/iconvieweditorimpl.cpp b/tools/designer/designer/iconvieweditorimpl.cpp new file mode 100644 index 0000000..09a686a --- /dev/null +++ b/tools/designer/designer/iconvieweditorimpl.cpp @@ -0,0 +1,170 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "iconvieweditorimpl.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "pixmapchooser.h" + +#include +#include +#include +#include +#include + +IconViewEditor::IconViewEditor( QWidget *parent, QWidget *editWidget, FormWindow *fw ) + : IconViewEditorBase( parent, 0, TRUE ), formwindow( fw ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + iconview = (QIconView*)editWidget; + + itemText->setText( "" ); + itemText->setEnabled( FALSE ); + itemPixmap->setText( "" ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + + QIconViewItem *i = 0; + for ( i = iconview->firstItem(); i; i = i->nextItem() ) { + (void)new QIconViewItem( preview, i->text(), *i->pixmap() ); + } + + if ( preview->firstItem() ) + preview->setCurrentItem( preview->firstItem() ); +} + +void IconViewEditor::insertNewItem() +{ + QIconViewItem *i = new QIconViewItem( preview, tr( "New Item" ) ); + preview->setCurrentItem( i ); + preview->setSelected( i, TRUE ); + itemText->setFocus(); + itemText->selectAll(); +} + +void IconViewEditor::deleteCurrentItem() +{ + delete preview->currentItem(); + if ( preview->currentItem() ) + preview->setSelected( preview->currentItem(), TRUE ); +} + +void IconViewEditor::currentItemChanged( QIconViewItem *i ) +{ + itemText->blockSignals( TRUE ); + itemText->setText( "" ); + itemPixmap->setText( "" ); + itemText->blockSignals( FALSE ); + + if ( !i ) { + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + return; + } + + itemText->blockSignals( TRUE ); + itemText->setEnabled( TRUE ); + itemChoosePixmap->setEnabled( TRUE ); + itemDeletePixmap->setEnabled( i->pixmap() && !i->pixmap()->isNull() ); + + itemText->setText( i->text() ); + if ( i->pixmap() ) + itemPixmap->setPixmap( *i->pixmap() ); + itemText->blockSignals( FALSE ); +} + +void IconViewEditor::currentTextChanged( const QString &txt ) +{ + if ( !preview->currentItem() ) + return; + + preview->currentItem()->setText( txt ); +} + +void IconViewEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void IconViewEditor::cancelClicked() +{ + reject(); +} + +void IconViewEditor::applyClicked() +{ + QIconViewItem *i = 0; + QValueList items; + for ( i = preview->firstItem(); i; i = i->nextItem() ) { + PopulateIconViewCommand::Item item; + if ( i->pixmap() ) + item.pix = *i->pixmap(); + item.text = i->text(); + items.append( item ); + } + + PopulateIconViewCommand *cmd = new PopulateIconViewCommand( tr( "Edit the Items of '%1'" ).arg( iconview->name() ), + formwindow, iconview, items ); + cmd->execute(); + formwindow->commandHistory()->addCommand( cmd ); +} + +void IconViewEditor::choosePixmap() +{ + if ( !preview->currentItem() ) + return; + + QPixmap pix; + if ( preview->currentItem()->pixmap() ) + pix = qChoosePixmap( this, formwindow, *preview->currentItem()->pixmap() ); + else + pix = qChoosePixmap( this, formwindow, QPixmap() ); + + if ( pix.isNull() ) + return; + + preview->currentItem()->setPixmap( pix ); + itemPixmap->setPixmap( pix ); + itemDeletePixmap->setEnabled( TRUE ); +} + +void IconViewEditor::deletePixmap() +{ + if ( !preview->currentItem() ) + return; + + preview->currentItem()->setPixmap( QPixmap() ); + itemPixmap->setText( "" ); + itemDeletePixmap->setEnabled( FALSE ); +} diff --git a/tools/designer/designer/iconvieweditorimpl.h b/tools/designer/designer/iconvieweditorimpl.h new file mode 100644 index 0000000..21506f9 --- /dev/null +++ b/tools/designer/designer/iconvieweditorimpl.h @@ -0,0 +1,65 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef ICONVIEWEDITORIMPL_H +#define ICONVIEWEDITORIMPL_H + +#include "iconvieweditor.h" + +class FormWindow; + +class IconViewEditor : public IconViewEditorBase +{ + Q_OBJECT + +public: + IconViewEditor( QWidget *parent, QWidget *editWidget, FormWindow *fw ); + +protected slots: + void insertNewItem(); + void deleteCurrentItem(); + void currentItemChanged( QIconViewItem * ); + void currentTextChanged( const QString & ); + void okClicked(); + void cancelClicked(); + void applyClicked(); + void choosePixmap(); + void deletePixmap(); + +private: + QIconView *iconview; + FormWindow *formwindow; + +}; + +#endif diff --git a/tools/designer/designer/images/designer_adjustsize.png b/tools/designer/designer/images/designer_adjustsize.png new file mode 100644 index 0000000..6ade1e2 Binary files /dev/null and b/tools/designer/designer/images/designer_adjustsize.png differ diff --git a/tools/designer/designer/images/designer_appicon.png b/tools/designer/designer/images/designer_appicon.png new file mode 100644 index 0000000..7aadcba Binary files /dev/null and b/tools/designer/designer/images/designer_appicon.png differ diff --git a/tools/designer/designer/images/designer_arrow.png b/tools/designer/designer/images/designer_arrow.png new file mode 100644 index 0000000..ec9c061 Binary files /dev/null and b/tools/designer/designer/images/designer_arrow.png differ diff --git a/tools/designer/designer/images/designer_background.png b/tools/designer/designer/images/designer_background.png new file mode 100644 index 0000000..27d2e99 Binary files /dev/null and b/tools/designer/designer/images/designer_background.png differ diff --git a/tools/designer/designer/images/designer_book.png b/tools/designer/designer/images/designer_book.png new file mode 100644 index 0000000..dd850ab Binary files /dev/null and b/tools/designer/designer/images/designer_book.png differ diff --git a/tools/designer/designer/images/designer_buttongroup.png b/tools/designer/designer/images/designer_buttongroup.png new file mode 100644 index 0000000..d89e28f Binary files /dev/null and b/tools/designer/designer/images/designer_buttongroup.png differ diff --git a/tools/designer/designer/images/designer_checkbox.png b/tools/designer/designer/images/designer_checkbox.png new file mode 100644 index 0000000..ab6f53e Binary files /dev/null and b/tools/designer/designer/images/designer_checkbox.png differ diff --git a/tools/designer/designer/images/designer_combobox.png b/tools/designer/designer/images/designer_combobox.png new file mode 100644 index 0000000..7d4890a Binary files /dev/null and b/tools/designer/designer/images/designer_combobox.png differ diff --git a/tools/designer/designer/images/designer_connecttool.png b/tools/designer/designer/images/designer_connecttool.png new file mode 100644 index 0000000..fca6748 Binary files /dev/null and b/tools/designer/designer/images/designer_connecttool.png differ diff --git a/tools/designer/designer/images/designer_cross.png b/tools/designer/designer/images/designer_cross.png new file mode 100644 index 0000000..d5e9f0c Binary files /dev/null and b/tools/designer/designer/images/designer_cross.png differ diff --git a/tools/designer/designer/images/designer_customwidget.png b/tools/designer/designer/images/designer_customwidget.png new file mode 100644 index 0000000..ab790e1 Binary files /dev/null and b/tools/designer/designer/images/designer_customwidget.png differ diff --git a/tools/designer/designer/images/designer_d_adjustsize.png b/tools/designer/designer/images/designer_d_adjustsize.png new file mode 100644 index 0000000..bbe30ff Binary files /dev/null and b/tools/designer/designer/images/designer_d_adjustsize.png differ diff --git a/tools/designer/designer/images/designer_d_book.png b/tools/designer/designer/images/designer_d_book.png new file mode 100644 index 0000000..b61d611 Binary files /dev/null and b/tools/designer/designer/images/designer_d_book.png differ diff --git a/tools/designer/designer/images/designer_d_buttongroup.png b/tools/designer/designer/images/designer_d_buttongroup.png new file mode 100644 index 0000000..1e451a8 Binary files /dev/null and b/tools/designer/designer/images/designer_d_buttongroup.png differ diff --git a/tools/designer/designer/images/designer_d_checkbox.png b/tools/designer/designer/images/designer_d_checkbox.png new file mode 100644 index 0000000..1415eab Binary files /dev/null and b/tools/designer/designer/images/designer_d_checkbox.png differ diff --git a/tools/designer/designer/images/designer_d_combobox.png b/tools/designer/designer/images/designer_d_combobox.png new file mode 100644 index 0000000..5fb44ef Binary files /dev/null and b/tools/designer/designer/images/designer_d_combobox.png differ diff --git a/tools/designer/designer/images/designer_d_connecttool.png b/tools/designer/designer/images/designer_d_connecttool.png new file mode 100644 index 0000000..76a3b5f Binary files /dev/null and b/tools/designer/designer/images/designer_d_connecttool.png differ diff --git a/tools/designer/designer/images/designer_d_customwidget.png b/tools/designer/designer/images/designer_d_customwidget.png new file mode 100644 index 0000000..5ea648f Binary files /dev/null and b/tools/designer/designer/images/designer_d_customwidget.png differ diff --git a/tools/designer/designer/images/designer_d_databrowser.png b/tools/designer/designer/images/designer_d_databrowser.png new file mode 100644 index 0000000..115826a Binary files /dev/null and b/tools/designer/designer/images/designer_d_databrowser.png differ diff --git a/tools/designer/designer/images/designer_d_datatable.png b/tools/designer/designer/images/designer_d_datatable.png new file mode 100644 index 0000000..7060dc3 Binary files /dev/null and b/tools/designer/designer/images/designer_d_datatable.png differ diff --git a/tools/designer/designer/images/designer_d_dataview.png b/tools/designer/designer/images/designer_d_dataview.png new file mode 100644 index 0000000..c507d41 Binary files /dev/null and b/tools/designer/designer/images/designer_d_dataview.png differ diff --git a/tools/designer/designer/images/designer_d_dateedit.png b/tools/designer/designer/images/designer_d_dateedit.png new file mode 100644 index 0000000..162e63a Binary files /dev/null and b/tools/designer/designer/images/designer_d_dateedit.png differ diff --git a/tools/designer/designer/images/designer_d_datetimeedit.png b/tools/designer/designer/images/designer_d_datetimeedit.png new file mode 100644 index 0000000..82a7e14 Binary files /dev/null and b/tools/designer/designer/images/designer_d_datetimeedit.png differ diff --git a/tools/designer/designer/images/designer_d_dial.png b/tools/designer/designer/images/designer_d_dial.png new file mode 100644 index 0000000..a84869e Binary files /dev/null and b/tools/designer/designer/images/designer_d_dial.png differ diff --git a/tools/designer/designer/images/designer_d_down.png b/tools/designer/designer/images/designer_d_down.png new file mode 100644 index 0000000..57b407e Binary files /dev/null and b/tools/designer/designer/images/designer_d_down.png differ diff --git a/tools/designer/designer/images/designer_d_editbreaklayout.png b/tools/designer/designer/images/designer_d_editbreaklayout.png new file mode 100644 index 0000000..2a36d67 Binary files /dev/null and b/tools/designer/designer/images/designer_d_editbreaklayout.png differ diff --git a/tools/designer/designer/images/designer_d_editcopy.png b/tools/designer/designer/images/designer_d_editcopy.png new file mode 100644 index 0000000..895e3c6 Binary files /dev/null and b/tools/designer/designer/images/designer_d_editcopy.png differ diff --git a/tools/designer/designer/images/designer_d_editcut.png b/tools/designer/designer/images/designer_d_editcut.png new file mode 100644 index 0000000..8d50ae0 Binary files /dev/null and b/tools/designer/designer/images/designer_d_editcut.png differ diff --git a/tools/designer/designer/images/designer_d_editdelete.png b/tools/designer/designer/images/designer_d_editdelete.png new file mode 100644 index 0000000..e960c58 Binary files /dev/null and b/tools/designer/designer/images/designer_d_editdelete.png differ diff --git a/tools/designer/designer/images/designer_d_editgrid.png b/tools/designer/designer/images/designer_d_editgrid.png new file mode 100644 index 0000000..ad2b87b Binary files /dev/null and b/tools/designer/designer/images/designer_d_editgrid.png differ diff --git a/tools/designer/designer/images/designer_d_edithlayout.png b/tools/designer/designer/images/designer_d_edithlayout.png new file mode 100644 index 0000000..dacaf82 Binary files /dev/null and b/tools/designer/designer/images/designer_d_edithlayout.png differ diff --git a/tools/designer/designer/images/designer_d_edithlayoutsplit.png b/tools/designer/designer/images/designer_d_edithlayoutsplit.png new file mode 100644 index 0000000..00a9605 Binary files /dev/null and b/tools/designer/designer/images/designer_d_edithlayoutsplit.png differ diff --git a/tools/designer/designer/images/designer_d_editlower.png b/tools/designer/designer/images/designer_d_editlower.png new file mode 100644 index 0000000..df7d371 Binary files /dev/null and b/tools/designer/designer/images/designer_d_editlower.png differ diff --git a/tools/designer/designer/images/designer_d_editpaste.png b/tools/designer/designer/images/designer_d_editpaste.png new file mode 100644 index 0000000..48acd7d Binary files /dev/null and b/tools/designer/designer/images/designer_d_editpaste.png differ diff --git a/tools/designer/designer/images/designer_d_editraise.png b/tools/designer/designer/images/designer_d_editraise.png new file mode 100644 index 0000000..5f7f04b Binary files /dev/null and b/tools/designer/designer/images/designer_d_editraise.png differ diff --git a/tools/designer/designer/images/designer_d_editslots.png b/tools/designer/designer/images/designer_d_editslots.png new file mode 100644 index 0000000..c2f900a Binary files /dev/null and b/tools/designer/designer/images/designer_d_editslots.png differ diff --git a/tools/designer/designer/images/designer_d_editvlayout.png b/tools/designer/designer/images/designer_d_editvlayout.png new file mode 100644 index 0000000..ed202af Binary files /dev/null and b/tools/designer/designer/images/designer_d_editvlayout.png differ diff --git a/tools/designer/designer/images/designer_d_editvlayoutsplit.png b/tools/designer/designer/images/designer_d_editvlayoutsplit.png new file mode 100644 index 0000000..54ee44c Binary files /dev/null and b/tools/designer/designer/images/designer_d_editvlayoutsplit.png differ diff --git a/tools/designer/designer/images/designer_d_filenew.png b/tools/designer/designer/images/designer_d_filenew.png new file mode 100644 index 0000000..d5e7061 Binary files /dev/null and b/tools/designer/designer/images/designer_d_filenew.png differ diff --git a/tools/designer/designer/images/designer_d_fileopen.png b/tools/designer/designer/images/designer_d_fileopen.png new file mode 100644 index 0000000..ddbd33d Binary files /dev/null and b/tools/designer/designer/images/designer_d_fileopen.png differ diff --git a/tools/designer/designer/images/designer_d_filesave.png b/tools/designer/designer/images/designer_d_filesave.png new file mode 100644 index 0000000..5d1476d Binary files /dev/null and b/tools/designer/designer/images/designer_d_filesave.png differ diff --git a/tools/designer/designer/images/designer_d_folder.png b/tools/designer/designer/images/designer_d_folder.png new file mode 100644 index 0000000..4bed3ca Binary files /dev/null and b/tools/designer/designer/images/designer_d_folder.png differ diff --git a/tools/designer/designer/images/designer_d_form.png b/tools/designer/designer/images/designer_d_form.png new file mode 100644 index 0000000..9f89d65 Binary files /dev/null and b/tools/designer/designer/images/designer_d_form.png differ diff --git a/tools/designer/designer/images/designer_d_frame.png b/tools/designer/designer/images/designer_d_frame.png new file mode 100644 index 0000000..09b21b2 Binary files /dev/null and b/tools/designer/designer/images/designer_d_frame.png differ diff --git a/tools/designer/designer/images/designer_d_groupbox.png b/tools/designer/designer/images/designer_d_groupbox.png new file mode 100644 index 0000000..e7e0108 Binary files /dev/null and b/tools/designer/designer/images/designer_d_groupbox.png differ diff --git a/tools/designer/designer/images/designer_d_help.png b/tools/designer/designer/images/designer_d_help.png new file mode 100644 index 0000000..8f9d182 Binary files /dev/null and b/tools/designer/designer/images/designer_d_help.png differ diff --git a/tools/designer/designer/images/designer_d_home.png b/tools/designer/designer/images/designer_d_home.png new file mode 100644 index 0000000..b3906a4 Binary files /dev/null and b/tools/designer/designer/images/designer_d_home.png differ diff --git a/tools/designer/designer/images/designer_d_iconview.png b/tools/designer/designer/images/designer_d_iconview.png new file mode 100644 index 0000000..782c362 Binary files /dev/null and b/tools/designer/designer/images/designer_d_iconview.png differ diff --git a/tools/designer/designer/images/designer_d_image.png b/tools/designer/designer/images/designer_d_image.png new file mode 100644 index 0000000..f7cb29c Binary files /dev/null and b/tools/designer/designer/images/designer_d_image.png differ diff --git a/tools/designer/designer/images/designer_d_label.png b/tools/designer/designer/images/designer_d_label.png new file mode 100644 index 0000000..bfbd5b8 Binary files /dev/null and b/tools/designer/designer/images/designer_d_label.png differ diff --git a/tools/designer/designer/images/designer_d_layout.png b/tools/designer/designer/images/designer_d_layout.png new file mode 100644 index 0000000..1ee6095 Binary files /dev/null and b/tools/designer/designer/images/designer_d_layout.png differ diff --git a/tools/designer/designer/images/designer_d_lcdnumber.png b/tools/designer/designer/images/designer_d_lcdnumber.png new file mode 100644 index 0000000..786747e Binary files /dev/null and b/tools/designer/designer/images/designer_d_lcdnumber.png differ diff --git a/tools/designer/designer/images/designer_d_left.png b/tools/designer/designer/images/designer_d_left.png new file mode 100644 index 0000000..50d03bb Binary files /dev/null and b/tools/designer/designer/images/designer_d_left.png differ diff --git a/tools/designer/designer/images/designer_d_line.png b/tools/designer/designer/images/designer_d_line.png new file mode 100644 index 0000000..25b0dae Binary files /dev/null and b/tools/designer/designer/images/designer_d_line.png differ diff --git a/tools/designer/designer/images/designer_d_lineedit.png b/tools/designer/designer/images/designer_d_lineedit.png new file mode 100644 index 0000000..9d34ce9 Binary files /dev/null and b/tools/designer/designer/images/designer_d_lineedit.png differ diff --git a/tools/designer/designer/images/designer_d_listbox.png b/tools/designer/designer/images/designer_d_listbox.png new file mode 100644 index 0000000..d80c790 Binary files /dev/null and b/tools/designer/designer/images/designer_d_listbox.png differ diff --git a/tools/designer/designer/images/designer_d_listview.png b/tools/designer/designer/images/designer_d_listview.png new file mode 100644 index 0000000..dc1338f Binary files /dev/null and b/tools/designer/designer/images/designer_d_listview.png differ diff --git a/tools/designer/designer/images/designer_d_multilineedit.png b/tools/designer/designer/images/designer_d_multilineedit.png new file mode 100644 index 0000000..0532aee Binary files /dev/null and b/tools/designer/designer/images/designer_d_multilineedit.png differ diff --git a/tools/designer/designer/images/designer_d_newform.png b/tools/designer/designer/images/designer_d_newform.png new file mode 100644 index 0000000..ace6130 Binary files /dev/null and b/tools/designer/designer/images/designer_d_newform.png differ diff --git a/tools/designer/designer/images/designer_d_ordertool.png b/tools/designer/designer/images/designer_d_ordertool.png new file mode 100644 index 0000000..61bdc7e Binary files /dev/null and b/tools/designer/designer/images/designer_d_ordertool.png differ diff --git a/tools/designer/designer/images/designer_d_pixlabel.png b/tools/designer/designer/images/designer_d_pixlabel.png new file mode 100644 index 0000000..21e1f49 Binary files /dev/null and b/tools/designer/designer/images/designer_d_pixlabel.png differ diff --git a/tools/designer/designer/images/designer_d_pointer.png b/tools/designer/designer/images/designer_d_pointer.png new file mode 100644 index 0000000..e6903eb Binary files /dev/null and b/tools/designer/designer/images/designer_d_pointer.png differ diff --git a/tools/designer/designer/images/designer_d_print.png b/tools/designer/designer/images/designer_d_print.png new file mode 100644 index 0000000..03ee9b2 Binary files /dev/null and b/tools/designer/designer/images/designer_d_print.png differ diff --git a/tools/designer/designer/images/designer_d_progress.png b/tools/designer/designer/images/designer_d_progress.png new file mode 100644 index 0000000..25d857a Binary files /dev/null and b/tools/designer/designer/images/designer_d_progress.png differ diff --git a/tools/designer/designer/images/designer_d_project.png b/tools/designer/designer/images/designer_d_project.png new file mode 100644 index 0000000..b265eae Binary files /dev/null and b/tools/designer/designer/images/designer_d_project.png differ diff --git a/tools/designer/designer/images/designer_d_pushbutton.png b/tools/designer/designer/images/designer_d_pushbutton.png new file mode 100644 index 0000000..635f35c Binary files /dev/null and b/tools/designer/designer/images/designer_d_pushbutton.png differ diff --git a/tools/designer/designer/images/designer_d_radiobutton.png b/tools/designer/designer/images/designer_d_radiobutton.png new file mode 100644 index 0000000..e86eb8c Binary files /dev/null and b/tools/designer/designer/images/designer_d_radiobutton.png differ diff --git a/tools/designer/designer/images/designer_d_redo.png b/tools/designer/designer/images/designer_d_redo.png new file mode 100644 index 0000000..6e993cc Binary files /dev/null and b/tools/designer/designer/images/designer_d_redo.png differ diff --git a/tools/designer/designer/images/designer_d_richtextedit.png b/tools/designer/designer/images/designer_d_richtextedit.png new file mode 100644 index 0000000..ba7ada1 Binary files /dev/null and b/tools/designer/designer/images/designer_d_richtextedit.png differ diff --git a/tools/designer/designer/images/designer_d_right.png b/tools/designer/designer/images/designer_d_right.png new file mode 100644 index 0000000..9dbf2dd Binary files /dev/null and b/tools/designer/designer/images/designer_d_right.png differ diff --git a/tools/designer/designer/images/designer_d_scrollbar.png b/tools/designer/designer/images/designer_d_scrollbar.png new file mode 100644 index 0000000..9a81897 Binary files /dev/null and b/tools/designer/designer/images/designer_d_scrollbar.png differ diff --git a/tools/designer/designer/images/designer_d_searchfind.png b/tools/designer/designer/images/designer_d_searchfind.png new file mode 100644 index 0000000..e85e33f Binary files /dev/null and b/tools/designer/designer/images/designer_d_searchfind.png differ diff --git a/tools/designer/designer/images/designer_d_setbuddy.png b/tools/designer/designer/images/designer_d_setbuddy.png new file mode 100644 index 0000000..fe816aa Binary files /dev/null and b/tools/designer/designer/images/designer_d_setbuddy.png differ diff --git a/tools/designer/designer/images/designer_d_slider.png b/tools/designer/designer/images/designer_d_slider.png new file mode 100644 index 0000000..a1ad5d5 Binary files /dev/null and b/tools/designer/designer/images/designer_d_slider.png differ diff --git a/tools/designer/designer/images/designer_d_spacer.png b/tools/designer/designer/images/designer_d_spacer.png new file mode 100644 index 0000000..15319d9 Binary files /dev/null and b/tools/designer/designer/images/designer_d_spacer.png differ diff --git a/tools/designer/designer/images/designer_d_spinbox.png b/tools/designer/designer/images/designer_d_spinbox.png new file mode 100644 index 0000000..cafbe01 Binary files /dev/null and b/tools/designer/designer/images/designer_d_spinbox.png differ diff --git a/tools/designer/designer/images/designer_d_table.png b/tools/designer/designer/images/designer_d_table.png new file mode 100644 index 0000000..a95bde1 Binary files /dev/null and b/tools/designer/designer/images/designer_d_table.png differ diff --git a/tools/designer/designer/images/designer_d_tabwidget.png b/tools/designer/designer/images/designer_d_tabwidget.png new file mode 100644 index 0000000..0f0bad0 Binary files /dev/null and b/tools/designer/designer/images/designer_d_tabwidget.png differ diff --git a/tools/designer/designer/images/designer_d_textbold.png b/tools/designer/designer/images/designer_d_textbold.png new file mode 100644 index 0000000..402a157 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textbold.png differ diff --git a/tools/designer/designer/images/designer_d_textbrowser.png b/tools/designer/designer/images/designer_d_textbrowser.png new file mode 100644 index 0000000..b4315f9 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textbrowser.png differ diff --git a/tools/designer/designer/images/designer_d_textcenter.png b/tools/designer/designer/images/designer_d_textcenter.png new file mode 100644 index 0000000..7a66036 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textcenter.png differ diff --git a/tools/designer/designer/images/designer_d_textedit.png b/tools/designer/designer/images/designer_d_textedit.png new file mode 100644 index 0000000..6931414 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textedit.png differ diff --git a/tools/designer/designer/images/designer_d_textfont.png b/tools/designer/designer/images/designer_d_textfont.png new file mode 100644 index 0000000..beb2112 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textfont.png differ diff --git a/tools/designer/designer/images/designer_d_texth1.png b/tools/designer/designer/images/designer_d_texth1.png new file mode 100644 index 0000000..bfffe02 Binary files /dev/null and b/tools/designer/designer/images/designer_d_texth1.png differ diff --git a/tools/designer/designer/images/designer_d_texth2.png b/tools/designer/designer/images/designer_d_texth2.png new file mode 100644 index 0000000..e90437b Binary files /dev/null and b/tools/designer/designer/images/designer_d_texth2.png differ diff --git a/tools/designer/designer/images/designer_d_texth3.png b/tools/designer/designer/images/designer_d_texth3.png new file mode 100644 index 0000000..dd527e3 Binary files /dev/null and b/tools/designer/designer/images/designer_d_texth3.png differ diff --git a/tools/designer/designer/images/designer_d_textitalic.png b/tools/designer/designer/images/designer_d_textitalic.png new file mode 100644 index 0000000..253ed9c Binary files /dev/null and b/tools/designer/designer/images/designer_d_textitalic.png differ diff --git a/tools/designer/designer/images/designer_d_textjustify.png b/tools/designer/designer/images/designer_d_textjustify.png new file mode 100644 index 0000000..3fb3cc3 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textjustify.png differ diff --git a/tools/designer/designer/images/designer_d_textlarger.png b/tools/designer/designer/images/designer_d_textlarger.png new file mode 100644 index 0000000..ecc35f5 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textlarger.png differ diff --git a/tools/designer/designer/images/designer_d_textleft.png b/tools/designer/designer/images/designer_d_textleft.png new file mode 100644 index 0000000..26db80f Binary files /dev/null and b/tools/designer/designer/images/designer_d_textleft.png differ diff --git a/tools/designer/designer/images/designer_d_textlinebreak.png b/tools/designer/designer/images/designer_d_textlinebreak.png new file mode 100644 index 0000000..b48e323 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textlinebreak.png differ diff --git a/tools/designer/designer/images/designer_d_textparagraph.png b/tools/designer/designer/images/designer_d_textparagraph.png new file mode 100644 index 0000000..a7ef75c Binary files /dev/null and b/tools/designer/designer/images/designer_d_textparagraph.png differ diff --git a/tools/designer/designer/images/designer_d_textright.png b/tools/designer/designer/images/designer_d_textright.png new file mode 100644 index 0000000..d2954e9 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textright.png differ diff --git a/tools/designer/designer/images/designer_d_textsmaller.png b/tools/designer/designer/images/designer_d_textsmaller.png new file mode 100644 index 0000000..00734e7 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textsmaller.png differ diff --git a/tools/designer/designer/images/designer_d_textteletext.png b/tools/designer/designer/images/designer_d_textteletext.png new file mode 100644 index 0000000..6459730 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textteletext.png differ diff --git a/tools/designer/designer/images/designer_d_textunderline.png b/tools/designer/designer/images/designer_d_textunderline.png new file mode 100644 index 0000000..4793445 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textunderline.png differ diff --git a/tools/designer/designer/images/designer_d_textview.png b/tools/designer/designer/images/designer_d_textview.png new file mode 100644 index 0000000..05ce9c6 Binary files /dev/null and b/tools/designer/designer/images/designer_d_textview.png differ diff --git a/tools/designer/designer/images/designer_d_timeedit.png b/tools/designer/designer/images/designer_d_timeedit.png new file mode 100644 index 0000000..955144e Binary files /dev/null and b/tools/designer/designer/images/designer_d_timeedit.png differ diff --git a/tools/designer/designer/images/designer_d_toolbox.png b/tools/designer/designer/images/designer_d_toolbox.png new file mode 100644 index 0000000..e1f8447 Binary files /dev/null and b/tools/designer/designer/images/designer_d_toolbox.png differ diff --git a/tools/designer/designer/images/designer_d_toolbutton.png b/tools/designer/designer/images/designer_d_toolbutton.png new file mode 100644 index 0000000..08e309a Binary files /dev/null and b/tools/designer/designer/images/designer_d_toolbutton.png differ diff --git a/tools/designer/designer/images/designer_d_undo.png b/tools/designer/designer/images/designer_d_undo.png new file mode 100644 index 0000000..22ac97f Binary files /dev/null and b/tools/designer/designer/images/designer_d_undo.png differ diff --git a/tools/designer/designer/images/designer_d_up.png b/tools/designer/designer/images/designer_d_up.png new file mode 100644 index 0000000..4c3ab7c Binary files /dev/null and b/tools/designer/designer/images/designer_d_up.png differ diff --git a/tools/designer/designer/images/designer_d_widgetstack.png b/tools/designer/designer/images/designer_d_widgetstack.png new file mode 100644 index 0000000..c62f8e1 Binary files /dev/null and b/tools/designer/designer/images/designer_d_widgetstack.png differ diff --git a/tools/designer/designer/images/designer_d_wizarddata.png b/tools/designer/designer/images/designer_d_wizarddata.png new file mode 100644 index 0000000..fb540b8 Binary files /dev/null and b/tools/designer/designer/images/designer_d_wizarddata.png differ diff --git a/tools/designer/designer/images/designer_d_wizarddialog.png b/tools/designer/designer/images/designer_d_wizarddialog.png new file mode 100644 index 0000000..b83ca7e Binary files /dev/null and b/tools/designer/designer/images/designer_d_wizarddialog.png differ diff --git a/tools/designer/designer/images/designer_d_wordwrap.png b/tools/designer/designer/images/designer_d_wordwrap.png new file mode 100644 index 0000000..f3f5d96 Binary files /dev/null and b/tools/designer/designer/images/designer_d_wordwrap.png differ diff --git a/tools/designer/designer/images/designer_databrowser.png b/tools/designer/designer/images/designer_databrowser.png new file mode 100644 index 0000000..1dd9578 Binary files /dev/null and b/tools/designer/designer/images/designer_databrowser.png differ diff --git a/tools/designer/designer/images/designer_datatable.png b/tools/designer/designer/images/designer_datatable.png new file mode 100644 index 0000000..5b3bfc7 Binary files /dev/null and b/tools/designer/designer/images/designer_datatable.png differ diff --git a/tools/designer/designer/images/designer_dataview.png b/tools/designer/designer/images/designer_dataview.png new file mode 100644 index 0000000..5f6aad3 Binary files /dev/null and b/tools/designer/designer/images/designer_dataview.png differ diff --git a/tools/designer/designer/images/designer_dateedit.png b/tools/designer/designer/images/designer_dateedit.png new file mode 100644 index 0000000..48286be Binary files /dev/null and b/tools/designer/designer/images/designer_dateedit.png differ diff --git a/tools/designer/designer/images/designer_datetimeedit.png b/tools/designer/designer/images/designer_datetimeedit.png new file mode 100644 index 0000000..68a5673 Binary files /dev/null and b/tools/designer/designer/images/designer_datetimeedit.png differ diff --git a/tools/designer/designer/images/designer_dial.png b/tools/designer/designer/images/designer_dial.png new file mode 100644 index 0000000..3de30f1 Binary files /dev/null and b/tools/designer/designer/images/designer_dial.png differ diff --git a/tools/designer/designer/images/designer_down.png b/tools/designer/designer/images/designer_down.png new file mode 100644 index 0000000..3269dec Binary files /dev/null and b/tools/designer/designer/images/designer_down.png differ diff --git a/tools/designer/designer/images/designer_editbreaklayout.png b/tools/designer/designer/images/designer_editbreaklayout.png new file mode 100644 index 0000000..badbb8e Binary files /dev/null and b/tools/designer/designer/images/designer_editbreaklayout.png differ diff --git a/tools/designer/designer/images/designer_editcopy.png b/tools/designer/designer/images/designer_editcopy.png new file mode 100644 index 0000000..2f931cb Binary files /dev/null and b/tools/designer/designer/images/designer_editcopy.png differ diff --git a/tools/designer/designer/images/designer_editcut.png b/tools/designer/designer/images/designer_editcut.png new file mode 100644 index 0000000..a911482 Binary files /dev/null and b/tools/designer/designer/images/designer_editcut.png differ diff --git a/tools/designer/designer/images/designer_editdelete.png b/tools/designer/designer/images/designer_editdelete.png new file mode 100644 index 0000000..9f0491d Binary files /dev/null and b/tools/designer/designer/images/designer_editdelete.png differ diff --git a/tools/designer/designer/images/designer_editgrid.png b/tools/designer/designer/images/designer_editgrid.png new file mode 100644 index 0000000..e1159bb Binary files /dev/null and b/tools/designer/designer/images/designer_editgrid.png differ diff --git a/tools/designer/designer/images/designer_edithlayout.png b/tools/designer/designer/images/designer_edithlayout.png new file mode 100644 index 0000000..1a2b150 Binary files /dev/null and b/tools/designer/designer/images/designer_edithlayout.png differ diff --git a/tools/designer/designer/images/designer_edithlayoutsplit.png b/tools/designer/designer/images/designer_edithlayoutsplit.png new file mode 100644 index 0000000..cba102b Binary files /dev/null and b/tools/designer/designer/images/designer_edithlayoutsplit.png differ diff --git a/tools/designer/designer/images/designer_editlower.png b/tools/designer/designer/images/designer_editlower.png new file mode 100644 index 0000000..50605f2 Binary files /dev/null and b/tools/designer/designer/images/designer_editlower.png differ diff --git a/tools/designer/designer/images/designer_editpaste.png b/tools/designer/designer/images/designer_editpaste.png new file mode 100644 index 0000000..b1b7f85 Binary files /dev/null and b/tools/designer/designer/images/designer_editpaste.png differ diff --git a/tools/designer/designer/images/designer_editraise.png b/tools/designer/designer/images/designer_editraise.png new file mode 100644 index 0000000..f157251 Binary files /dev/null and b/tools/designer/designer/images/designer_editraise.png differ diff --git a/tools/designer/designer/images/designer_editslots.png b/tools/designer/designer/images/designer_editslots.png new file mode 100644 index 0000000..b86bddb Binary files /dev/null and b/tools/designer/designer/images/designer_editslots.png differ diff --git a/tools/designer/designer/images/designer_editvlayout.png b/tools/designer/designer/images/designer_editvlayout.png new file mode 100644 index 0000000..f4cd3f9 Binary files /dev/null and b/tools/designer/designer/images/designer_editvlayout.png differ diff --git a/tools/designer/designer/images/designer_editvlayoutsplit.png b/tools/designer/designer/images/designer_editvlayoutsplit.png new file mode 100644 index 0000000..0180cf5 Binary files /dev/null and b/tools/designer/designer/images/designer_editvlayoutsplit.png differ diff --git a/tools/designer/designer/images/designer_filenew.png b/tools/designer/designer/images/designer_filenew.png new file mode 100644 index 0000000..9520080 Binary files /dev/null and b/tools/designer/designer/images/designer_filenew.png differ diff --git a/tools/designer/designer/images/designer_fileopen.png b/tools/designer/designer/images/designer_fileopen.png new file mode 100644 index 0000000..3005290 Binary files /dev/null and b/tools/designer/designer/images/designer_fileopen.png differ diff --git a/tools/designer/designer/images/designer_filesave.png b/tools/designer/designer/images/designer_filesave.png new file mode 100644 index 0000000..c137165 Binary files /dev/null and b/tools/designer/designer/images/designer_filesave.png differ diff --git a/tools/designer/designer/images/designer_folder.png b/tools/designer/designer/images/designer_folder.png new file mode 100644 index 0000000..7007e37 Binary files /dev/null and b/tools/designer/designer/images/designer_folder.png differ diff --git a/tools/designer/designer/images/designer_form.png b/tools/designer/designer/images/designer_form.png new file mode 100644 index 0000000..08268bf Binary files /dev/null and b/tools/designer/designer/images/designer_form.png differ diff --git a/tools/designer/designer/images/designer_frame.png b/tools/designer/designer/images/designer_frame.png new file mode 100644 index 0000000..c070b9c Binary files /dev/null and b/tools/designer/designer/images/designer_frame.png differ diff --git a/tools/designer/designer/images/designer_groupbox.png b/tools/designer/designer/images/designer_groupbox.png new file mode 100644 index 0000000..4025b4d Binary files /dev/null and b/tools/designer/designer/images/designer_groupbox.png differ diff --git a/tools/designer/designer/images/designer_hand.png b/tools/designer/designer/images/designer_hand.png new file mode 100644 index 0000000..dd8af74 Binary files /dev/null and b/tools/designer/designer/images/designer_hand.png differ diff --git a/tools/designer/designer/images/designer_help.png b/tools/designer/designer/images/designer_help.png new file mode 100644 index 0000000..2ab2c25 Binary files /dev/null and b/tools/designer/designer/images/designer_help.png differ diff --git a/tools/designer/designer/images/designer_home.png b/tools/designer/designer/images/designer_home.png new file mode 100644 index 0000000..806d11d Binary files /dev/null and b/tools/designer/designer/images/designer_home.png differ diff --git a/tools/designer/designer/images/designer_hsplit.png b/tools/designer/designer/images/designer_hsplit.png new file mode 100644 index 0000000..232faf1 Binary files /dev/null and b/tools/designer/designer/images/designer_hsplit.png differ diff --git a/tools/designer/designer/images/designer_ibeam.png b/tools/designer/designer/images/designer_ibeam.png new file mode 100644 index 0000000..6074c89 Binary files /dev/null and b/tools/designer/designer/images/designer_ibeam.png differ diff --git a/tools/designer/designer/images/designer_iconview.png b/tools/designer/designer/images/designer_iconview.png new file mode 100644 index 0000000..13b8f15 Binary files /dev/null and b/tools/designer/designer/images/designer_iconview.png differ diff --git a/tools/designer/designer/images/designer_image.png b/tools/designer/designer/images/designer_image.png new file mode 100644 index 0000000..29854df Binary files /dev/null and b/tools/designer/designer/images/designer_image.png differ diff --git a/tools/designer/designer/images/designer_label.png b/tools/designer/designer/images/designer_label.png new file mode 100644 index 0000000..5d7d7b4 Binary files /dev/null and b/tools/designer/designer/images/designer_label.png differ diff --git a/tools/designer/designer/images/designer_layout.png b/tools/designer/designer/images/designer_layout.png new file mode 100644 index 0000000..168eb1f Binary files /dev/null and b/tools/designer/designer/images/designer_layout.png differ diff --git a/tools/designer/designer/images/designer_lcdnumber.png b/tools/designer/designer/images/designer_lcdnumber.png new file mode 100644 index 0000000..64eda5e Binary files /dev/null and b/tools/designer/designer/images/designer_lcdnumber.png differ diff --git a/tools/designer/designer/images/designer_left.png b/tools/designer/designer/images/designer_left.png new file mode 100644 index 0000000..e58177f Binary files /dev/null and b/tools/designer/designer/images/designer_left.png differ diff --git a/tools/designer/designer/images/designer_line.png b/tools/designer/designer/images/designer_line.png new file mode 100644 index 0000000..5c64dfb Binary files /dev/null and b/tools/designer/designer/images/designer_line.png differ diff --git a/tools/designer/designer/images/designer_lineedit.png b/tools/designer/designer/images/designer_lineedit.png new file mode 100644 index 0000000..75fc890 Binary files /dev/null and b/tools/designer/designer/images/designer_lineedit.png differ diff --git a/tools/designer/designer/images/designer_listbox.png b/tools/designer/designer/images/designer_listbox.png new file mode 100644 index 0000000..1c58cb6 Binary files /dev/null and b/tools/designer/designer/images/designer_listbox.png differ diff --git a/tools/designer/designer/images/designer_listview.png b/tools/designer/designer/images/designer_listview.png new file mode 100644 index 0000000..d71cc1c Binary files /dev/null and b/tools/designer/designer/images/designer_listview.png differ diff --git a/tools/designer/designer/images/designer_multilineedit.png b/tools/designer/designer/images/designer_multilineedit.png new file mode 100644 index 0000000..26f7ef0 Binary files /dev/null and b/tools/designer/designer/images/designer_multilineedit.png differ diff --git a/tools/designer/designer/images/designer_newform.png b/tools/designer/designer/images/designer_newform.png new file mode 100644 index 0000000..37779c1 Binary files /dev/null and b/tools/designer/designer/images/designer_newform.png differ diff --git a/tools/designer/designer/images/designer_no.png b/tools/designer/designer/images/designer_no.png new file mode 100644 index 0000000..8bacc04 Binary files /dev/null and b/tools/designer/designer/images/designer_no.png differ diff --git a/tools/designer/designer/images/designer_object.png b/tools/designer/designer/images/designer_object.png new file mode 100644 index 0000000..cc4192e Binary files /dev/null and b/tools/designer/designer/images/designer_object.png differ diff --git a/tools/designer/designer/images/designer_ordertool.png b/tools/designer/designer/images/designer_ordertool.png new file mode 100644 index 0000000..ad12283 Binary files /dev/null and b/tools/designer/designer/images/designer_ordertool.png differ diff --git a/tools/designer/designer/images/designer_pixlabel.png b/tools/designer/designer/images/designer_pixlabel.png new file mode 100644 index 0000000..0d54d63 Binary files /dev/null and b/tools/designer/designer/images/designer_pixlabel.png differ diff --git a/tools/designer/designer/images/designer_pointer.png b/tools/designer/designer/images/designer_pointer.png new file mode 100644 index 0000000..67e38a3 Binary files /dev/null and b/tools/designer/designer/images/designer_pointer.png differ diff --git a/tools/designer/designer/images/designer_print.png b/tools/designer/designer/images/designer_print.png new file mode 100644 index 0000000..57e3e53 Binary files /dev/null and b/tools/designer/designer/images/designer_print.png differ diff --git a/tools/designer/designer/images/designer_progress.png b/tools/designer/designer/images/designer_progress.png new file mode 100644 index 0000000..44ae094 Binary files /dev/null and b/tools/designer/designer/images/designer_progress.png differ diff --git a/tools/designer/designer/images/designer_project.png b/tools/designer/designer/images/designer_project.png new file mode 100644 index 0000000..6a0fb96 Binary files /dev/null and b/tools/designer/designer/images/designer_project.png differ diff --git a/tools/designer/designer/images/designer_pushbutton.png b/tools/designer/designer/images/designer_pushbutton.png new file mode 100644 index 0000000..61f779c Binary files /dev/null and b/tools/designer/designer/images/designer_pushbutton.png differ diff --git a/tools/designer/designer/images/designer_qtlogo.png b/tools/designer/designer/images/designer_qtlogo.png new file mode 100644 index 0000000..4e1a147 Binary files /dev/null and b/tools/designer/designer/images/designer_qtlogo.png differ diff --git a/tools/designer/designer/images/designer_radiobutton.png b/tools/designer/designer/images/designer_radiobutton.png new file mode 100644 index 0000000..10c1d8c Binary files /dev/null and b/tools/designer/designer/images/designer_radiobutton.png differ diff --git a/tools/designer/designer/images/designer_redo.png b/tools/designer/designer/images/designer_redo.png new file mode 100644 index 0000000..abdad26 Binary files /dev/null and b/tools/designer/designer/images/designer_redo.png differ diff --git a/tools/designer/designer/images/designer_resetproperty.png b/tools/designer/designer/images/designer_resetproperty.png new file mode 100644 index 0000000..cc0d6a2 Binary files /dev/null and b/tools/designer/designer/images/designer_resetproperty.png differ diff --git a/tools/designer/designer/images/designer_richtextedit.png b/tools/designer/designer/images/designer_richtextedit.png new file mode 100644 index 0000000..73573a8 Binary files /dev/null and b/tools/designer/designer/images/designer_richtextedit.png differ diff --git a/tools/designer/designer/images/designer_right.png b/tools/designer/designer/images/designer_right.png new file mode 100644 index 0000000..5f2f703 Binary files /dev/null and b/tools/designer/designer/images/designer_right.png differ diff --git a/tools/designer/designer/images/designer_s_down.png b/tools/designer/designer/images/designer_s_down.png new file mode 100644 index 0000000..908e55e Binary files /dev/null and b/tools/designer/designer/images/designer_s_down.png differ diff --git a/tools/designer/designer/images/designer_s_editcut.png b/tools/designer/designer/images/designer_s_editcut.png new file mode 100644 index 0000000..7cf5a9e Binary files /dev/null and b/tools/designer/designer/images/designer_s_editcut.png differ diff --git a/tools/designer/designer/images/designer_s_left.png b/tools/designer/designer/images/designer_s_left.png new file mode 100644 index 0000000..e6e19f8 Binary files /dev/null and b/tools/designer/designer/images/designer_s_left.png differ diff --git a/tools/designer/designer/images/designer_s_right.png b/tools/designer/designer/images/designer_s_right.png new file mode 100644 index 0000000..bfccda6 Binary files /dev/null and b/tools/designer/designer/images/designer_s_right.png differ diff --git a/tools/designer/designer/images/designer_s_up.png b/tools/designer/designer/images/designer_s_up.png new file mode 100644 index 0000000..97705d4 Binary files /dev/null and b/tools/designer/designer/images/designer_s_up.png differ diff --git a/tools/designer/designer/images/designer_scrollbar.png b/tools/designer/designer/images/designer_scrollbar.png new file mode 100644 index 0000000..466c58d Binary files /dev/null and b/tools/designer/designer/images/designer_scrollbar.png differ diff --git a/tools/designer/designer/images/designer_searchfind.png b/tools/designer/designer/images/designer_searchfind.png new file mode 100644 index 0000000..3f369fd Binary files /dev/null and b/tools/designer/designer/images/designer_searchfind.png differ diff --git a/tools/designer/designer/images/designer_setbuddy.png b/tools/designer/designer/images/designer_setbuddy.png new file mode 100644 index 0000000..5ae9e1a Binary files /dev/null and b/tools/designer/designer/images/designer_setbuddy.png differ diff --git a/tools/designer/designer/images/designer_sizeall.png b/tools/designer/designer/images/designer_sizeall.png new file mode 100644 index 0000000..fa2a266 Binary files /dev/null and b/tools/designer/designer/images/designer_sizeall.png differ diff --git a/tools/designer/designer/images/designer_sizeb.png b/tools/designer/designer/images/designer_sizeb.png new file mode 100644 index 0000000..ac5235b Binary files /dev/null and b/tools/designer/designer/images/designer_sizeb.png differ diff --git a/tools/designer/designer/images/designer_sizef.png b/tools/designer/designer/images/designer_sizef.png new file mode 100644 index 0000000..28a30c2 Binary files /dev/null and b/tools/designer/designer/images/designer_sizef.png differ diff --git a/tools/designer/designer/images/designer_sizeh.png b/tools/designer/designer/images/designer_sizeh.png new file mode 100644 index 0000000..7b8abd3 Binary files /dev/null and b/tools/designer/designer/images/designer_sizeh.png differ diff --git a/tools/designer/designer/images/designer_sizev.png b/tools/designer/designer/images/designer_sizev.png new file mode 100644 index 0000000..80b3d8b Binary files /dev/null and b/tools/designer/designer/images/designer_sizev.png differ diff --git a/tools/designer/designer/images/designer_slider.png b/tools/designer/designer/images/designer_slider.png new file mode 100644 index 0000000..525bd1c Binary files /dev/null and b/tools/designer/designer/images/designer_slider.png differ diff --git a/tools/designer/designer/images/designer_spacer.png b/tools/designer/designer/images/designer_spacer.png new file mode 100644 index 0000000..926e8af Binary files /dev/null and b/tools/designer/designer/images/designer_spacer.png differ diff --git a/tools/designer/designer/images/designer_spinbox.png b/tools/designer/designer/images/designer_spinbox.png new file mode 100644 index 0000000..7ae2063 Binary files /dev/null and b/tools/designer/designer/images/designer_spinbox.png differ diff --git a/tools/designer/designer/images/designer_splash.png b/tools/designer/designer/images/designer_splash.png new file mode 100644 index 0000000..d3b62a1 Binary files /dev/null and b/tools/designer/designer/images/designer_splash.png differ diff --git a/tools/designer/designer/images/designer_table.png b/tools/designer/designer/images/designer_table.png new file mode 100644 index 0000000..4bbd9c2 Binary files /dev/null and b/tools/designer/designer/images/designer_table.png differ diff --git a/tools/designer/designer/images/designer_tabwidget.png b/tools/designer/designer/images/designer_tabwidget.png new file mode 100644 index 0000000..1254bb6 Binary files /dev/null and b/tools/designer/designer/images/designer_tabwidget.png differ diff --git a/tools/designer/designer/images/designer_textbold.png b/tools/designer/designer/images/designer_textbold.png new file mode 100644 index 0000000..7b5be47 Binary files /dev/null and b/tools/designer/designer/images/designer_textbold.png differ diff --git a/tools/designer/designer/images/designer_textbrowser.png b/tools/designer/designer/images/designer_textbrowser.png new file mode 100644 index 0000000..090e2f8 Binary files /dev/null and b/tools/designer/designer/images/designer_textbrowser.png differ diff --git a/tools/designer/designer/images/designer_textcenter.png b/tools/designer/designer/images/designer_textcenter.png new file mode 100644 index 0000000..5c68b09 Binary files /dev/null and b/tools/designer/designer/images/designer_textcenter.png differ diff --git a/tools/designer/designer/images/designer_textedit.png b/tools/designer/designer/images/designer_textedit.png new file mode 100644 index 0000000..4cdff14 Binary files /dev/null and b/tools/designer/designer/images/designer_textedit.png differ diff --git a/tools/designer/designer/images/designer_textfont.png b/tools/designer/designer/images/designer_textfont.png new file mode 100644 index 0000000..a4de87a Binary files /dev/null and b/tools/designer/designer/images/designer_textfont.png differ diff --git a/tools/designer/designer/images/designer_texth1.png b/tools/designer/designer/images/designer_texth1.png new file mode 100644 index 0000000..1c3aa2f Binary files /dev/null and b/tools/designer/designer/images/designer_texth1.png differ diff --git a/tools/designer/designer/images/designer_texth2.png b/tools/designer/designer/images/designer_texth2.png new file mode 100644 index 0000000..b3a02af Binary files /dev/null and b/tools/designer/designer/images/designer_texth2.png differ diff --git a/tools/designer/designer/images/designer_texth3.png b/tools/designer/designer/images/designer_texth3.png new file mode 100644 index 0000000..c02ea26 Binary files /dev/null and b/tools/designer/designer/images/designer_texth3.png differ diff --git a/tools/designer/designer/images/designer_textitalic.png b/tools/designer/designer/images/designer_textitalic.png new file mode 100644 index 0000000..68e2b44 Binary files /dev/null and b/tools/designer/designer/images/designer_textitalic.png differ diff --git a/tools/designer/designer/images/designer_textjustify.png b/tools/designer/designer/images/designer_textjustify.png new file mode 100644 index 0000000..1c6e5b9 Binary files /dev/null and b/tools/designer/designer/images/designer_textjustify.png differ diff --git a/tools/designer/designer/images/designer_textlarger.png b/tools/designer/designer/images/designer_textlarger.png new file mode 100644 index 0000000..20282b6 Binary files /dev/null and b/tools/designer/designer/images/designer_textlarger.png differ diff --git a/tools/designer/designer/images/designer_textleft.png b/tools/designer/designer/images/designer_textleft.png new file mode 100644 index 0000000..30b0501 Binary files /dev/null and b/tools/designer/designer/images/designer_textleft.png differ diff --git a/tools/designer/designer/images/designer_textlinebreak.png b/tools/designer/designer/images/designer_textlinebreak.png new file mode 100644 index 0000000..081a49e Binary files /dev/null and b/tools/designer/designer/images/designer_textlinebreak.png differ diff --git a/tools/designer/designer/images/designer_textparagraph.png b/tools/designer/designer/images/designer_textparagraph.png new file mode 100644 index 0000000..dcd0b3e Binary files /dev/null and b/tools/designer/designer/images/designer_textparagraph.png differ diff --git a/tools/designer/designer/images/designer_textright.png b/tools/designer/designer/images/designer_textright.png new file mode 100644 index 0000000..73f1cad Binary files /dev/null and b/tools/designer/designer/images/designer_textright.png differ diff --git a/tools/designer/designer/images/designer_textsmaller.png b/tools/designer/designer/images/designer_textsmaller.png new file mode 100644 index 0000000..acf2577 Binary files /dev/null and b/tools/designer/designer/images/designer_textsmaller.png differ diff --git a/tools/designer/designer/images/designer_textteletext.png b/tools/designer/designer/images/designer_textteletext.png new file mode 100644 index 0000000..c020463 Binary files /dev/null and b/tools/designer/designer/images/designer_textteletext.png differ diff --git a/tools/designer/designer/images/designer_textunderline.png b/tools/designer/designer/images/designer_textunderline.png new file mode 100644 index 0000000..3477ccb Binary files /dev/null and b/tools/designer/designer/images/designer_textunderline.png differ diff --git a/tools/designer/designer/images/designer_textview.png b/tools/designer/designer/images/designer_textview.png new file mode 100644 index 0000000..ec2270c Binary files /dev/null and b/tools/designer/designer/images/designer_textview.png differ diff --git a/tools/designer/designer/images/designer_timeedit.png b/tools/designer/designer/images/designer_timeedit.png new file mode 100644 index 0000000..01b3788 Binary files /dev/null and b/tools/designer/designer/images/designer_timeedit.png differ diff --git a/tools/designer/designer/images/designer_toolbox.png b/tools/designer/designer/images/designer_toolbox.png new file mode 100644 index 0000000..2ab71dc Binary files /dev/null and b/tools/designer/designer/images/designer_toolbox.png differ diff --git a/tools/designer/designer/images/designer_toolbutton.png b/tools/designer/designer/images/designer_toolbutton.png new file mode 100644 index 0000000..49921a1 Binary files /dev/null and b/tools/designer/designer/images/designer_toolbutton.png differ diff --git a/tools/designer/designer/images/designer_undo.png b/tools/designer/designer/images/designer_undo.png new file mode 100644 index 0000000..839a823 Binary files /dev/null and b/tools/designer/designer/images/designer_undo.png differ diff --git a/tools/designer/designer/images/designer_up.png b/tools/designer/designer/images/designer_up.png new file mode 100644 index 0000000..e437312 Binary files /dev/null and b/tools/designer/designer/images/designer_up.png differ diff --git a/tools/designer/designer/images/designer_uparrow.png b/tools/designer/designer/images/designer_uparrow.png new file mode 100644 index 0000000..eefe4a0 Binary files /dev/null and b/tools/designer/designer/images/designer_uparrow.png differ diff --git a/tools/designer/designer/images/designer_vsplit.png b/tools/designer/designer/images/designer_vsplit.png new file mode 100644 index 0000000..b820c19 Binary files /dev/null and b/tools/designer/designer/images/designer_vsplit.png differ diff --git a/tools/designer/designer/images/designer_wait.png b/tools/designer/designer/images/designer_wait.png new file mode 100644 index 0000000..5d8cfed Binary files /dev/null and b/tools/designer/designer/images/designer_wait.png differ diff --git a/tools/designer/designer/images/designer_widgetstack.png b/tools/designer/designer/images/designer_widgetstack.png new file mode 100644 index 0000000..c326de8 Binary files /dev/null and b/tools/designer/designer/images/designer_widgetstack.png differ diff --git a/tools/designer/designer/images/designer_wizarddata.png b/tools/designer/designer/images/designer_wizarddata.png new file mode 100644 index 0000000..9493e3b Binary files /dev/null and b/tools/designer/designer/images/designer_wizarddata.png differ diff --git a/tools/designer/designer/images/designer_wizarddialog.png b/tools/designer/designer/images/designer_wizarddialog.png new file mode 100644 index 0000000..a22dc88 Binary files /dev/null and b/tools/designer/designer/images/designer_wizarddialog.png differ diff --git a/tools/designer/designer/images/designer_wordwrap.png b/tools/designer/designer/images/designer_wordwrap.png new file mode 100644 index 0000000..29513c3 Binary files /dev/null and b/tools/designer/designer/images/designer_wordwrap.png differ diff --git a/tools/designer/designer/layout.cpp b/tools/designer/designer/layout.cpp new file mode 100644 index 0000000..2701023 --- /dev/null +++ b/tools/designer/designer/layout.cpp @@ -0,0 +1,1024 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "formwindow.h" +#include "layout.h" +#include +#include "widgetfactory.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +bool operator<( const QGuardedPtr &p1, const QGuardedPtr &p2 ) +{ + return p1.operator->() < p2.operator->(); +} + +/*! + \class Layout layout.h + \brief Baseclass for layouting widgets in the Designer + + Classes derived from this abstract base class are used for layouting + operations in the Designer. + +*/ + +/*! \a p specifies the parent of the layoutBase \a lb. The parent + might be changed in setup(). If the layoutBase is a + container, the parent and the layoutBase are the same. Also they + always have to be a widget known to the designer (e.g. in the case + of the tabwidget parent and layoutBase are the tabwidget and not the + page which actually gets laid out. For actual usage the correct + widget is found later by Layout.) + */ + +Layout::Layout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup, bool splitter ) + : widgets( wl ), parent( p ), formWindow( fw ), isBreak( !doSetup ), useSplitter( splitter ) +{ + widgets.setAutoDelete( FALSE ); + layoutBase = lb; + if ( !doSetup && layoutBase ) + oldGeometry = layoutBase->geometry(); +} + +/*! The widget list we got in the constructor might contain too much + widgets (like widgets with different parents, already laid out + widgets, etc.). Here we set up the list and so the only the "best" + widgets get laid out. +*/ + +void Layout::setup() +{ + startPoint = QPoint( 32767, 32767 ); + QValueList lists; + QWidget *lastParent = 0; + QWidgetList *lastList = 0; + QWidget *w = 0; + + // Go through all widgets of the list we got. As we can only + // layout widgets which have the same parent, we first do some + // sorting which means create a list for each parent containing + // its child here. After that we keep working on the list of + // childs which has the most entries. + // Widgets which are already laid out are thrown away here too + for ( w = widgets.first(); w; w = widgets.next() ) { + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + continue; + if ( lastParent != w->parentWidget() ) { + lastList = 0; + lastParent = w->parentWidget(); + QValueList::Iterator it = lists.begin(); + for ( ; it != lists.end(); ++it ) { + if ( ( *it ).first()->parentWidget() == w->parentWidget() ) + lastList = &( *it ); + } + if ( !lastList ) { + QWidgetList l; + l.setAutoDelete( FALSE ); + lists.append( l ); + lastList = &lists.last(); + } + } + lastList->append( w ); + } + + // So, now find the list with the most entries + lastList = 0; + QValueList::Iterator it = lists.begin(); + for ( ; it != lists.end(); ++it ) { + if ( !lastList || ( *it ).count() > lastList->count() ) + lastList = &( *it ); + } + + // If we found no list (because no widget did fit at all) or the + // best list has only one entry and we do not layout a container, + // we leave here. + if ( !lastList || ( lastList->count() < 2 && + ( !layoutBase || + ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( layoutBase ) ) ) && + layoutBase != formWindow->mainContainer() ) ) + ) ) { + widgets.clear(); + startPoint = QPoint( 0, 0 ); + return; + } + + // Now we have a new and clean widget list, which makes sense + // to layout + widgets = *lastList; + // Also use the only correct parent later, so store it + parent = WidgetFactory::widgetOfContainer( widgets.first()->parentWidget() ); + // Now calculate the position where the layout-meta-widget should + // be placed and connect to widgetDestroyed() signals of the + // widgets to get informed if one gets deleted to be able to + // handle that and do not crash in this case + for ( w = widgets.first(); w; w = widgets.next() ) { + connect( w, SIGNAL( destroyed() ), + this, SLOT( widgetDestroyed() ) ); + startPoint = QPoint( QMIN( startPoint.x(), w->x() ), + QMIN( startPoint.y(), w->y() ) ); + geometries.insert( w, QRect( w->pos(), w->size() ) ); + // Change the Z-order, as saving/loading uses the Z-order for + // writing/creating widgets and this has to be the same as in + // the layout. Else saving + loading will give different results + w->raise(); + } +} + +void Layout::widgetDestroyed() +{ + if ( sender() && sender()->isWidgetType() ) + widgets.removeRef( (QWidget*)sender() ); +} + +bool Layout::prepareLayout( bool &needMove, bool &needReparent ) +{ + if ( !widgets.count() ) + return FALSE; + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) + w->raise(); + needMove = !layoutBase; + needReparent = needMove || ::qt_cast(layoutBase) || ::qt_cast(layoutBase); + if ( !layoutBase ) { + if ( !useSplitter ) + layoutBase = WidgetFactory::create( WidgetDatabase::idFromClassName( "QLayoutWidget" ), + WidgetFactory::containerOfWidget( parent ) ); + else + layoutBase = WidgetFactory::create( WidgetDatabase::idFromClassName( "QSplitter" ), + WidgetFactory::containerOfWidget( parent ) ); + } else { + WidgetFactory::deleteLayout( layoutBase ); + } + + return TRUE; +} + +void Layout::finishLayout( bool needMove, QLayout *layout ) +{ + if ( needMove ) + layoutBase->move( startPoint ); + QRect g( QRect( layoutBase->pos(), layoutBase->size() ) ); + if ( WidgetFactory::layoutType( layoutBase->parentWidget() ) == WidgetFactory::NoLayout && !isBreak ) + layoutBase->adjustSize(); + else if ( isBreak ) + layoutBase->setGeometry( oldGeometry ); + oldGeometry = g; + layoutBase->show(); + layout->activate(); + formWindow->insertWidget( layoutBase ); + formWindow->selectWidget( layoutBase ); + QString n = layoutBase->name(); + if ( n.find( "qt_dead_widget_" ) != -1 ) { + n.remove( 0, QString( "qt_dead_widget_" ).length() ); + layoutBase->setName( n ); + } +} + +void Layout::undoLayout() +{ + if ( !widgets.count() ) + return; + QMap, QRect>::Iterator it = geometries.begin(); + for ( ; it != geometries.end(); ++it ) { + if ( !it.key() ) + continue; + it.key()->reparent( WidgetFactory::containerOfWidget( parent ), 0, ( *it ).topLeft(), it.key()->isVisibleTo( formWindow ) ); + it.key()->resize( ( *it ).size() ); + } + formWindow->selectWidget( layoutBase, FALSE ); + WidgetFactory::deleteLayout( layoutBase ); + if ( parent != layoutBase && !::qt_cast(layoutBase) ) { + layoutBase->hide(); + QString n = layoutBase->name(); + n.prepend( "qt_dead_widget_" ); + layoutBase->setName( n ); + } else { + layoutBase->setGeometry( oldGeometry ); + } + if ( widgets.first() ) + formWindow->selectWidget( widgets.first() ); + else + formWindow->selectWidget( formWindow ); +} + +void Layout::breakLayout() +{ + QMap rects; + if ( !widgets.isEmpty() ) { + QWidget *w; + for ( w = widgets.first(); w; w = widgets.next() ) + rects.insert( w, w->geometry() ); + } + WidgetFactory::deleteLayout( layoutBase ); + bool needReparent = qstrcmp( layoutBase->className(), "QLayoutWidget" ) == 0 || + qstrcmp( layoutBase->className(), "QSplitter" ) == 0 || + ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( layoutBase ) ) ) && + layoutBase != formWindow->mainContainer() ); + bool needResize = qstrcmp( layoutBase->className(), "QSplitter" ) == 0; + bool add = geometries.isEmpty(); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( needReparent ) + w->reparent( layoutBase->parentWidget(), 0, + layoutBase->pos() + w->pos(), TRUE ); + if ( needResize ) { + QMap::Iterator it = rects.find( w ); + if ( it != rects.end() ) + w->setGeometry( QRect( layoutBase->pos() + (*it).topLeft(), (*it).size() ) ); + } + if ( add ) + geometries.insert( w, QRect( w->pos(), w->size() ) ); + } + if ( needReparent ) { + layoutBase->hide(); + parent = layoutBase->parentWidget(); + QString n = layoutBase->name(); + n.prepend( "qt_dead_widget_" ); + layoutBase->setName( n ); + } else { + parent = layoutBase; + } + if ( widgets.first() && widgets.first()->isVisibleTo( formWindow ) ) + formWindow->selectWidget( widgets.first() ); + else + formWindow->selectWidget( formWindow ); +} + +class HorizontalLayoutList : public QWidgetList +{ +public: + HorizontalLayoutList( const QWidgetList &l ) + : QWidgetList( l ) {} + + int compareItems( QPtrCollection::Item item1, QPtrCollection::Item item2 ) { + QWidget *w1 = (QWidget*)item1; + QWidget *w2 = (QWidget*)item2; + if ( w1->x() == w2->x() ) + return 0; + if ( w1->x() > w2->x() ) + return 1; + return -1; + } + +}; + +HorizontalLayout::HorizontalLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup, bool splitter ) + : Layout( wl, p, fw, lb, doSetup, splitter ) +{ + if ( doSetup ) + setup(); +} + +void HorizontalLayout::setup() +{ + HorizontalLayoutList l( widgets ); + l.sort(); + widgets = l; + Layout::setup(); +} + +void HorizontalLayout::doLayout() +{ + bool needMove, needReparent; + if ( !prepareLayout( needMove, needReparent ) ) + return; + + QHBoxLayout *layout = (QHBoxLayout*)WidgetFactory::createLayout( layoutBase, 0, WidgetFactory::HBox ); + + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( needReparent && w->parent() != layoutBase ) + w->reparent( layoutBase, 0, QPoint( 0, 0 ), FALSE ); + if ( !useSplitter ) { + if ( qstrcmp( w->className(), "Spacer" ) == 0 ) + layout->addWidget( w, 0, ( (Spacer*)w )->alignment() ); + else + layout->addWidget( w ); + if ( ::qt_cast(w) ) + ( (QLayoutWidget*)w )->updateSizePolicy(); + } + w->show(); + } + + if ( ::qt_cast(layoutBase) ) + ( (QSplitter*)layoutBase )->setOrientation( Qt::Horizontal ); + + finishLayout( needMove, layout ); +} + + + + +class VerticalLayoutList : public QWidgetList +{ +public: + VerticalLayoutList( const QWidgetList &l ) + : QWidgetList( l ) {} + + int compareItems( QPtrCollection::Item item1, QPtrCollection::Item item2 ) { + QWidget *w1 = (QWidget*)item1; + QWidget *w2 = (QWidget*)item2; + if ( w1->y() == w2->y() ) + return 0; + if ( w1->y() > w2->y() ) + return 1; + return -1; + } + +}; + +VerticalLayout::VerticalLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup, bool splitter ) + : Layout( wl, p, fw, lb, doSetup, splitter ) +{ + if ( doSetup ) + setup(); +} + +void VerticalLayout::setup() +{ + VerticalLayoutList l( widgets ); + l.sort(); + widgets = l; + Layout::setup(); +} + +void VerticalLayout::doLayout() +{ + bool needMove, needReparent; + if ( !prepareLayout( needMove, needReparent ) ) + return; + + QVBoxLayout *layout = (QVBoxLayout*)WidgetFactory::createLayout( layoutBase, 0, WidgetFactory::VBox ); + + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( needReparent && w->parent() != layoutBase ) + w->reparent( layoutBase, 0, QPoint( 0, 0 ), FALSE ); + if ( !useSplitter ) { + if ( qstrcmp( w->className(), "Spacer" ) == 0 ) + layout->addWidget( w, 0, ( (Spacer*)w )->alignment() ); + else + layout->addWidget( w ); + if ( ::qt_cast(w) ) + ( (QLayoutWidget*)w )->updateSizePolicy(); + } + w->show(); + } + + if ( ::qt_cast(layoutBase) ) + ( (QSplitter*)layoutBase )->setOrientation( Qt::Vertical ); + + finishLayout( needMove, layout ); +} + + + + + +class Grid +{ +public: + Grid( int rows, int cols ); + ~Grid(); + + QWidget* cell( int row, int col ) const { return cells[ row * ncols + col]; } + void setCell( int row, int col, QWidget* w ) { cells[ row*ncols + col] = w; } + void setCells( QRect c, QWidget* w ) { + for ( int rows = c.bottom()-c.top(); rows >= 0; rows--) + for ( int cols = c.right()-c.left(); cols >= 0; cols--) { + setCell(c.top()+rows, c.left()+cols, w); + } + } + int numRows() const { return nrows; } + int numCols() const { return ncols; } + + void simplify(); + bool locateWidget( QWidget* w, int& row, int& col, int& rowspan, int& colspan ); + +private: + void merge(); + int countRow( int r, int c ) const; + int countCol( int r, int c ) const; + void setRow( int r, int c, QWidget* w, int count ); + void setCol( int r, int c, QWidget* w, int count ); + bool isWidgetStartCol( int c ) const; + bool isWidgetEndCol( int c ) const; + bool isWidgetStartRow( int r ) const; + bool isWidgetEndRow( int r ) const; + bool isWidgetTopLeft( int r, int c ) const; + void extendLeft(); + void extendRight(); + void extendUp(); + void extendDown(); + QWidget** cells; + bool* cols; + bool* rows; + int nrows, ncols; + +}; + +Grid::Grid( int r, int c ) + : nrows( r ), ncols( c ) +{ + cells = new QWidget*[ r * c ]; + memset( cells, 0, sizeof( cells ) * r * c ); + rows = new bool[ r ]; + cols = new bool[ c ]; + +} + +Grid::~Grid() +{ + delete [] cells; + delete [] cols; + delete [] rows; +} + +int Grid::countRow( int r, int c ) const +{ + QWidget* w = cell( r, c ); + int i = c + 1; + while ( i < ncols && cell( r, i ) == w ) + i++; + return i - c; +} + +int Grid::countCol( int r, int c ) const +{ + QWidget* w = cell( r, c ); + int i = r + 1; + while ( i < nrows && cell( i, c ) == w ) + i++; + return i - r; +} + +void Grid::setCol( int r, int c, QWidget* w, int count ) +{ + for (int i = 0; i < count; i++ ) + setCell( r + i, c, w ); +} + +void Grid::setRow( int r, int c, QWidget* w, int count ) +{ + for (int i = 0; i < count; i++ ) + setCell( r, c + i, w ); +} + +bool Grid::isWidgetStartCol( int c ) const +{ + int r; + for ( r = 0; r < nrows; r++ ) { + if ( cell( r, c ) && ( (c==0) || (cell( r, c) != cell( r, c-1) )) ) { + return TRUE; + } + } + return FALSE; +} + +bool Grid::isWidgetEndCol( int c ) const +{ + int r; + for ( r = 0; r < nrows; r++ ) { + if ( cell( r, c ) && ((c == ncols-1) || (cell( r, c) != cell( r, c+1) )) ) + return TRUE; + } + return FALSE; +} + +bool Grid::isWidgetStartRow( int r ) const +{ + int c; + for ( c = 0; c < ncols; c++ ) { + if ( cell( r, c ) && ( (r==0) || (cell( r, c) != cell( r-1, c) )) ) + return TRUE; + } + return FALSE; +} + +bool Grid::isWidgetEndRow( int r ) const +{ + int c; + for ( c = 0; c < ncols; c++ ) { + if ( cell( r, c ) && ((r == nrows-1) || (cell( r, c) != cell( r+1, c) )) ) + return TRUE; + } + return FALSE; +} + + +bool Grid::isWidgetTopLeft( int r, int c ) const +{ + QWidget* w = cell( r, c ); + if ( !w ) + return FALSE; + return ( !r || cell( r-1, c) != w ) && (!c || cell( r, c-1) != w); +} + +void Grid::extendLeft() +{ + int r,c,i; + for ( c = 1; c < ncols; c++ ) { + for ( r = 0; r < nrows; r++ ) { + QWidget* w = cell( r, c ); + if ( !w ) + continue; + int cc = countCol( r, c); + int stretch = 0; + for ( i = c-1; i >= 0; i-- ) { + if ( cell( r, i ) ) + break; + if ( countCol( r, i ) < cc ) + break; + if ( isWidgetEndCol( i ) ) + break; + if ( isWidgetStartCol( i ) ) { + stretch = c - i; + break; + } + } + if ( stretch ) { + for ( i = 0; i < stretch; i++ ) + setCol( r, c-i-1, w, cc ); + } + } + } +} + + +void Grid::extendRight() +{ + int r,c,i; + for ( c = ncols - 2; c >= 0; c-- ) { + for ( r = 0; r < nrows; r++ ) { + QWidget* w = cell( r, c ); + if ( !w ) + continue; + int cc = countCol( r, c); + int stretch = 0; + for ( i = c+1; i < ncols; i++ ) { + if ( cell( r, i ) ) + break; + if ( countCol( r, i ) < cc ) + break; + if ( isWidgetStartCol( i ) ) + break; + if ( isWidgetEndCol( i ) ) { + stretch = i - c; + break; + } + } + if ( stretch ) { + for ( i = 0; i < stretch; i++ ) + setCol( r, c+i+1, w, cc ); + } + } + } + +} + +void Grid::extendUp() +{ + int r,c,i; + for ( r = 1; r < nrows; r++ ) { + for ( c = 0; c < ncols; c++ ) { + QWidget* w = cell( r, c ); + if ( !w ) + continue; + int cr = countRow( r, c); + int stretch = 0; + for ( i = r-1; i >= 0; i-- ) { + if ( cell( i, c ) ) + break; + if ( countRow( i, c ) < cr ) + break; + if ( isWidgetEndRow( i ) ) + break; + if ( isWidgetStartRow( i ) ) { + stretch = r - i; + break; + } + } + if ( stretch ) { + for ( i = 0; i < stretch; i++ ) + setRow( r-i-1, c, w, cr ); + } + } + } +} + +void Grid::extendDown() +{ + int r,c,i; + for ( r = nrows - 2; r >= 0; r-- ) { + for ( c = 0; c < ncols; c++ ) { + QWidget* w = cell( r, c ); + if ( !w ) + continue; + int cr = countRow( r, c); + int stretch = 0; + for ( i = r+1; i < nrows; i++ ) { + if ( cell( i, c ) ) + break; + if ( countRow( i, c ) < cr ) + break; + if ( isWidgetStartRow( i ) ) + break; + if ( isWidgetEndRow( i ) ) { + stretch = i - r; + break; + } + } + if ( stretch ) { + for ( i = 0; i < stretch; i++ ) + setRow( r+i+1, c, w, cr ); + } + } + } + +} + +void Grid::simplify() +{ + extendLeft(); + extendRight(); + extendUp(); + extendDown(); + merge(); +} + + +void Grid::merge() +{ + int r,c; + for ( c = 0; c < ncols; c++ ) + cols[c] = FALSE; + + for ( r = 0; r < nrows; r++ ) + rows[r] = FALSE; + + for ( c = 0; c < ncols; c++ ) { + for ( r = 0; r < nrows; r++ ) { + if ( isWidgetTopLeft( r, c ) ) { + rows[r] = TRUE; + cols[c] = TRUE; + } + } + } +} + +bool Grid::locateWidget( QWidget* w, int& row, int& col, int& rowspan, int & colspan ) +{ + int r,c, r2, c2; + for ( c = 0; c < ncols; c++ ) { + for ( r = 0; r < nrows; r++ ) { + if ( cell( r, c ) == w ) { + row = 0; + for ( r2 = 1; r2 <= r; r2++ ) { + if ( rows[ r2-1 ] ) + row++; + } + col = 0; + for ( c2 = 1; c2 <= c; c2++ ) { + if ( cols[ c2-1 ] ) + col++; + } + rowspan = 0; + for ( r2 = r ; r2 < nrows && cell( r2, c) == w; r2++ ) { + if ( rows[ r2 ] ) + rowspan++; + } + colspan = 0; + for ( c2 = c; c2 < ncols && cell( r, c2) == w; c2++ ) { + if ( cols[ c2] ) + colspan++; + } + return TRUE; + } + } + } + return FALSE; +} + + + + +GridLayout::GridLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, const QSize &res, bool doSetup ) + : Layout( wl, p, fw, lb, doSetup ), resolution( res ) +{ + grid = 0; + if ( doSetup ) + setup(); +} + +GridLayout::~GridLayout() +{ + delete grid; +} + +void GridLayout::doLayout() +{ + bool needMove, needReparent; + if ( !prepareLayout( needMove, needReparent ) ) + return; + + QDesignerGridLayout *layout = (QDesignerGridLayout*)WidgetFactory::createLayout( layoutBase, 0, WidgetFactory::Grid ); + + if ( !grid ) + buildGrid(); + + QWidget* w; + int r, c, rs, cs; + for ( w = widgets.first(); w; w = widgets.next() ) { + if ( grid->locateWidget( w, r, c, rs, cs) ) { + if ( needReparent && w->parent() != layoutBase ) + w->reparent( layoutBase, 0, QPoint( 0, 0 ), FALSE ); + if ( rs * cs == 1 ) { + layout->addWidget( w, r, c, ::qt_cast(w) ? ( (Spacer*)w )->alignment() : 0 ); + } else { + layout->addMultiCellWidget( w, r, r+rs-1, c, c+cs-1, ::qt_cast(w) ? ( (Spacer*)w )->alignment() : 0 ); + } + if ( ::qt_cast(w) ) + ( (QLayoutWidget*)w )->updateSizePolicy(); + w->show(); + } else { + qWarning("ooops, widget '%s' does not fit in layout", w->name() ); + } + } + finishLayout( needMove, layout ); +} + +void GridLayout::setup() +{ + Layout::setup(); + buildGrid(); +} + +void GridLayout::buildGrid() +{ + if ( !widgets.count() ) + return; + + // Pixel to cell conversion: + // By keeping a list of start'n'stop values (x & y) for each widget, + // it is possible to create a very small grid of cells to represent + // the widget layout. + // ----------------------------------------------------------------- + + // We need a list of both start and stop values for x- & y-axis + QValueVector x( widgets.count()*2 ); + QValueVector y( widgets.count()*2 ); + + // Using push_back would look nicer, but operator[] is much faster + int index = 0; + QWidget* w = 0; + for ( w = widgets.first(); w; w = widgets.next() ) { + QRect widgetPos = w->geometry(); + x[index] = widgetPos.left(); + x[index+1] = widgetPos.right(); + y[index] = widgetPos.top(); + y[index+1] = widgetPos.bottom(); + index += 2; + } + + qHeapSort(x); + qHeapSort(y); + + // Remove duplicate x enteries (Remove next, if equal to current) + if ( !x.empty() ) { + for (QValueVector::iterator current = x.begin() ; + (current != x.end()) && ((current+1) != x.end()) ; ) + if ( (*current == *(current+1)) ) + x.erase(current+1); + else + current++; + } + + // Remove duplicate y enteries (Remove next, if equal to current) + if ( !y.empty() ) { + for (QValueVector::iterator current = y.begin() ; + (current != y.end()) && ((current+1) != y.end()) ; ) + if ( (*current == *(current+1)) ) + y.erase(current+1); + else + current++; + } + + // Create the smallest grid possible to represent the current layout + // Since no widget will be placed in the last row and column, we'll + // skip them to increase speed even further + delete grid; + grid = new Grid( (int)(y.size()-1), (int)(x.size()-1) ); + + // Mark the cells in the grid that contains a widget + for ( w = widgets.first(); w; w = widgets.next() ) { + QRect c(0,0,0,0), widgetPos = w->geometry(); + // From left til right (not including) + for (uint cw=0; cwsetCells(c, w); // Mark cellblock + } + grid->simplify(); +} + + + + + + + +Spacer::Spacer( QWidget *parent, const char *name ) + : QWidget( parent, name, WMouseNoMask ), + orient( Vertical ), interactive(TRUE), sh( QSize(20,20) ) +{ + setSizeType( Expanding ); + setAutoMask( TRUE ); +} + +void Spacer::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + p.setPen( Qt::blue ); + + if ( orient == Horizontal ) { + const int dist = 3; + const int amplitude = QMIN( 3, height() / 3 ); + const int base = height() / 2; + int i = 0; + p.setPen( white ); + for ( i = 0; i < width() / 3 +2; ++i ) + p.drawLine( i * dist, base - amplitude, i * dist + dist / 2, base + amplitude ); + p.setPen( blue ); + for ( i = 0; i < width() / 3 +2; ++i ) + p.drawLine( i * dist + dist / 2, base + amplitude, i * dist + dist, base - amplitude ); + p.drawLine( 0, 0, 0, height() ); + p.drawLine( width() - 1, 0, width() - 1, height()); + } else { + const int dist = 3; + const int amplitude = QMIN( 3, width() / 3 ); + const int base = width() / 2; + int i = 0; + p.setPen( white ); + for ( i = 0; i < height() / 3 +2; ++i ) + p.drawLine( base - amplitude, i * dist, base + amplitude,i * dist + dist / 2 ); + p.setPen( blue ); + for ( i = 0; i < height() / 3 +2; ++i ) + p.drawLine( base + amplitude, i * dist + dist / 2, base - amplitude, i * dist + dist ); + p.drawLine( 0, 0, width(), 0 ); + p.drawLine( 0, height() - 1, width(), height() - 1 ); + } +} + +void Spacer::resizeEvent( QResizeEvent* e) +{ + QWidget::resizeEvent( e ); + if ( !parentWidget() || WidgetFactory::layoutType( parentWidget() ) == WidgetFactory::NoLayout ) + sh = size(); +} + +void Spacer::updateMask() +{ + QRegion r( rect() ); + if ( orient == Horizontal ) { + const int amplitude = QMIN( 3, height() / 3 ); + const int base = height() / 2; + r = r.subtract( QRect(1, 0, width() - 2, base - amplitude ) ); + r = r.subtract( QRect(1, base + amplitude, width() - 2, height() - base - amplitude ) ); + } else { + const int amplitude = QMIN( 3, width() / 3 ); + const int base = width() / 2; + r = r.subtract( QRect(0, 1, base - amplitude, height() - 2 ) ); + r = r.subtract( QRect( base + amplitude, 1, width() - base - amplitude, height() - 2 ) ); + } + setMask( r ); +} + +void Spacer::setSizeType( SizeType t ) +{ + QSizePolicy sizeP; + if ( orient == Vertical ) + sizeP = QSizePolicy( QSizePolicy::Minimum, (QSizePolicy::SizeType)t ); + else + sizeP = QSizePolicy( (QSizePolicy::SizeType)t, QSizePolicy::Minimum ); + setSizePolicy( sizeP ); +} + + +Spacer::SizeType Spacer::sizeType() const +{ + if ( orient == Vertical ) + return (SizeType)sizePolicy().verData(); + return (SizeType)sizePolicy().horData(); +} + +int Spacer::alignment() const +{ + if ( orient == Vertical ) + return AlignHCenter; + return AlignVCenter; +} + +QSize Spacer::minimumSize() const +{ + QSize s = QSize( 20,20 ); + if ( sizeType() == Expanding ) + if ( orient == Vertical ) + s.rheight() = 0; + else + s.rwidth() = 0; + return s; +} + +QSize Spacer::sizeHint() const +{ + return sh; +} + + +void Spacer::setSizeHint( const QSize &s ) +{ + sh = s; + if ( !parentWidget() || WidgetFactory::layoutType( parentWidget() ) == WidgetFactory::NoLayout ) + resize( sizeHint() ); + updateGeometry(); +} + +Qt::Orientation Spacer::orientation() const +{ + return orient; +} + +void Spacer::setOrientation( Qt::Orientation o ) +{ + if ( orient == o ) + return; + + SizeType st = sizeType(); + orient = o; + setSizeType( st ); + if ( interactive ) { + sh = QSize( sh.height(), sh.width() ); + if (!parentWidget() || WidgetFactory::layoutType( parentWidget() ) == WidgetFactory::NoLayout ) + resize( height(), width() ); + } + updateMask(); + update(); + updateGeometry(); +} + + +void QDesignerGridLayout::addWidget( QWidget *w, int row, int col, int align_ ) +{ + items.insert( w, Item(row, col, 1, 1) ); + QGridLayout::addWidget( w, row, col, align_ ); +} + +void QDesignerGridLayout::addMultiCellWidget( QWidget *w, int fromRow, int toRow, + int fromCol, int toCol, int align_ ) +{ + items.insert( w, Item(fromRow, fromCol, toRow - fromRow + 1, toCol - fromCol +1) ); + QGridLayout::addMultiCellWidget( w, fromRow, toRow, fromCol, toCol, align_ ); +} diff --git a/tools/designer/designer/layout.h b/tools/designer/designer/layout.h new file mode 100644 index 0000000..4e0aa0f --- /dev/null +++ b/tools/designer/designer/layout.h @@ -0,0 +1,195 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LAYOUT_H +#define LAYOUT_H + +#include +#include +#include +#include +#include +#include +#include + +class FormWindow; +class QPaintEvent; + +class Layout : public QObject +{ + Q_OBJECT + +public: + Layout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup = TRUE, bool splitter = FALSE ); + virtual ~Layout() {} + + virtual void doLayout() = 0; + virtual void undoLayout(); + virtual void breakLayout(); + virtual bool prepareLayout( bool &needMove, bool &needReparent ); + virtual void finishLayout( bool needMove, QLayout *layout ); + +protected: + QWidgetList widgets; + QWidget *parent; + QPoint startPoint; + QMap, QRect> geometries; + QWidget *layoutBase; + FormWindow *formWindow; + QRect oldGeometry; + bool isBreak; + bool useSplitter; + +protected: + virtual void setup(); + +protected slots: + void widgetDestroyed(); + +}; + +class HorizontalLayout : public Layout +{ +public: + HorizontalLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup = TRUE, bool splitter = FALSE ); + + void doLayout(); + +protected: + void setup(); + +}; + +class VerticalLayout : public Layout +{ +public: + VerticalLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, bool doSetup = TRUE, bool splitter = FALSE ); + + void doLayout(); + +protected: + void setup(); + +}; + +class Grid; + +class GridLayout : public Layout +{ +public: + GridLayout( const QWidgetList &wl, QWidget *p, FormWindow *fw, QWidget *lb, const QSize &res, bool doSetup = TRUE ); + ~GridLayout(); + + void doLayout(); + +protected: + void setup(); + +protected: + void buildGrid(); + QSize resolution; + Grid* grid; + +}; + +class Spacer : public QWidget +{ + Q_OBJECT + + Q_OVERRIDE( QCString name ) + Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation ) + Q_ENUMS( SizeType ) + Q_PROPERTY( SizeType sizeType READ sizeType WRITE setSizeType ) + Q_PROPERTY( QSize sizeHint READ sizeHint WRITE setSizeHint DESIGNABLE true STORED true ) + Q_OVERRIDE( QRect geometry DESIGNABLE false ) + +private: + enum { HSize = 6, HMask = 0x3f, VMask = HMask << HSize, + MayGrow = 1, ExpMask = 2, MayShrink = 4 }; + +public: + enum SizeType { Fixed = 0, + Minimum = MayGrow, + Maximum = MayShrink, + Preferred = MayGrow|MayShrink , + MinimumExpanding = Minimum|ExpMask, + Expanding = MinimumExpanding|MayShrink }; + + Spacer( QWidget *parent, const char *name ); + + QSize minimumSize() const; + QSize sizeHint() const; + void setSizeType( SizeType t ); + SizeType sizeType() const; + int alignment() const; + Orientation orientation() const; + void setOrientation( Orientation o ); + void setInteraciveMode( bool b ) { interactive = b; }; + void setSizeHint( const QSize &s ); + +protected: + void paintEvent( QPaintEvent *e ); + void resizeEvent( QResizeEvent* e ); + void updateMask(); + Qt::Orientation orient; + bool interactive; + QSize sh; +}; + +class QDesignerGridLayout : public QGridLayout +{ + Q_OBJECT +public: + QDesignerGridLayout( QWidget *parent ) : QGridLayout( parent ){}; + QDesignerGridLayout( QLayout *parentLayout ) : QGridLayout( parentLayout ){}; + + void addWidget( QWidget *, int row, int col, int align = 0 ); + void addMultiCellWidget( QWidget *, int fromRow, int toRow, + int fromCol, int toCol, int align = 0 ); + + struct Item + { + Item(): row(0), column(0),rowspan(1),colspan(1){} + Item( int r, int c, int rs, int cs): row(r), column(c), rowspan(rs), colspan(cs){} + int row; + int column; + int rowspan; + int colspan; + Q_DUMMY_COMPARISON_OPERATOR( Item ) + }; + + QMap items; +}; + + +#endif diff --git a/tools/designer/designer/listboxdnd.cpp b/tools/designer/designer/listboxdnd.cpp new file mode 100644 index 0000000..02e1147 --- /dev/null +++ b/tools/designer/designer/listboxdnd.cpp @@ -0,0 +1,312 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "listboxdnd.h" +#include +#include +#include +#include +#include + +// The Dragobject Declaration --------------------------------------- +class ListBoxItemDrag : public QStoredDrag +{ +public: + ListBoxItemDrag( ListBoxItemList & items, bool sendPtr = FALSE, QListBox * parent = 0, const char * name = 0 ); + ~ListBoxItemDrag() {}; + static bool canDecode( QDragMoveEvent * event ); + static bool decode( QDropEvent * event, QListBox * parent, QListBoxItem * insertPoint ); + enum ItemType { ListBoxText = 1, ListBoxPixmap = 2 }; +}; +// ------------------------------------------------------------------ + +ListBoxDnd::ListBoxDnd( QListBox * eventSource, const char * name ) + : ListDnd( eventSource, name ) { } + +void ListBoxDnd::confirmDrop( QListBoxItem * ) +{ + dropConfirmed = TRUE; +} + +bool ListBoxDnd::dropEvent( QDropEvent * event ) +{ + if ( dragInside ) { + + if ( dMode & NullDrop ) { // combined with Move, a NullDrop will delete an item + event->accept(); + emit dropped( 0 ); // a NullDrop + return TRUE; + } + + QPoint pos = event->pos(); + QListBoxItem * after = itemAt( pos ); + + if ( ListBoxItemDrag::decode( event, (QListBox *) src, after ) ) { + event->accept(); + QListBox * src = (QListBox *) this->src; + QListBoxItem * item = ( after ? after->next() : src->firstItem() ); + src->setCurrentItem( item ); + emit dropped( item ); // ###FIX: Supports only one item! + } + } + + line->hide(); + dragInside = FALSE; + + return TRUE; +} + +bool ListBoxDnd::mouseMoveEvent( QMouseEvent * event ) +{ + if ( event->state() & LeftButton ) { + if ( ( event->pos() - mousePressPos ).manhattanLength() > 3 ) { + + ListBoxItemList list; + buildList( list ); + ListBoxItemDrag * dragobject = new ListBoxItemDrag( list, (dMode & Internal), (QListBox *) src ); + + // Emit signal for all dragged items + QListBoxItem * i = list.first(); + while ( i ) { + emit dragged( i ); + i = list.next(); + } + + if ( dMode & Move ) { + removeList( list ); // "hide" items + } + + dragobject->dragCopy(); + + if ( dMode & Move ) { + if ( dropConfirmed ) { + // ###FIX: memleak ? in internal mode, only pointers are transfered... + //list.setAutoDelete( TRUE ); + list.clear(); + dropConfirmed = FALSE; + } + insertList( list ); // "show" items + } + } + } + return FALSE; +} + +int ListBoxDnd::buildList( ListBoxItemList & list ) +{ + QListBoxItem * i = ((QListBox *)src)->firstItem(); + while ( i ) { + if ( i->isSelected() ) { + ((QListBox *)src)->setSelected( i, FALSE ); + list.append( i ); + } + i = i->next(); + } + return list.count(); +} + +void ListBoxDnd::insertList( ListBoxItemList & list ) +{ + QListBoxItem * i = list.first(); + while ( i ) { + ((QListBox *)src)->insertItem( i, i->prev() ); + i = list.next(); + } +} + +void ListBoxDnd::removeList( ListBoxItemList & list ) +{ + QListBoxItem * i = list.first(); + while ( i ) { + ((QListBox *)src)->takeItem( i ); // remove item from QListBox + i = list.next(); + } +} + +void ListBoxDnd::updateLine( const QPoint & dragPos ) +{ + QListBox * src = (QListBox *) this->src; + QListBoxItem *item = itemAt( dragPos ); + + int ypos = item ? + ( src->itemRect( item ).bottom() - ( line->height() / 2 ) ) : + ( src->itemRect( ((QListBox *)src)->firstItem() ).top() ); + + line->resize( src->viewport()->width(), line->height() ); + line->move( 0, ypos ); +} + +QListBoxItem * ListBoxDnd::itemAt( QPoint pos ) +{ + QListBox * src = (QListBox *) this->src; + QListBoxItem * result = src->itemAt( pos ); + QListBoxItem * last = src->item( src->count() - 1 ); + int i = src->index( result ); + + if ( result && ( pos.y() < (src->itemRect(result).top() + src->itemHeight(i)/2) ) ) + result = result->prev(); + else if ( !result && pos.y() > src->itemRect( last ).bottom() ) + result = last; + + return result; +} + +bool ListBoxDnd::canDecode( QDragEnterEvent * event ) +{ + return ListBoxItemDrag::canDecode( event ); +} + + +// ------------------------------------------------------------------ +// The Dragobject Implementation ------------------------------------ +// ------------------------------------------------------------------ + +ListBoxItemDrag::ListBoxItemDrag( ListBoxItemList & items, bool sendPtr, QListBox * parent, const char * name ) + : QStoredDrag( "qt/listboxitem", parent, name ) +{ + // ### FIX! + QByteArray data( sizeof( Q_INT32 ) + sizeof( QListBoxItem ) * items.count() ); + QDataStream stream( data, IO_WriteOnly ); + + stream << items.count(); + stream << (Q_UINT8) sendPtr; // just transfer item pointer; omit data + + QListBoxItem * i = items.first(); + + if ( sendPtr ) { + + while ( i ) { + + stream << (Q_ULONG) i; //###FIX: demands sizeof(ulong) >= sizeof(void*) + i = items.next(); + + } + + } else { + + while ( i ) { + + Q_UINT8 b = 0; + + b = (Q_UINT8) ( i->text() != QString::null ); // does item have text ? + stream << b; + if ( b ) { + stream << i->text(); + } + + b = (Q_UINT8) ( !!i->pixmap() ); // does item have a pixmap ? + stream << b; + if ( b ) { + stream << ( *i->pixmap() ); + } + + stream << (Q_UINT8) i->isSelectable(); + + i = items.next(); + } + + } + + setEncodedData( data ); +} + +bool ListBoxItemDrag::canDecode( QDragMoveEvent * event ) +{ + return event->provides( "qt/listboxitem" ); +} + +bool ListBoxItemDrag::decode( QDropEvent * event, QListBox * parent, QListBoxItem * after ) +{ + QByteArray data = event->encodedData( "qt/listboxitem" ); + + if ( data.size() ) { + event->accept(); + QDataStream stream( data, IO_ReadOnly ); + + int count = 0; + stream >> count; + + Q_UINT8 recievePtr = 0; // data contains just item pointers; no data + stream >> recievePtr; + + QListBoxItem * item = 0; + + if ( recievePtr ) { + + for( int i = 0; i < count; i++ ) { + + Q_ULONG p = 0; //###FIX: demands sizeof(ulong) >= sizeof(void*) + stream >> p; + item = (QListBoxItem *) p; + + parent->insertItem( item, after ); + + } + + } else { + + for ( int i = 0; i < count; i++ ) { + + Q_UINT8 hasText = 0; + QString text; + stream >> hasText; + if ( hasText ) { + stream >> text; + } + + Q_UINT8 hasPixmap = 0; + QPixmap pixmap; + stream >> hasPixmap; + if ( hasPixmap ) { + stream >> pixmap; + } + + Q_UINT8 isSelectable = 0; + stream >> isSelectable; + + if ( hasPixmap ) { + item = new QListBoxPixmap( parent, pixmap, text, after ); + } else { + item = new QListBoxText( parent, text, after ); + } + + item->setSelectable( isSelectable ); + + } + + } + + return TRUE; + } + return FALSE; +} diff --git a/tools/designer/designer/listboxdnd.h b/tools/designer/designer/listboxdnd.h new file mode 100644 index 0000000..23e28e7 --- /dev/null +++ b/tools/designer/designer/listboxdnd.h @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LISTBOXDND_H +#define LISTBOXDND_H + +#include +#include +#include "listdnd.h" + +typedef QPtrList ListBoxItemList; + +class ListBoxDnd : public ListDnd +{ + Q_OBJECT +public: + // dragModes are enumerated in ListDnd + ListBoxDnd( QListBox * eventSource, const char * name = 0 ); + +signals: + void dropped( QListBoxItem * ); + void dragged( QListBoxItem * ); + +public slots: + void confirmDrop( QListBoxItem * ); + +protected: + virtual bool dropEvent( QDropEvent * event ); + virtual bool mouseMoveEvent( QMouseEvent * event ); + virtual void updateLine( const QPoint & pos ); + virtual bool canDecode( QDragEnterEvent * event ); + +private: + QListBoxItem * itemAt( QPoint pos ); + int buildList( ListBoxItemList & list ); + void insertList( ListBoxItemList & list ); + void removeList( ListBoxItemList & list ); +}; + +#endif //LISTBOXDND_H diff --git a/tools/designer/designer/listboxeditor.ui b/tools/designer/designer/listboxeditor.ui new file mode 100644 index 0000000..346e4a0 --- /dev/null +++ b/tools/designer/designer/listboxeditor.ui @@ -0,0 +1,461 @@ + +ListBoxEditorBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + ListBoxEditorBase + + + + 0 + 0 + 482 + 229 + + + + Edit Listbox + + + true + + + <b>Edit Listbox</b><p>Add, edit or delete items in the listbox.</p><p>Click the <b>New Item</b>-button to create a new listbox entry, then enter text and choose a pixmap.</p><p>Select an item from the list and click the <b>Delete Item</b>-button to remove the item from the list.</p> + + + + unnamed + + + 11 + + + 6 + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + helpButton + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonApply + + + &Apply + + + true + + + Apply all changes. + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + preview + + + Item list + + + The list of items. + + + + + GroupBox1 + + + &Item Properties + + + + unnamed + + + 11 + + + 6 + + + + Label2 + + + &Pixmap: + + + itemChoosePixmap + + + + + itemPixmap + + + Label4 + + + + + itemDeletePixmap + + + + 30 + 22 + + + + + + + designer_s_editcut.png + + + Delete Pixmap + + + Delete the selected item's pixmap. + + + + + itemChoosePixmap + + + + 30 + 22 + + + + ... + + + Select a Pixmap + + + Choose a pixmap file for the selected item. + + + + + Label1 + + + &Text: + + + itemText + + + + + itemText + + + + 0 + 0 + + + + Change text + + + Change the selected item's text. + + + + + + + itemNew + + + &New Item + + + Add an item + + + <b>Add a new item.</b><p>New items are appended to the list.</p> + + + + + itemDelete + + + &Delete Item + + + Delete Item + + + Delete the selected item + + + + + Vertical Spacing1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + itemUp + + + + + + designer_s_up.png + + + Move up + + + Moves the selected item up. + + + + + itemDown + + + + + + designer_s_down.png + + + Move down + + + Move the selected item down. + + + + + + + itemNew + clicked() + ListBoxEditorBase + insertNewItem() + + + itemDelete + clicked() + ListBoxEditorBase + deleteCurrentItem() + + + itemText + textChanged( const QString & ) + ListBoxEditorBase + currentTextChanged(const QString&) + + + buttonOk + clicked() + ListBoxEditorBase + okClicked() + + + buttonApply + clicked() + ListBoxEditorBase + applyClicked() + + + buttonCancel + clicked() + ListBoxEditorBase + cancelClicked() + + + itemChoosePixmap + clicked() + ListBoxEditorBase + choosePixmap() + + + itemDeletePixmap + clicked() + ListBoxEditorBase + deletePixmap() + + + itemUp + clicked() + ListBoxEditorBase + moveItemUp() + + + itemDown + clicked() + ListBoxEditorBase + moveItemDown() + + + preview + selectionChanged(QListBoxItem*) + ListBoxEditorBase + currentItemChanged(QListBoxItem*) + + + preview + currentChanged( QListBoxItem * ) + ListBoxEditorBase + currentItemChanged(QListBoxItem*) + + + + buttonOk + buttonCancel + preview + itemNew + itemDelete + itemUp + itemDown + itemText + itemDeletePixmap + itemChoosePixmap + helpButton + buttonApply + + + init() + destroy() + insertNewItem() + deleteCurrentItem() + currentItemChanged( QListBoxItem * ) + currentTextChanged( const QString & ) + okClicked() + cancelClicked() + applyClicked() + choosePixmap() + deletePixmap() + moveItemUp() + moveItemDown() + + + + diff --git a/tools/designer/designer/listboxeditorimpl.cpp b/tools/designer/designer/listboxeditorimpl.cpp new file mode 100644 index 0000000..511fdab --- /dev/null +++ b/tools/designer/designer/listboxeditorimpl.cpp @@ -0,0 +1,250 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "listboxeditorimpl.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "pixmapchooser.h" +#include "command.h" +#include "listboxdnd.h" +#include "listboxrename.h" + +#include +#include +#include +#include +#include + +ListBoxEditor::ListBoxEditor( QWidget *parent, QWidget *editWidget, FormWindow *fw ) + : ListBoxEditorBase( parent, 0, TRUE ), formwindow( fw ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + listbox = (QListBox*)editWidget; + + itemText->setText( "" ); + itemText->setEnabled( FALSE ); + itemPixmap->setText( "" ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + + QListBoxItem *i = 0; + for ( i = listbox->firstItem(); i; i = i->next() ) { + if ( i->pixmap() ) + (void)new QListBoxPixmap( preview, *i->pixmap(), i->text() ); + else + (void)new QListBoxText( preview, i->text() ); + } + + if ( preview->firstItem() ) + preview->setCurrentItem( preview->firstItem() ); + + ListBoxDnd *editorDnd = new ListBoxDnd( preview ); + editorDnd->setDragMode( ListBoxDnd::Internal | ListBoxDnd::Move ); + QObject::connect( editorDnd, SIGNAL( dropped( QListBoxItem * ) ), + editorDnd, SLOT( confirmDrop( QListBoxItem * ) ) ); + + ListBoxRename *editorRename = new ListBoxRename( preview ); + + QObjectList *l = parent->queryList( "QLineEdit", "itemText" ); + QObjectListIt it( *l ); + QObject *obj; + while ( (obj = it.current()) != 0 ) { + ++it; + QObject::connect( editorRename, + SIGNAL( itemTextChanged( const QString & ) ), + obj, + SLOT( setText( const QString & ) ) ); + } + delete l; + +} + +void ListBoxEditor::insertNewItem() +{ + QListBoxItem *i = new QListBoxText( preview, tr("New Item") ); + preview->setCurrentItem( i ); + preview->setSelected( i, TRUE ); + itemText->setFocus(); + itemText->selectAll(); +} + +void ListBoxEditor::deleteCurrentItem() +{ + delete preview->item( preview->currentItem() ); + if ( preview->currentItem() != -1 ) + preview->setSelected( preview->currentItem(), TRUE ); +} + +void ListBoxEditor::currentItemChanged( QListBoxItem *i ) +{ + itemText->blockSignals( TRUE ); + itemText->setText( "" ); + itemPixmap->setText( "" ); + itemText->blockSignals( FALSE ); + + if ( !i ) { + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + return; + } + + itemText->blockSignals( TRUE ); + itemText->setEnabled( TRUE ); + itemChoosePixmap->setEnabled( TRUE ); + itemDeletePixmap->setEnabled( i->pixmap() && !i->pixmap()->isNull() ); + + itemText->setText( i->text() ); + if ( i->pixmap() ) + itemPixmap->setPixmap( *i->pixmap() ); + itemText->blockSignals( FALSE ); +} + +void ListBoxEditor::currentTextChanged( const QString &txt ) +{ + if ( preview->currentItem() == -1 ) + return; + + preview->blockSignals( TRUE ); + if ( preview->item( preview->currentItem() )->pixmap() ) + preview->changeItem( *preview->item( preview->currentItem() )->pixmap(), txt, preview->currentItem() ); + else + preview->changeItem( txt, preview->currentItem() ); + preview->blockSignals( FALSE ); +} + +void ListBoxEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void ListBoxEditor::cancelClicked() +{ + reject(); +} + +void ListBoxEditor::applyClicked() +{ + QListBoxItem *i = 0; + QValueList items; + for ( i = preview->firstItem(); i; i = i->next() ) { + PopulateListBoxCommand::Item item; + if ( i->pixmap() ) + item.pix = *i->pixmap(); + item.text = i->text(); + items.append( item ); + } + + PopulateListBoxCommand *cmd = new PopulateListBoxCommand( tr( "Edit the Items of '%1'" ).arg( listbox->name() ), + formwindow, listbox, items ); + cmd->execute(); + formwindow->commandHistory()->addCommand( cmd ); +} + +void ListBoxEditor::choosePixmap() +{ + if ( preview->currentItem() == -1 ) + return; + + QPixmap pix; + if ( preview->item( preview->currentItem() )->pixmap() ) + pix = qChoosePixmap( this, formwindow, *preview->item( preview->currentItem() )->pixmap() ); + else + pix = qChoosePixmap( this, formwindow, QPixmap() ); + + if ( pix.isNull() ) + return; + + QString txt = preview->item( preview->currentItem() )->text(); + preview->changeItem( pix, txt, preview->currentItem() ); + itemDeletePixmap->setEnabled( TRUE ); +} + +void ListBoxEditor::moveItemUp() +{ + if ( preview->currentItem() < 1 ) + return; + + QListBoxItem *i = preview->item( preview->currentItem() ); + bool hasPix = (i->pixmap() != 0); + QPixmap pix; + if ( hasPix ) + pix = *i->pixmap(); + QString txt = i->text(); + + QListBoxItem *p = i->prev(); + if ( p->pixmap() ) + preview->changeItem( *p->pixmap(), p->text(), preview->currentItem() ); + else + preview->changeItem( p->text(), preview->currentItem() ); + + if ( hasPix ) + preview->changeItem( pix, txt, preview->currentItem() - 1 ); + else + preview->changeItem( txt, preview->currentItem() - 1 ); +} + +void ListBoxEditor::moveItemDown() +{ + if ( preview->currentItem() == -1 || preview->currentItem() > (int)preview->count() - 2 ) + return; + + QListBoxItem *i = preview->item( preview->currentItem() ); + bool hasPix = (i->pixmap() != 0); + QPixmap pix; + if ( hasPix ) + pix = *i->pixmap(); + QString txt = i->text(); + + QListBoxItem *n = i->next(); + if ( n->pixmap() ) + preview->changeItem( *n->pixmap(), n->text(), preview->currentItem() ); + else + preview->changeItem( n->text(), preview->currentItem() ); + + if ( hasPix ) + preview->changeItem( pix, txt, preview->currentItem() + 1 ); + else + preview->changeItem( txt, preview->currentItem() + 1 ); +} + +void ListBoxEditor::deletePixmap() +{ + if ( preview->currentItem() == -1 ) + return; + + QListBoxItem *i = preview->item( preview->currentItem() ); + preview->changeItem( i->text(), preview->currentItem() ); + itemDeletePixmap->setEnabled( FALSE ); +} diff --git a/tools/designer/designer/listboxeditorimpl.h b/tools/designer/designer/listboxeditorimpl.h new file mode 100644 index 0000000..04f9b33 --- /dev/null +++ b/tools/designer/designer/listboxeditorimpl.h @@ -0,0 +1,68 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LISTBOXEDITORIMPL_H +#define LISTBOXEDITORIMPL_H + +class QListBox; +class FormWindow; + +#include "listboxeditor.h" + +class ListBoxEditor : public ListBoxEditorBase +{ + Q_OBJECT + +public: + ListBoxEditor( QWidget *parent, QWidget *editWidget, FormWindow *fw ); + +protected slots: + void insertNewItem(); + void deleteCurrentItem(); + void currentItemChanged( QListBoxItem * ); + void currentTextChanged( const QString & ); + void okClicked(); + void cancelClicked(); + void applyClicked(); + void choosePixmap(); + void moveItemUp(); + void moveItemDown(); + void deletePixmap(); + +private: + QListBox *listbox; + FormWindow *formwindow; + +}; + +#endif diff --git a/tools/designer/designer/listboxrename.cpp b/tools/designer/designer/listboxrename.cpp new file mode 100644 index 0000000..983c5db --- /dev/null +++ b/tools/designer/designer/listboxrename.cpp @@ -0,0 +1,164 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include "listboxrename.h" + +class EditableListBoxItem : public QListBoxItem +{ +public: + void setText( const QString & text ) + { + QListBoxItem::setText( text ); + } +}; + +ListBoxRename::ListBoxRename( QListBox * eventSource, const char * name ) + : QObject( eventSource, name ), + clickedItem( 0 ), activity( FALSE ) +{ + src = eventSource; + src->installEventFilter( this ); + ed = new QLineEdit( src->viewport() ); + ed->hide(); + ed->setFrame( FALSE ); + + QObject::connect( ed, SIGNAL( returnPressed() ), + this, SLOT( renameClickedItem() ) ); +} + +bool ListBoxRename::eventFilter( QObject *, QEvent * event ) +{ + switch ( event->type() ) { + + case QEvent::MouseButtonPress: + { + QPoint pos = ((QMouseEvent *) event)->pos(); + + if ( clickedItem && + clickedItem->isSelected() && + (clickedItem == src->itemAt( pos )) ) { + QTimer::singleShot( 500, this, SLOT( showLineEdit() ) ); + activity = FALSE; // no drags or clicks for 500 ms before we start the renaming + } else { // new item clicked + activity = TRUE; + clickedItem = src->itemAt( pos ); + ed->hide(); + } + } + break; + + case QEvent::MouseMove: + + if ( ((QMouseEvent *) event)->state() & Qt::LeftButton ) { + activity = TRUE; // drag + } + break; + + case QEvent::KeyPress: + + switch ( ((QKeyEvent *) event)->key() ) { + + case Qt::Key_F2: + + activity = FALSE; + clickedItem = src->item( src->currentItem() ); + showLineEdit(); + break; + + case Qt::Key_Escape: + if ( !ed->isHidden() ) { + hideLineEdit(); // abort rename + return TRUE; + } + break; + + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + + if ( !ed->isHidden() ) + return TRUE; // Filter out the keystrokes + break; + + } + break; + + case QEvent::Resize: + + if ( clickedItem && ed && !ed->isHidden() ) { + QRect rect = src->itemRect( clickedItem ); + ed->resize( rect.right() - rect.left() - 1, + rect.bottom() - rect.top() - 1 ); + } + break; + + default: + break; + } + + return FALSE; +} + +void ListBoxRename::showLineEdit() +{ + if ( !clickedItem || activity ) + return; + QRect rect = src->itemRect( clickedItem ); + ed->resize( rect.right() - rect.left() - 1, + rect.bottom() - rect.top() - 1 ); + ed->move( rect.left() + 1, rect.top() + 1 ); + ed->setText( clickedItem->text() ); + ed->selectAll(); + ed->show(); + ed->setFocus(); +} + +void ListBoxRename::hideLineEdit() +{ + ed->hide(); + clickedItem = 0; + src->setFocus(); +} + +void ListBoxRename::renameClickedItem() +{ + if ( clickedItem && ed ) { + ( (EditableListBoxItem *) clickedItem )->setText( ed->text() ); + emit itemTextChanged( ed->text() ); + } + hideLineEdit(); +} diff --git a/tools/designer/designer/listboxrename.h b/tools/designer/designer/listboxrename.h new file mode 100644 index 0000000..d6d9bc6 --- /dev/null +++ b/tools/designer/designer/listboxrename.h @@ -0,0 +1,64 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LISTBOXRENAME_H +#define LISTBOXRENAME_H + +#include +#include + +class QLineEdit; + +class ListBoxRename : public QObject +{ + Q_OBJECT +public: + ListBoxRename( QListBox * eventSource, const char * name = 0 ); + bool eventFilter( QObject *, QEvent * event ); + +signals: + void itemTextChanged( const QString & ); + +public slots: + void showLineEdit(); + void hideLineEdit(); + void renameClickedItem(); + +private: + QListBoxItem * clickedItem; + QListBox * src; + QLineEdit * ed; + bool activity; +}; + +#endif //LISTBOXRENAME_H diff --git a/tools/designer/designer/listdnd.cpp b/tools/designer/designer/listdnd.cpp new file mode 100644 index 0000000..27adccd --- /dev/null +++ b/tools/designer/designer/listdnd.cpp @@ -0,0 +1,149 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "listdnd.h" +#include +#include + +ListDnd::ListDnd( QScrollView * eventSource, const char * name ) + : QObject( eventSource, name ), + dragInside( FALSE ), dragDelete( TRUE ), dropConfirmed( FALSE ), dMode( Both ) +{ + src = eventSource; + src->setAcceptDrops( TRUE ); + src->installEventFilter( this ); + src->viewport()->installEventFilter( this ); + + line = new QWidget( src->viewport(), 0, Qt::WStyle_NoBorder | WStyle_StaysOnTop ); + line->setBackgroundColor( Qt::black ); + line->resize( src->viewport()->width(), 2 ); + line->hide(); +} + +void ListDnd::setDragMode( int mode ) +{ + dMode = mode; +} + +int ListDnd::dragMode() const +{ + return dMode; +} + +bool ListDnd::eventFilter( QObject *, QEvent * event ) +{ + switch ( event->type() ) { + case QEvent::DragEnter: + return dragEnterEvent( (QDragEnterEvent *) event ); + case QEvent::DragLeave: + return dragLeaveEvent( (QDragLeaveEvent *) event ); + case QEvent::DragMove: + return dragMoveEvent( (QDragMoveEvent *) event ); + case QEvent::Drop: + return dropEvent( (QDropEvent *) event ); + case QEvent::MouseButtonPress: + return mousePressEvent( (QMouseEvent *) event ); + case QEvent::MouseMove: + return mouseMoveEvent( (QMouseEvent *) event ); + default: + break; + } + return FALSE; +} + + +bool ListDnd::dragEnterEvent( QDragEnterEvent * event ) +{ + if ( dMode == None ) { + return TRUE; + } + + bool ok = ( ( ( dMode & Both ) == Both ) || + ( ( dMode & Internal ) && ( event->source() == src ) ) || + ( ( dMode & External ) && ( event->source() != src ) ) ); + + if ( ok && canDecode( event ) ) { + event->accept(); + dragInside = TRUE; + if ( !( dMode & NullDrop ) ) { + updateLine( event->pos() ); + line->show(); + } + } + return TRUE; +} + +bool ListDnd::dragLeaveEvent( QDragLeaveEvent * ) +{ + dragInside = FALSE; + line->hide(); + return TRUE; +} + +bool ListDnd::dragMoveEvent( QDragMoveEvent * event ) +{ + if ( dragInside && dMode && !( dMode & NullDrop ) ) { + updateLine( event->pos() ); + } + return TRUE; +} + +bool ListDnd::dropEvent( QDropEvent * ) +{ + // do nothing + return FALSE; +} + +bool ListDnd::mousePressEvent( QMouseEvent * event ) +{ + if ( event->button() == LeftButton ) + mousePressPos = event->pos(); + return FALSE; +} + +bool ListDnd::mouseMoveEvent( QMouseEvent * ) +{ + // do nothing + return FALSE; +} + +void ListDnd::updateLine( const QPoint & ) +{ + // do nothing +} + +bool ListDnd::canDecode( QDragEnterEvent * ) +{ + // do nothing + return FALSE; +} diff --git a/tools/designer/designer/listdnd.h b/tools/designer/designer/listdnd.h new file mode 100644 index 0000000..2802642 --- /dev/null +++ b/tools/designer/designer/listdnd.h @@ -0,0 +1,70 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LISTDND_H +#define LISTDND_H + +#include +#include + +class ListDnd : public QObject +{ + Q_OBJECT +public: + enum DragMode { None = 0, External = 1, Internal = 2, Both = 3, Move = 4, NullDrop = 8 }; + ListDnd( QScrollView * eventSource, const char * name = 0 ); + void setDragMode( int mode ); + int dragMode() const; + bool eventFilter( QObject *, QEvent * event ); + +protected: + virtual bool dragEnterEvent( QDragEnterEvent * event ); + virtual bool dragLeaveEvent( QDragLeaveEvent * ); + virtual bool dragMoveEvent( QDragMoveEvent * event ); + virtual bool dropEvent( QDropEvent * event ); + virtual bool mousePressEvent( QMouseEvent * event ); + virtual bool mouseMoveEvent( QMouseEvent * event ); + virtual void updateLine( const QPoint & dragPos ); + virtual bool canDecode( QDragEnterEvent * event ); + + QScrollView * src; + QWidget * line; + QPoint mousePressPos; + QPoint dragPos; + bool dragInside; + bool dragDelete; + bool dropConfirmed; + int dMode; +}; + +#endif // LISTDND_H diff --git a/tools/designer/designer/listeditor.ui b/tools/designer/designer/listeditor.ui new file mode 100644 index 0000000..58ed838 --- /dev/null +++ b/tools/designer/designer/listeditor.ui @@ -0,0 +1,182 @@ + +ListEditor +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + ListEditor + + + + 0 + 0 + 331 + 301 + + + + Edit... + + + + unnamed + + + 11 + + + 6 + + + + + Column 1 + + + true + + + true + + + + listview + + + Extended + + + AllColumns + + + + + PushButton1 + + + &Add + + + + + PushButton2 + + + &Remove + + + + + PushButton3 + + + Re&name + + + + + PushButton4 + + + &Close + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + PushButton1 + clicked() + ListEditor + addItem() + + + PushButton2 + clicked() + ListEditor + removeItems() + + + PushButton4 + clicked() + ListEditor + accept() + + + listview + itemRenamed(QListViewItem*,int) + ListEditor + renamed(QListViewItem*) + + + PushButton3 + clicked() + ListEditor + renameItem() + + + + listeditor.ui.h + + + class QStringList; + + + init() + setList( const QStringList & l ) + addItem() + renamed( QListViewItem * i ) + removeItems() + items() + renameItem() + + + + diff --git a/tools/designer/designer/listeditor.ui.h b/tools/designer/designer/listeditor.ui.h new file mode 100644 index 0000000..bba0610 --- /dev/null +++ b/tools/designer/designer/listeditor.ui.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +#include +#include + +void ListEditor::init() +{ + listview->header()->hide(); + listview->setSorting( -1 ); + listview->setDefaultRenameAction( QListView::Accept ); +} + +void ListEditor::setList( const QStringList &l ) +{ + QListViewItem *i = 0; + for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { + i = new QListViewItem( listview, i ); + i->setText( 0, *it ); + i->setRenameEnabled( 0, TRUE ); + } +} + +void ListEditor::addItem() +{ + QListViewItem *i = new QListViewItem( listview, listview->lastItem() ); + i->setRenameEnabled( 0, TRUE ); + qApp->processEvents(); + i->startRename( 0 ); +} + +void ListEditor::renamed( QListViewItem *i ) +{ + if ( i && i->text( 0 ).isEmpty() ) + i->startRename( 0 ); +} + +void ListEditor::removeItems() +{ + QListViewItemIterator it( listview ); + QListViewItem *i = 0; + while ( ( i = it.current() ) ) { + ++it; + if ( i->isSelected() ) + delete i; + } +} + +QStringList ListEditor::items() +{ + QStringList l; + QListViewItemIterator it( listview ); + QListViewItem *i = 0; + while ( ( i = it.current() ) ) { + ++it; + if ( !i->text( 0 ).isEmpty() ) + l << i->text( 0 ); + } + return l; +} + +void ListEditor::renameItem() +{ + QListViewItem *i = listview->currentItem(); + if ( i ) + i->startRename( 0 ); +} diff --git a/tools/designer/designer/listviewdnd.cpp b/tools/designer/designer/listviewdnd.cpp new file mode 100644 index 0000000..ce0afeb --- /dev/null +++ b/tools/designer/designer/listviewdnd.cpp @@ -0,0 +1,439 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "listviewdnd.h" +#include +#include +#include +#include +#include + +// The Dragobject Declaration --------------------------------------- +class ListViewItemDrag : public QStoredDrag +{ +public: + enum DropRelation { Sibling, Child }; + ListViewItemDrag( ListViewItemList & items, QWidget * parent = 0, const char * name = 0 ); + ~ListViewItemDrag() {}; + static bool canDecode( QDragMoveEvent * event ); + static bool decode( QDropEvent * event, QListView * parent, QListViewItem * insertPoint, DropRelation dr ); +}; +// ------------------------------------------------------------------ + +ListViewDnd::ListViewDnd( QListView * eventSource, const char * name ) + : ListDnd( eventSource, name ) { } + +void ListViewDnd::confirmDrop( QListViewItem * ) +{ + dropConfirmed = TRUE; +} + +bool ListViewDnd::dropEvent( QDropEvent * event ) +{ + if ( dragInside ) { + + if ( dMode & NullDrop ) { // combined with Move, a NullDrop will delete an item + event->accept(); + emit dropped( 0 ); // a NullDrop + return TRUE; + } + + QPoint pos = event->pos(); + + ListViewItemDrag::DropRelation dr = ListViewItemDrag::Sibling; + QListViewItem *item = itemAt( pos ); + int dpos = dropDepth( item, pos ); + + if ( item ) { + if ( dpos > item->depth() && !(dMode & Flat) ) { + // Child node + dr = ListViewItemDrag::Child; + } else if ( dpos < item->depth() ) { + // Parent(s) Sibling + while ( item && (item->depth() > dpos) ) + item = item->parent(); + } + } + + if ( ListViewItemDrag::decode( event, (QListView *) src, item, dr ) ) { + event->accept(); + emit dropped( 0 ); // Use ID instead of item? + } + } + + line->hide(); + dragInside = FALSE; + + return TRUE; +} + +bool ListViewDnd::mouseMoveEvent( QMouseEvent * event ) +{ + if ( event->state() & LeftButton ) { + if ( ( event->pos() - mousePressPos ).manhattanLength() > 3 ) { + ListViewItemList list; + + if ( dMode & Flat ) + buildFlatList( list ); + else + buildTreeList( list ); + + ListViewItemDrag * dragobject = new ListViewItemDrag( list, (QListView *) src ); + + if ( dMode & Move ) { + disabledItems = list; + setVisibleItems( FALSE ); + } + + dragobject->dragCopy(); + + if ( dMode & Move ) { + // Did the target accept the drop? + if ( dropConfirmed ) { + // Shouldn't autoDelete handle this? + for( list.first(); list.current(); list.next() ) + delete list.current(); + dropConfirmed = FALSE; + } else { + // Reenable disabled items since + // drag'n'drop was aborted + setVisibleItems( TRUE ); + } + disabledItems.clear(); + } + } + } + return FALSE; +} + +int ListViewDnd::buildFlatList( ListViewItemList & list ) +{ + bool addKids = FALSE; + QListViewItem *nextSibling = 0; + QListViewItem *nextParent = 0; + QListViewItemIterator it = ((QListView *)src)->firstChild(); + for ( ; *it; it++ ) { + // Hit the nextSibling, turn of child processing + if ( (*it) == nextSibling ) + addKids = FALSE; + + if ( (*it)->isSelected() ) { + if ( (*it)->childCount() == 0 ) { + // Selected, no children + list.append( *it ); + } else if ( !addKids ) { + // Children processing not set, so set it + // Also find the item were we shall quit + // processing children...if any such item + addKids = TRUE; + nextSibling = (*it)->nextSibling(); + nextParent = (*it)->parent(); + while ( nextParent && !nextSibling ) { + nextSibling = nextParent->nextSibling(); + nextParent = nextParent->parent(); + } + } + } else if ( ((*it)->childCount() == 0) && addKids ) { + // Leaf node, and we _do_ process children + list.append( *it ); + } + } + return list.count(); +} + +int ListViewDnd::buildTreeList( ListViewItemList & list ) +{ + QListViewItemIterator it = ((QListView *)src)->firstChild(); + for ( ; *it; it++ ) { + if ( (*it)->isSelected() ) + list.append( *it ); + } + return list.count(); +} + +void ListViewDnd::setVisibleItems( bool b ) +{ + if ( disabledItems.isEmpty() ) + return; + + disabledItems.first(); + do { + disabledItems.current()->setVisible( b ); + } while ( disabledItems.next() ); +} + +void ListViewDnd::updateLine( const QPoint & dragPos ) +{ + QListViewItem * item = itemAt(dragPos); + QListView * src = (QListView *) this->src; + + int ypos = item ? + ( src->itemRect( item ).bottom() - ( line->height() / 2 ) ) : + ( src->itemRect( src->firstChild() ).top() ); + + int xpos = dropDepth( item, dragPos ) * src->treeStepSize(); + line->resize( src->viewport()->width() - xpos, line->height() ); + line->move( xpos, ypos ); +} + +QListViewItem * ListViewDnd::itemAt( QPoint pos ) +{ + QListView * src = (QListView *) this->src; + int headerHeight = (int)(src->header()->height()); + pos.ry() -= headerHeight; + QListViewItem * result = src->itemAt( pos ); + + if ( result && ( pos.ry() < (src->itemPos(result) + result->height()/2) ) ) + result = result->itemAbove(); + + // Wind back if has parent, and we're in flat mode + while ( result && result->parent() && (dMode & Flat) ) + result = result->parent(); + + // Wind back if has parent, and we're in flat mode + while ( result && !result->isVisible() && result->parent() ) + result = result->parent(); + + if ( !result && src->firstChild() && (pos.y() > src->itemRect(src->firstChild()).bottom()) ) { + result = src->lastItem(); + if ( !result->isVisible() ) + // Handle special case where last item is actually hidden + result = result->itemAbove(); + } + + return result; +} + +int ListViewDnd::dropDepth( QListViewItem * item, QPoint pos ) +{ + if ( !item || (dMode & Flat) ) + return 0; + + int result = 0; + int itemDepth = item->depth(); + int indentSize = ((QListView *)src)->treeStepSize(); + int itemLeft = indentSize * itemDepth; + int childMargin = indentSize*2; + if ( pos.x() > itemLeft + childMargin ) { + result = itemDepth + 1; + } else if ( pos.x() < itemLeft ) { + result = pos.x() / indentSize; + } else { + result = itemDepth; + } + return result; +} + +bool ListViewDnd::canDecode( QDragEnterEvent * event ) +{ + return ListViewItemDrag::canDecode( event ); +} + +// ------------------------------------------------------------------ +// The Dragobject Implementation ------------------------------------ +// ------------------------------------------------------------------ + +QDataStream & operator<< ( QDataStream & stream, const QListViewItem & item ); +QDataStream & operator>> ( QDataStream & stream, QListViewItem & item ); + +ListViewItemDrag::ListViewItemDrag( ListViewItemList & items, QWidget * parent, const char * name ) + : QStoredDrag( "qt/listviewitem", parent, name ) +{ + // ### FIX! + QByteArray data( sizeof( Q_INT32 ) + sizeof( QListViewItem ) * items.count() ); + QDataStream stream( data, IO_WriteOnly ); + + stream << items.count(); + + QListViewItem *i = items.first(); + while ( i ) { + stream << *i; + i = items.next(); + } + + setEncodedData( data ); +} + +bool ListViewItemDrag::canDecode( QDragMoveEvent * event ) +{ + return event->provides( "qt/listviewitem" ); +} + +bool ListViewItemDrag::decode( QDropEvent * event, QListView * parent, QListViewItem * insertPoint, DropRelation dr ) +{ + QByteArray data = event->encodedData( "qt/listviewitem" ); + QListViewItem* itemParent = insertPoint ? insertPoint->parent() : 0; + + // Change from sibling (default) to child creation + if ( insertPoint && dr == Child ) { + itemParent = insertPoint; + insertPoint = 0; + } + + if ( data.size() ) { + event->accept(); + QDataStream stream( data, IO_ReadOnly ); + + int count = 0; + stream >> count; + + for( int i = 0; i < count; i++ ) { + if ( itemParent ) { + insertPoint = new QListViewItem( itemParent, insertPoint ); + itemParent->setOpen( TRUE ); + } else { // No parent for insertPoint, use QListView + insertPoint = new QListViewItem( parent, insertPoint ); + } + stream >> *insertPoint; + } + return TRUE; + } + return FALSE; +} + + +QDataStream & operator<< ( QDataStream & stream, const QListViewItem & item ) +{ + int columns = item.listView()->columns(); + stream << columns; + + Q_UINT8 b = 0; + + int i; + for ( i = 0; i < columns; i++ ) { + b = (Q_UINT8) ( item.text( i ) != QString::null ); // does column i have a string ? + stream << b; + if ( b ) { + stream << item.text( i ); + } + } + + for ( i = 0; i < columns; i++ ) { + b = (Q_UINT8) ( !!item.pixmap( i ) ); // does column i have a pixmap ? + stream << b; + if ( b ) { + stream << ( *item.pixmap( i ) ); + } + } + + stream << (Q_UINT8) item.isOpen(); + stream << (Q_UINT8) item.isSelectable(); + stream << (Q_UINT8) item.isExpandable(); + stream << (Q_UINT8) item.dragEnabled(); + stream << (Q_UINT8) item.dropEnabled(); + stream << (Q_UINT8) item.isVisible(); + + for ( i = 0; i < columns; i++ ) { + stream << (Q_UINT8) item.renameEnabled( i ); + } + + stream << (Q_UINT8) item.multiLinesEnabled(); + stream << item.childCount(); + + if ( item.childCount() > 0 ) { + QListViewItem * child = item.firstChild(); + while ( child ) { + stream << ( *child ); // recursive call + child = child->nextSibling(); + } + } + + return stream; +} + +QDataStream & operator>> ( QDataStream & stream, QListViewItem & item ) +{ + Q_INT32 columns; + stream >> columns; + + Q_UINT8 b = 0; + + QString text; + int i; + for ( i = 0; i < columns; i++ ) { + stream >> b; + if ( b ) { // column i has string ? + stream >> text; + item.setText( i, text ); + } + } + + QPixmap pixmap; + for ( i = 0; i < columns; i++ ) { + stream >> b; // column i has pixmap ? + if ( b ) { + stream >> pixmap; + item.setPixmap( i, pixmap ); + } + } + + stream >> b; + item.setOpen( b ); + + stream >> b; + item.setSelectable( b ); + + stream >> b; + item.setExpandable( b ); + + stream >> b; + item.setDragEnabled( b ); + + stream >> b; + item.setDropEnabled( b ); + + stream >> b; + item.setVisible( b ); + + for ( i = 0; i < columns; i++ ) { + stream >> b; + item.setRenameEnabled( i, b ); + } + + stream >> b; + item.setMultiLinesEnabled( b ); + + int childCount; + stream >> childCount; + + QListViewItem *child = 0; + QListViewItem *prevchild = 0; + for ( i = 0; i < childCount; i++ ) { + child = new QListViewItem( &item, prevchild ); + stream >> ( *child ); + item.insertItem( child ); + prevchild = child; + } + + return stream; +} diff --git a/tools/designer/designer/listviewdnd.h b/tools/designer/designer/listviewdnd.h new file mode 100644 index 0000000..4978e7e --- /dev/null +++ b/tools/designer/designer/listviewdnd.h @@ -0,0 +1,73 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LISTVIEWDND_H +#define LISTVIEWDND_H + +#include +#include +#include "listdnd.h" + +class QWidget; +class QListView; +typedef QPtrList ListViewItemList; + +class ListViewDnd : public ListDnd +{ + Q_OBJECT +public: + enum DragMode { Flat = 16 }; // see ListDnd::DragMode + + ListViewDnd( QListView * eventSource, const char * name = 0 ); + +signals: + void dropped( QListViewItem * ); + +public slots: + void confirmDrop( QListViewItem * ); + +protected: + virtual bool dropEvent( QDropEvent * event ); + virtual bool mouseMoveEvent( QMouseEvent * event ); + virtual void updateLine( const QPoint & pos ); + virtual bool canDecode( QDragEnterEvent * event ); +private: + QListViewItem * itemAt( QPoint pos ); + int dropDepth( QListViewItem * item, QPoint pos ); + int buildFlatList( ListViewItemList & list ); + int buildTreeList( ListViewItemList & list ); + void setVisibleItems( bool b ); + ListViewItemList disabledItems; +}; + +#endif //LISTVIEWDND_H diff --git a/tools/designer/designer/listvieweditor.ui b/tools/designer/designer/listvieweditor.ui new file mode 100644 index 0000000..5357d28 --- /dev/null +++ b/tools/designer/designer/listvieweditor.ui @@ -0,0 +1,938 @@ + +ListViewEditorBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + ListViewEditorBase + + + + 0 + 0 + 567 + 398 + + + + Edit Listview + + + true + + + <b>Edit Listview</b><p>Use the controls on the <b>Items</b>-tab to add, edit or delete items in the listview. Change the column configuration of the listview using the controls on the <b>Columns</b>-tab.</p>Click the <b>New Item</b>-button to create a new item, then enter text and add a pixmap.</p><p>Select an item from the list and click the <b>Delete Item</b>-button to remove the item from the list.</p> + + + + unnamed + + + 11 + + + 6 + + + + tabWidget + + + + Widget10 + + + &Items + + + + unnamed + + + 11 + + + 6 + + + + itemDelete + + + &Delete Item + + + Delete item + + + <b>Deletes the selected item.</b><p>Any sub-items are also deleted.</p> + + + + + GroupBox1 + + + + 0 + 5 + 0 + 0 + + + + Item Properties + + + + unnamed + + + 11 + + + 6 + + + + Label2 + + + Pi&xmap: + + + itemChoosePixmap + + + + + Label1 + + + &Text: + + + itemText + + + + + itemText + + + + 0 + 0 + + + + Change text + + + <b>Change the text of the item.</b><p>The text will be changed in the current column of the selected item.</p> + + + + + itemColumn + + + Change column + + + <b>Select the current column.</b><p>The item's text and pixmap will be changed for the current column</p> + + + + + Label4 + + + Colu&mn: + + + itemColumn + + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + itemPixmap + + + Label4 + + + + + itemDeletePixmap + + + + 30 + 22 + + + + + + + designer_s_editcut.png + + + Delete Pixmap + + + <b>Delete the selected item's pixmap.</b><p>The pixmap in the current column of the selected item will be deleted.</p> + + + + + itemChoosePixmap + + + + 30 + 22 + + + + ... + + + Select a Pixmap + + + <b>Select a pixmap file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p> + + + + + + + + + itemNew + + + &New Item + + + Add an item + + + <b>Adds a new item to the list.</b><p>The item will be inserted at the top of the list and can be moved using the up- and down-buttons.</p> + + + + + itemsPreview + + + The list of items. + + + + + itemNewSub + + + New &Subitem + + + Add a subitem + + + <b>Create a new sub-item for the selected item.</b><p>New sub-items are inserted at the top of the list of sub-items, and new levels are created automatically.</p> + + + + + Vertical Spacing1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + itemUp + + + + + + designer_s_up.png + + + Move up + + + <b>Move the selected item up.</b><p>The item will be moved within its level in the hierarchy.</p> + + + + + itemDown + + + + + + designer_s_down.png + + + Move down + + + <b>Move the selected item down.</b><p>The item will be moved within its level in the hierarchy.</p> + + + + + itemLeft + + + + + + designer_s_left.png + + + Move left + + + <b>Move the selected item one level up.</b><p>This will also change the level of the item's sub-items.</p> + + + + + itemRight + + + + + + designer_s_right.png + + + Move right + + + <b>Move the selected item one level down.</b><p>This will also change the level of the item's sub-items.</p> + + + + + + + Widget11 + + + Co&lumns + + + + unnamed + + + 11 + + + 6 + + + + GroupBox1 + + + Column Properties + + + + unnamed + + + 11 + + + 6 + + + + Label2 + + + &Pixmap: + + + colChoosePixmap + + + + + colPixmap + + + Label4 + + + + + colDeletePixmap + + + + 30 + 22 + + + + + + + designer_s_editcut.png + + + Delete Pixmap + + + Delete the pixmap of the selected column. + + + + + colChoosePixmap + + + + 30 + 22 + + + + ... + + + Select a Pixmap + + + <b>Select a pixmap file for the selected column.</b><p>The pixmap will be displayed in the header of the listview.</p> + + + + + Label1 + + + &Text: + + + colText + + + + + colText + + + + 0 + 0 + + + + Enter column text + + + <b>Enter the text for the selected column.</b><p>The text will be displayed in the header of the listview.</p> + + + + + colClickable + + + Clicka&ble + + + If this option is checked, the selected column will react to mouse clicks on the header. + + + + + colResizable + + + Re&sizable + + + The column's width will be resizable if this option is checked. + + + + + + + colDelete + + + &Delete Column + + + Delete column + + + Deletes the selected Column. + + + + + colDown + + + + + + designer_s_down.png + + + Move down + + + <b>Move the selected item down.</b><p>The top-most column will be the first column in the list.</p> + + + + + colNew + + + &New Column + + + Add a Column + + + <b>Create a new column.</b><p>New columns are appended at the end of (right of) the list and may be moved using the up- and down-buttons.</p> + + + + + colUp + + + + + + designer_s_up.png + + + Move up + + + <b>Move the selected item up.</b><p>The top-most column will be the first column in the list.</p> + + + + + colPreview + + + The list of columns. + + + + + Vertical Spacing2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + helpButton + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + applyButton + + + &Apply + + + true + + + Apply all changes. + + + + + okButton + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + cancelButton + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + + + cancelButton + clicked() + ListViewEditorBase + reject() + + + itemNew + clicked() + ListViewEditorBase + itemNewClicked() + + + itemDelete + clicked() + ListViewEditorBase + itemDeleteClicked() + + + itemUp + clicked() + ListViewEditorBase + itemUpClicked() + + + itemDown + clicked() + ListViewEditorBase + itemDownClicked() + + + itemColumn + valueChanged(int) + ListViewEditorBase + itemColChanged(int) + + + itemText + textChanged(const QString&) + ListViewEditorBase + itemTextChanged(const QString&) + + + itemDeletePixmap + clicked() + ListViewEditorBase + itemPixmapDeleted() + + + itemChoosePixmap + clicked() + ListViewEditorBase + itemPixmapChoosen() + + + colNew + clicked() + ListViewEditorBase + newColumnClicked() + + + colDelete + clicked() + ListViewEditorBase + deleteColumnClicked() + + + colUp + clicked() + ListViewEditorBase + columnUpClicked() + + + colDown + clicked() + ListViewEditorBase + columnDownClicked() + + + colText + textChanged(const QString&) + ListViewEditorBase + columnTextChanged(const QString&) + + + colDeletePixmap + clicked() + ListViewEditorBase + columnPixmapDeleted() + + + colChoosePixmap + clicked() + ListViewEditorBase + columnPixmapChosen() + + + colResizable + toggled(bool) + ListViewEditorBase + columnResizable(bool) + + + colClickable + toggled(bool) + ListViewEditorBase + columnClickable(bool) + + + tabWidget + selected(const QString&) + ListViewEditorBase + initTabPage(const QString&) + + + okButton + clicked() + ListViewEditorBase + okClicked() + + + applyButton + clicked() + ListViewEditorBase + applyClicked() + + + colPreview + currentChanged(QListBoxItem*) + ListViewEditorBase + currentColumnChanged(QListBoxItem*) + + + colPreview + selectionChanged(QListBoxItem*) + ListViewEditorBase + currentColumnChanged(QListBoxItem*) + + + itemsPreview + currentChanged(QListViewItem*) + ListViewEditorBase + currentItemChanged(QListViewItem*) + + + itemsPreview + selectionChanged(QListViewItem*) + ListViewEditorBase + currentItemChanged(QListViewItem*) + + + itemNewSub + clicked() + ListViewEditorBase + itemNewSubClicked() + + + itemLeft + clicked() + ListViewEditorBase + itemLeftClicked() + + + itemRight + clicked() + ListViewEditorBase + itemRightClicked() + + + + okButton + cancelButton + tabWidget + itemsPreview + itemNew + itemNewSub + itemDelete + itemUp + itemDown + itemLeft + itemRight + itemColumn + itemText + itemDeletePixmap + itemChoosePixmap + helpButton + applyButton + colPreview + colNew + colDelete + colUp + colDown + colText + colDeletePixmap + colChoosePixmap + colClickable + colResizable + + + init() + destroy() + applyClicked() + columnClickable(bool) + columnDownClicked() + columnPixmapChosen() + columnPixmapDeleted() + columnResizable(bool) + columnTextChanged(const QString &) + columnUpClicked() + currentColumnChanged(QListBoxItem*) + currentItemChanged(QListViewItem*) + deleteColumnClicked() + initTabPage(const QString &) + itemColChanged(int) + itemDeleteClicked() + itemDownClicked() + itemLeftClicked() + itemNewClicked() + itemNewSubClicked() + itemPixmapChoosen() + itemPixmapDeleted() + itemTextChanged(const QString &) + itemUpClicked() + newColumnClicked() + itemRightClicked() + okClicked() + + + + diff --git a/tools/designer/designer/listvieweditorimpl.cpp b/tools/designer/designer/listvieweditorimpl.cpp new file mode 100644 index 0000000..42167d7 --- /dev/null +++ b/tools/designer/designer/listvieweditorimpl.cpp @@ -0,0 +1,655 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "formwindow.h" +#include "mainwindow.h" +#include "listvieweditorimpl.h" +#include "pixmapchooser.h" +#include "command.h" +#include "listviewdnd.h" +#include "listboxdnd.h" +#include "listboxrename.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ListViewEditor::ListViewEditor( QWidget *parent, QListView *lv, FormWindow *fw ) + : ListViewEditorBase( parent, 0, TRUE ), listview( lv ), formwindow( fw ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + itemColumn->setEnabled( FALSE ); + + setupColumns(); + PopulateListViewCommand::transferItems( listview, itemsPreview ); + setupItems(); + + itemsPreview->setShowSortIndicator( listview->showSortIndicator() ); + itemsPreview->setAllColumnsShowFocus( listview->allColumnsShowFocus() ); + itemsPreview->setRootIsDecorated( listview->rootIsDecorated() ); + + if ( itemsPreview->firstChild() ) { + itemsPreview->setCurrentItem( itemsPreview->firstChild() ); + itemsPreview->setSelected( itemsPreview->firstChild(), TRUE ); + } + + // Clamp on drag and drop to QListView + ListViewDnd *itemsDnd = new ListViewDnd( itemsPreview ); + itemsDnd->setDragMode( ListViewDnd::Internal | ListViewDnd::Move ); + QObject::connect( itemsDnd, SIGNAL( dropped( QListViewItem * ) ), + itemsDnd, SLOT( confirmDrop( QListViewItem * ) ) ); + + // Enable rename for all QListViewItems + QListViewItemIterator it = ((QListView *)itemsPreview)->firstChild(); + for ( ; *it; it++ ) + (*it)->setRenameEnabled( 0, TRUE ); + + // Connect listview signal to signal-relay + QObject::connect( itemsPreview, + SIGNAL( itemRenamed( QListViewItem*, int, const QString & ) ), + this, + SLOT( emitItemRenamed(QListViewItem*, int, const QString&) ) ); + + // Connect signal-relay to QLineEdit "itemText" + QObjectList *l = parent->queryList( "QLineEdit", "itemText" ); + QObject *obj; + QObjectListIt itemsLineEditIt( *l ); + while ( (obj = itemsLineEditIt.current()) != 0 ) { + ++itemsLineEditIt; + QObject::connect( this, + SIGNAL( itemRenamed( const QString & ) ), + obj, + SLOT( setText( const QString & ) ) ); + } + delete l; + + // Clamp on drag and drop to QListBox + ListBoxDnd *columnsDnd = new ListBoxDnd( colPreview ); + columnsDnd->setDragMode( ListBoxDnd::Internal | ListBoxDnd::Move ); + QObject::connect( columnsDnd, SIGNAL( dropped( QListBoxItem * ) ), + columnsDnd, SLOT( confirmDrop( QListBoxItem * ) ) ); + + // Clamp on rename to QListBox + ListBoxRename *columnsRename = new ListBoxRename( colPreview ); + QObject::connect( columnsRename, + SIGNAL( itemTextChanged( const QString & ) ), + this, + SLOT( columnTextChanged( const QString & ) ) ); + + // Find QLineEdit "colText" and connect + l = parent->queryList( "QLineEdit", "colText" ); + QObjectListIt columnsLineEditIt( *l ); + while ( (obj = columnsLineEditIt.current()) != 0 ) { + ++columnsLineEditIt; + QObject::connect( columnsRename, + SIGNAL( itemTextChanged( const QString & ) ), + obj, + SLOT( setText( const QString & ) ) ); + } + delete l; +} + +void ListViewEditor::applyClicked() +{ + setupItems(); + PopulateListViewCommand *cmd = new PopulateListViewCommand( tr( "Edit the Items and Columns of '%1'" ).arg( listview->name() ), + formwindow, listview, itemsPreview ); + cmd->execute(); + formwindow->commandHistory()->addCommand( cmd ); +} + +void ListViewEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void ListViewEditor::columnClickable( bool b ) +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + c->clickable = b; +} + +void ListViewEditor::columnDownClicked() +{ + if ( colPreview->currentItem() == -1 || + colPreview->currentItem() > (int)colPreview->count() - 2 ) + return; + + colPreview->clearSelection(); + QListBoxItem *i = colPreview->item( colPreview->currentItem() ); + QListBoxItem *below = i->next(); + + colPreview->takeItem( i ); + colPreview->insertItem( i, below ); + + colPreview->setCurrentItem( i ); + colPreview->setSelected( i, TRUE ); +} + +void ListViewEditor::columnPixmapChosen() +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + + QPixmap pix; + if ( colPixmap->pixmap() ) + pix = qChoosePixmap( this, formwindow, *colPixmap->pixmap() ); + else + pix = qChoosePixmap( this, formwindow, QPixmap() ); + + if ( pix.isNull() ) + return; + + c->pixmap = pix; + colPreview->blockSignals( TRUE ); + if ( !c->pixmap.isNull() ) + colPreview->changeItem( c->pixmap, c->text, colPreview->index( c->item ) ); + else + colPreview->changeItem( c->text, colPreview->index( c->item ) ); + c->item = colPreview->item( colPreview->currentItem() ); + colPixmap->setPixmap( c->pixmap ); + colPreview->blockSignals( FALSE ); + colDeletePixmap->setEnabled( TRUE ); +} + +void ListViewEditor::columnPixmapDeleted() +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + + c->pixmap = QPixmap(); + colPreview->blockSignals( TRUE ); + if ( !c->pixmap.isNull() ) + colPreview->changeItem( c->pixmap, c->text, colPreview->index( c->item ) ); + else + colPreview->changeItem( c->text, colPreview->index( c->item ) ); + c->item = colPreview->item( colPreview->currentItem() ); + colPixmap->setText( "" ); + colPreview->blockSignals( FALSE ); + colDeletePixmap->setEnabled( FALSE ); +} + +void ListViewEditor::columnResizable( bool b ) +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + c->resizable = b; +} + +void ListViewEditor::columnTextChanged( const QString &txt ) +{ + Column *c = findColumn( colPreview->item( colPreview->currentItem() ) ); + if ( !c ) + return; + + c->text = txt; + colPreview->blockSignals( TRUE ); + if ( !c->pixmap.isNull() ) + colPreview->changeItem( c->pixmap, c->text, colPreview->index( c->item ) ); + else + colPreview->changeItem( c->text, colPreview->index( c->item ) ); + c->item = colPreview->item( colPreview->currentItem() ); + colPreview->blockSignals( FALSE ); +} + +void ListViewEditor::columnUpClicked() +{ + if ( colPreview->currentItem() <= 0 ) + return; + + colPreview->clearSelection(); + QListBoxItem *i = colPreview->item( colPreview->currentItem() ); + QListBoxItem *above = i->prev(); + + colPreview->takeItem( above ); + colPreview->insertItem( above, i ); + + colPreview->setCurrentItem( i ); + colPreview->setSelected( i, TRUE ); +} + +void ListViewEditor::currentColumnChanged( QListBoxItem *i ) +{ + Column *c = findColumn( i ); + if ( !i || !c ) { + colText->setEnabled( FALSE ); + colPixmap->setEnabled( FALSE ); + colDeletePixmap->setEnabled( FALSE ); + colText->blockSignals( TRUE ); + colText->setText( "" ); + colText->blockSignals( FALSE ); + colClickable->setEnabled( FALSE ); + colResizable->setEnabled( FALSE ); + return; + } + + colText->setEnabled( TRUE ); + colPixmap->setEnabled( TRUE ); + colDeletePixmap->setEnabled( i->pixmap() && !i->pixmap()->isNull() ); + colClickable->setEnabled( TRUE ); + colResizable->setEnabled( TRUE ); + + colText->blockSignals( TRUE ); + colText->setText( c->text ); + colText->blockSignals( FALSE ); + if ( !c->pixmap.isNull() ) + colPixmap->setPixmap( c->pixmap ); + else + colPixmap->setText( "" ); + colClickable->setChecked( c->clickable ); + colResizable->setChecked( c->resizable ); +} + +void ListViewEditor::newColumnClicked() +{ + Column col; + col.text = tr( "New Column" ); + col.pixmap = QPixmap(); + col.clickable = TRUE; + col.resizable = TRUE; + if ( !col.pixmap.isNull() ) + col.item = new QListBoxPixmap( colPreview, col.pixmap, col.text ); + else + col.item = new QListBoxText( colPreview, col.text ); + columns.append( col ); + colPreview->setCurrentItem( col.item ); + colPreview->setSelected( col.item, TRUE ); +} + +void ListViewEditor::deleteColumnClicked() +{ + QListBoxItem *i = colPreview->item( colPreview->currentItem() ); + if ( !i ) + return; + + for ( QValueList::Iterator it = columns.begin(); it != columns.end(); ++it ) { + if ( ( *it ).item == i ) { + delete (*it).item; + columns.remove( it ); + break; + } + } + + if ( colPreview->currentItem() != -1 ) + colPreview->setSelected( colPreview->currentItem(), TRUE ); +} + +void ListViewEditor::currentItemChanged( QListViewItem *i ) +{ + if ( !i ) { + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + itemColumn->setEnabled( FALSE ); + return; + } + + itemText->setEnabled( TRUE ); + itemChoosePixmap->setEnabled( TRUE ); + itemDeletePixmap->setEnabled( i->pixmap( itemColumn->value() ) && + !i->pixmap( itemColumn->value() )->isNull() ); + itemColumn->setEnabled( TRUE ); + + displayItem( i, itemColumn->value() ); +} + +void ListViewEditor::displayItem( QListViewItem *i, int col ) +{ + itemText->blockSignals( TRUE ); + itemText->setText( i->text( col ) ); + itemText->blockSignals( FALSE ); + + itemPixmap->blockSignals( TRUE ); + if ( i->pixmap( col ) ) + itemPixmap->setPixmap( *i->pixmap( col ) ); + else + itemPixmap->setText( "" ); + itemPixmap->blockSignals( FALSE ); +} + +void ListViewEditor::itemColChanged( int col ) +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + displayItem( i, col ); + itemDeletePixmap->setEnabled( i->pixmap( col ) && !i->pixmap( col )->isNull() ); +} + +void ListViewEditor::itemDeleteClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + delete i; + if ( itemsPreview->firstChild() ) { + itemsPreview->setCurrentItem( itemsPreview->firstChild() ); + itemsPreview->setSelected( itemsPreview->firstChild(), TRUE ); + } +} + +void ListViewEditor::itemDownClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QListViewItemIterator it( i ); + QListViewItem *parent = i->parent(); + it++; + while ( it.current() ) { + if ( it.current()->parent() == parent ) + break; + it++; + } + + if ( !it.current() ) + return; + QListViewItem *other = it.current(); + + i->moveItem( other ); +} + +void ListViewEditor::itemNewClicked() +{ + QListViewItem *item = new QListViewItem( itemsPreview ); + item->setText( 0, "Item" ); + item->setRenameEnabled( 0, TRUE ); + itemsPreview->setCurrentItem( item ); + itemsPreview->setSelected( item, TRUE ); + itemText->setFocus(); + itemText->selectAll(); +} + +void ListViewEditor::itemNewSubClicked() +{ + QListViewItem *parent = itemsPreview->currentItem(); + QListViewItem *item = 0; + if ( parent ) { + item = new QListViewItem( parent ); + parent->setOpen( TRUE ); + } else { + item = new QListViewItem( itemsPreview ); + } + item->setText( 0, "Subitem" ); + item->setRenameEnabled( 0, TRUE ); + itemsPreview->setCurrentItem( item ); + itemsPreview->setSelected( item, TRUE ); +} + +void ListViewEditor::itemPixmapChoosen() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QPixmap pix; + if ( itemPixmap->pixmap() ) + pix = qChoosePixmap( this, formwindow, *itemPixmap->pixmap() ); + else + pix = qChoosePixmap( this, formwindow, QPixmap() ); + + if ( pix.isNull() ) + return; + + i->setPixmap( itemColumn->value(), QPixmap( pix ) ); + itemPixmap->setPixmap( pix ); + itemDeletePixmap->setEnabled( TRUE ); +} + +void ListViewEditor::itemPixmapDeleted() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + i->setPixmap( itemColumn->value(), QPixmap() ); + itemPixmap->setText( "" ); + itemDeletePixmap->setEnabled( FALSE ); +} + +void ListViewEditor::itemTextChanged( const QString &txt ) +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + i->setText( itemColumn->value(), txt ); +} + +void ListViewEditor::itemUpClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QListViewItemIterator it( i ); + QListViewItem *parent = i->parent(); + --it; + while ( it.current() ) { + if ( it.current()->parent() == parent ) + break; + --it; + } + + if ( !it.current() ) + return; + QListViewItem *other = it.current(); + + other->moveItem( i ); +} + +void ListViewEditor::itemRightClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QListViewItemIterator it( i ); + QListViewItem *parent = i->parent(); + parent = parent ? parent->firstChild() : itemsPreview->firstChild(); + if ( !parent ) + return; + it++; + while ( it.current() ) { + if ( it.current()->parent() == parent ) + break; + it++; + } + + if ( !it.current() ) + return; + QListViewItem *other = it.current(); + + for ( int c = 0; c < itemsPreview->columns(); ++c ) { + QString s = i->text( c ); + i->setText( c, other->text( c ) ); + other->setText( c, s ); + QPixmap pix; + if ( i->pixmap( c ) ) + pix = *i->pixmap( c ); + if ( other->pixmap( c ) ) + i->setPixmap( c, *other->pixmap( c ) ); + else + i->setPixmap( c, QPixmap() ); + other->setPixmap( c, pix ); + } + + itemsPreview->setCurrentItem( other ); + itemsPreview->setSelected( other, TRUE ); +} + +void ListViewEditor::itemLeftClicked() +{ + QListViewItem *i = itemsPreview->currentItem(); + if ( !i ) + return; + + QListViewItemIterator it( i ); + QListViewItem *parent = i->parent(); + if ( !parent ) + return; + parent = parent->parent(); + --it; + while ( it.current() ) { + if ( it.current()->parent() == parent ) + break; + --it; + } + + if ( !it.current() ) + return; + QListViewItem *other = it.current(); + + for ( int c = 0; c < itemsPreview->columns(); ++c ) { + QString s = i->text( c ); + i->setText( c, other->text( c ) ); + other->setText( c, s ); + QPixmap pix; + if ( i->pixmap( c ) ) + pix = *i->pixmap( c ); + if ( other->pixmap( c ) ) + i->setPixmap( c, *other->pixmap( c ) ); + else + i->setPixmap( c, QPixmap() ); + other->setPixmap( c, pix ); + } + + itemsPreview->setCurrentItem( other ); + itemsPreview->setSelected( other, TRUE ); +} + +void ListViewEditor::setupColumns() +{ + QHeader *h = listview->header(); + for ( int i = 0; i < (int)h->count(); ++i ) { + Column col; + col.text = h->label( i ); + col.pixmap = QPixmap(); + if ( h->iconSet( i ) ) + col.pixmap = h->iconSet( i )->pixmap(); + col.clickable = h->isClickEnabled( i ); + col.resizable = h->isResizeEnabled( i ); + if ( !col.pixmap.isNull() ) + col.item = new QListBoxPixmap( colPreview, col.pixmap, col.text ); + else + col.item = new QListBoxText( colPreview, col.text ); + columns.append( col ); + } + + colText->setEnabled( FALSE ); + colPixmap->setEnabled( FALSE ); + colClickable->setEnabled( FALSE ); + colResizable->setEnabled( FALSE ); + + if ( colPreview->firstItem() ) + colPreview->setCurrentItem( colPreview->firstItem() ); + numColumns = colPreview->count(); +} + +void ListViewEditor::setupItems() +{ + itemColumn->setMinValue( 0 ); + itemColumn->setMaxValue( QMAX( numColumns - 1, 0 ) ); + int i = 0; + QHeader *header = itemsPreview->header(); + for ( QListBoxItem *item = colPreview->firstItem(); item; item = item->next() ) { + Column *col = findColumn( item ); + if ( !col ) + continue; + if ( i >= itemsPreview->columns() ) + itemsPreview->addColumn( col->text ); + header->setLabel( i, col->pixmap, col->text ); + header->setResizeEnabled( col->resizable, i ); + header->setClickEnabled( col->clickable, i ); + ++i; + } + while ( itemsPreview->columns() > i ) + itemsPreview->removeColumn( i ); + + itemColumn->setValue( QMIN( numColumns - 1, itemColumn->value() ) ); +} + +ListViewEditor::Column *ListViewEditor::findColumn( QListBoxItem *i ) +{ + if ( !i ) + return 0; + + for ( QValueList::Iterator it = columns.begin(); it != columns.end(); ++it ) { + if ( ( *it ).item == i ) + return &( *it ); + } + + return 0; +} + +void ListViewEditor::initTabPage( const QString &page ) +{ + numColumns = colPreview->count(); + if ( page == tr( "&Items" ) ) { + setupItems(); + if ( numColumns == 0 ) { + itemNew->setEnabled( FALSE ); + itemNewSub->setEnabled( FALSE ); + itemText->setEnabled( FALSE ); + itemChoosePixmap->setEnabled( FALSE ); + itemDeletePixmap->setEnabled( FALSE ); + itemColumn->setEnabled( FALSE ); + } else { + itemNew->setEnabled( TRUE ); + itemNewSub->setEnabled( TRUE ); + } + } +} + +void ListViewEditor::emitItemRenamed( QListViewItem *, int, const QString & text ) +{ + emit itemRenamed( text ); // Relay signal ( to QLineEdit ) +} diff --git a/tools/designer/designer/listvieweditorimpl.h b/tools/designer/designer/listvieweditorimpl.h new file mode 100644 index 0000000..2b52383 --- /dev/null +++ b/tools/designer/designer/listvieweditorimpl.h @@ -0,0 +1,109 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LISTVIEWEDITORIMPL_H +#define LISTVIEWEDITORIMPL_H + +#include "listvieweditor.h" + +#include +#include +#include + +class FormWindow; + +class ListViewEditor : public ListViewEditorBase +{ + Q_OBJECT + +public: + ListViewEditor( QWidget *parent, QListView *lv, FormWindow *fw ); + +signals: + void itemRenamed(const QString &); + +protected slots: + void applyClicked(); + void columnClickable(bool); + void columnDownClicked(); + void columnPixmapChosen(); + void columnPixmapDeleted(); + void columnResizable(bool); + void columnTextChanged(const QString &); + void columnUpClicked(); + void currentColumnChanged(QListBoxItem*); + void currentItemChanged(QListViewItem*); + void deleteColumnClicked(); + void itemColChanged(int); + void itemDeleteClicked(); + void itemDownClicked(); + void itemNewClicked(); + void itemNewSubClicked(); + void itemPixmapChoosen(); + void itemPixmapDeleted(); + void itemTextChanged(const QString &); + void itemUpClicked(); + void itemLeftClicked(); + void itemRightClicked(); + void newColumnClicked(); + void okClicked(); + void initTabPage(const QString &page); + void emitItemRenamed(QListViewItem*, int, const QString&); // signal relay + +private: + struct Column + { + QListBoxItem *item; + QString text; + QPixmap pixmap; + bool clickable, resizable; + Q_DUMMY_COMPARISON_OPERATOR( Column ) + }; + +private: + void setupColumns(); + void setupItems(); + Column *findColumn( QListBoxItem *i ); + void transferItems( QListView *from, QListView *to ); + void displayItem( QListViewItem *i, int col ); + +private: + QListView *listview; + QValueList columns; + int numColumns; + FormWindow *formwindow; + +}; + + +#endif diff --git a/tools/designer/designer/mainwindow.cpp b/tools/designer/designer/mainwindow.cpp new file mode 100644 index 0000000..0474b2f --- /dev/null +++ b/tools/designer/designer/mainwindow.cpp @@ -0,0 +1,3784 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "designerappiface.h" +#include "designerapp.h" + +#include "mainwindow.h" +#include "defs.h" +#include "globaldefs.h" +#include "formwindow.h" +#include "widgetdatabase.h" +#include "widgetfactory.h" +#include "propertyeditor.h" +#include "metadatabase.h" +#include "resource.h" +#include "hierarchyview.h" +#include "newformimpl.h" +#include "workspace.h" +#include "about.h" +#include "multilineeditorimpl.h" +#include "wizardeditorimpl.h" +#include "outputwindow.h" +#include "actioneditorimpl.h" +#include "actiondnd.h" +#include "project.h" +#include "projectsettingsimpl.h" +#include "qwidgetfactory.h" +#include "pixmapcollection.h" +#include "qcompletionedit.h" +#include "sourcefile.h" +#include "orderindicator.h" +#include +#include "widgetaction.h" +#include "propertyobject.h" +#include "popupmenueditor.h" +#include "menubareditor.h" + +#include "startdialog.h" +#include "createtemplate.h" +#include "editfunctions.h" +//#include "connectionviewer.h" +#include "formsettings.h" +#include "preferences.h" +#include "pixmapcollectioneditor.h" +#ifndef QT_NO_SQL +#include "dbconnectionimpl.h" +#endif +//#include "connectioneditor.h" +#include "customwidgeteditorimpl.h" +#include "paletteeditorimpl.h" +#include "listboxeditorimpl.h" +#include "listvieweditorimpl.h" +#include "iconvieweditorimpl.h" +#include "tableeditorimpl.h" +#include "multilineeditor.h" +#include "finddialog.h" +#include "replacedialog.h" +#include "gotolinedialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static bool mblockNewForms = FALSE; +extern QMap *qwf_forms; +extern QString *qwf_language; +extern bool qwf_execute_code; +extern bool qwf_stays_on_top; +extern void set_splash_status( const QString &txt ); +extern QObject* qwf_form_object; +extern QString *qwf_plugin_dir; + +MainWindow *MainWindow::self = 0; + +QString assistantPath() +{ + QString path = QDir::cleanDirPath( QString( qInstallPathBins() ) + + QDir::separator() ); + return path; +} + + +static QString textNoAccel( const QString& text) +{ + QString t = text; + int i; + while ( (i = t.find('&') )>= 0 ) { + t.remove(i,1); + } + return t; +} + + +MainWindow::MainWindow( bool asClient, bool single, const QString &plgDir ) + : QMainWindow( 0, "designer_mainwindow", WType_TopLevel | (single ? 0 : WDestructiveClose) | WGroupLeader ), + grd( 10, 10 ), sGrid( TRUE ), snGrid( TRUE ), restoreConfig( TRUE ), splashScreen( TRUE ), + fileFilter( tr( "Qt User-Interface Files (*.ui)" ) ), client( asClient ), + previewing( FALSE ), databaseAutoEdit( FALSE ), autoSaveEnabled( FALSE ), autoSaveInterval( 1800 ) +{ + extern void qInitImages_designercore(); + qInitImages_designercore(); + + self = this; + setPluginDirectory( plgDir ); + customWidgetToolBar = customWidgetToolBar2 = 0; + guiStuffVisible = TRUE; + editorsReadOnly = FALSE; + sSignalHandlers = TRUE; + init_colors(); + shStartDialog = TRUE; + + desInterface = new DesignerInterfaceImpl( this ); + desInterface->addRef(); + inDebugMode = FALSE; + savePluginPaths = FALSE; + + updateFunctionsTimer = new QTimer( this ); + connect( updateFunctionsTimer, SIGNAL( timeout() ), + this, SLOT( doFunctionsChanged() ) ); + + autoSaveTimer = new QTimer( this ); + connect( autoSaveTimer, SIGNAL( timeout() ), + this, SLOT( fileSaveAll() ) ); + + set_splash_status( "Loading Plugins..." ); + setupPluginManagers(); + + if ( !single ) + qApp->setMainWidget( this ); + QWidgetFactory::addWidgetFactory( new CustomWidgetFactory ); +#ifndef Q_WS_MACX + setIcon( QPixmap::fromMimeSource( "designer_appicon.png" ) ); +#endif + + actionGroupTools = 0; + prefDia = 0; + windowMenu = 0; + hierarchyView = 0; + actionEditor = 0; + currentProject = 0; + wspace = 0; + oWindow = 0; + singleProject = single; + + statusBar()->clear(); +#if defined(QT_NON_COMMERCIAL) + statusBar()->addWidget( new QLabel(tr("Ready - This is the non-commercial version of Qt - " + "For commercial evaluations, use the help menu to register with Trolltech."), statusBar()), 1 ); +#else + statusBar()->addWidget( new QLabel("Ready", statusBar()), 1 ); +#endif + + + set_splash_status( "Setting up GUI..." ); + setupMDI(); + setupMenuBar(); + + setupToolbox(); + + setupFileActions(); + setupEditActions(); + setupProjectActions(); + setupSearchActions(); + layoutToolBar = new QToolBar( this, "Layout" ); + layoutToolBar->setCloseMode( QDockWindow::Undocked ); + addToolBar( layoutToolBar, tr( "Layout" ) ); + interpreterPluginManager = 0; + setupToolActions(); + setupLayoutActions(); + setupPreviewActions(); + setupOutputWindow(); + setupActionManager(); + setupWindowActions(); + + setupWorkspace(); + setupHierarchyView(); + setupPropertyEditor(); + setupActionEditor(); + + setupHelpActions(); + + setupRMBMenus(); + + connect( this, SIGNAL( projectChanged() ), this, SLOT( emitProjectSignals() ) ); + connect( this, SIGNAL( hasActiveWindow(bool) ), this, SLOT( emitProjectSignals() ) ); + + emit hasActiveForm( FALSE ); + emit hasActiveWindow( FALSE ); + + lastPressWidget = 0; + qApp->installEventFilter( this ); + + QSize as( qApp->desktop()->size() ); + as -= QSize( 30, 30 ); + resize( QSize( 1200, 1000 ).boundedTo( as ) ); + + connect( qApp->clipboard(), SIGNAL( dataChanged() ), + this, SLOT( clipboardChanged() ) ); + clipboardChanged(); + layoutChilds = FALSE; + layoutSelected = FALSE; + breakLayout = FALSE; + backPix = TRUE; + + set_splash_status( "Loading User Settings..." ); + readConfig(); + // hack to make WidgetFactory happy (so it knows QWidget and QDialog for resetting properties) + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QWidget" ), this, 0, FALSE ); + delete w; + w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QDialog" ), this, 0, FALSE ); + delete w; + w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QLabel" ), this, 0, FALSE ); + delete w; + w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QTabWidget" ), this, 0, FALSE ); + delete w; + w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QFrame" ), this, 0, FALSE ); + delete w; + setAppropriate( (QDockWindow*)actionEditor->parentWidget(), FALSE ); + actionEditor->parentWidget()->hide(); + + assistant = new QAssistantClient( assistantPath(), this ); + + statusBar()->setSizeGripEnabled( TRUE ); + set_splash_status( "Initialization Done." ); + if ( shStartDialog ) + QTimer::singleShot( 0, this, SLOT( showStartDialog() )); + + if ( autoSaveEnabled ) + autoSaveTimer->start( autoSaveInterval * 1000 ); +} + +MainWindow::~MainWindow() +{ + QValueList::Iterator tit; + for ( tit = preferenceTabs.begin(); tit != preferenceTabs.end(); ++tit ) { + Tab t = *tit; + delete t.w; + } + for ( tit = projectTabs.begin(); tit != projectTabs.end(); ++tit ) { + Tab t = *tit; + delete t.w; + } + + QMap< QAction*, Project* >::Iterator it = projects.begin(); + while ( it != projects.end() ) { + Project *p = *it; + ++it; + delete p; + } + projects.clear(); + + delete oWindow; + oWindow = 0; + + desInterface->release(); + desInterface = 0; + + delete actionPluginManager; + delete preferencePluginManager; + delete projectSettingsPluginManager; + delete interpreterPluginManager; + delete templateWizardPluginManager; + delete editorPluginManager; + delete sourceTemplatePluginManager; + + MetaDataBase::clearDataBase(); + if(self == this) + self = 0; +} + +void MainWindow::setupMDI() +{ + QVBox *vbox = new QVBox( this ); + setCentralWidget( vbox ); + vbox->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + vbox->setMargin( 1 ); + vbox->setLineWidth( 1 ); + qworkspace = new QWorkspace( vbox ); + qworkspace->setPaletteBackgroundPixmap( QPixmap::fromMimeSource( "designer_background.png" ) ); + qworkspace->setScrollBarsEnabled( TRUE ); + connect( qworkspace, SIGNAL( windowActivated( QWidget * ) ), + this, SLOT( activeWindowChanged( QWidget * ) ) ); + lastActiveFormWindow = 0; + qworkspace->setAcceptDrops( TRUE ); +} + +void MainWindow::setupMenuBar() +{ + menubar = menuBar(); +} + +void MainWindow::setupPropertyEditor() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + propertyEditor = new PropertyEditor( dw ); + addToolBar( dw, Qt::DockRight ); + dw->setWidget( propertyEditor ); + dw->setFixedExtentWidth( 250 ); + dw->setCaption( tr( "Property Editor/Signal Handlers" ) ); + QWhatsThis::add( propertyEditor, + tr("The Property Editor" + "

You can change the appearance and behavior of the selected widget in the " + "property editor.

" + "

You can set properties for components and forms at design time and see the " + "immediately see the effects of the changes. " + "Each property has its own editor which (depending on the property) can be used " + "to enter " + "new values, open a special dialog, or to select values from a predefined list. " + "Click F1 to get detailed help for the selected property.

" + "

You can resize the columns of the editor by dragging the separators in the " + "list's header.

" + "

Signal Handlers

" + "

In the Signal Handlers tab you can define connections between " + "the signals emitted by widgets and the slots in the form. " + "(These connections can also be made using the connection tool.)" ) ); + dw->show(); +} + +void MainWindow::setupOutputWindow() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + addToolBar( dw, Qt::DockBottom ); + oWindow = new OutputWindow( dw ); + dw->setWidget( oWindow ); + dw->setFixedExtentHeight( 150 ); + dw->setCaption( tr( "Output Window" ) ); +} + +void MainWindow::setupHierarchyView() +{ + if ( hierarchyView ) + return; + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + hierarchyView = new HierarchyView( dw ); + addToolBar( dw, Qt::DockRight ); + dw->setWidget( hierarchyView ); + + dw->setCaption( tr( "Object Explorer" ) ); + dw->setFixedExtentWidth( 250 ); + QWhatsThis::add( hierarchyView, + tr("The Object Explorer" + "

The Object Explorer provides an overview of the relationships " + "between the widgets in a form. You can use the clipboard functions using " + "a context menu for each item in the view. It is also useful for selecting widgets " + "in forms that have complex layouts.

" + "

The columns can be resized by dragging the separator in the list's header.

" + "

The second tab shows all the form's slots, class variables, includes, etc.

") ); + dw->show(); +} + +void MainWindow::setupWorkspace() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + QVBox *vbox = new QVBox( dw ); + QCompletionEdit *edit = new QCompletionEdit( vbox ); + QToolTip::add( edit, tr( "Start typing the buffer you want to switch to here (ALT+B)" ) ); + QAccel *a = new QAccel( this ); + a->connectItem( a->insertItem( ALT + Key_B ), edit, SLOT( setFocus() ) ); + wspace = new Workspace( vbox, this ); + wspace->setBufferEdit( edit ); + wspace->setCurrentProject( currentProject ); + addToolBar( dw, Qt::DockRight ); + dw->setWidget( vbox ); + + dw->setCaption( tr( "Project Overview" ) ); + QWhatsThis::add( wspace, tr("The Project Overview Window" + "

The Project Overview Window displays all the current " + "project, including forms and source files.

" + "

Use the search field to rapidly switch between files.

")); + dw->setFixedExtentHeight( 100 ); + dw->show(); +} + +void MainWindow::setupActionEditor() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::OutsideDock, this, 0 ); + addDockWindow( dw, Qt::DockTornOff ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + actionEditor = new ActionEditor( dw ); + dw->setWidget( actionEditor ); + actionEditor->show(); + dw->setCaption( tr( "Action Editor" ) ); + QWhatsThis::add( actionEditor, tr("The Action Editor" + "

The Action Editor is used to add actions and action groups to " + "a form, and to connect actions to slots. Actions and action " + "groups can be dragged into menus and into toolbars, and may " + "feature keyboard shortcuts and tooltips. If actions have pixmaps " + "these are displayed on toolbar buttons and besides their names in " + "menus.

" ) ); + dw->hide(); + setAppropriate( dw, FALSE ); +} + +void MainWindow::setupToolbox() +{ + QDockWindow *dw = new QDockWindow( QDockWindow::InDock, this ); + dw->setResizeEnabled( TRUE ); + dw->setCloseMode( QDockWindow::Always ); + addToolBar( dw, Qt::DockLeft ); + toolBox = new QToolBox( dw ); + dw->setWidget( toolBox ); + dw->setFixedExtentWidth( 160 ); + dw->setCaption( tr( "Toolbox" ) ); + dw->show(); + setDockEnabled( dw, Qt::DockTop, FALSE ); + setDockEnabled( dw, Qt::DockBottom, FALSE ); + commonWidgetsToolBar = new QToolBar( "Common Widgets", 0, toolBox, FALSE, "Common Widgets" ); + commonWidgetsToolBar->setFrameStyle( QFrame::NoFrame ); + commonWidgetsToolBar->setOrientation( Qt::Vertical ); + commonWidgetsToolBar->setBackgroundMode(PaletteBase); + toolBox->addItem( commonWidgetsToolBar, "Common Widgets" ); +} + +void MainWindow::setupRMBMenus() +{ + rmbWidgets = new QPopupMenu( this ); + actionEditCut->addTo( rmbWidgets ); + actionEditCopy->addTo( rmbWidgets ); + actionEditPaste->addTo( rmbWidgets ); + actionEditDelete->addTo( rmbWidgets ); +#if 0 + rmbWidgets->insertSeparator(); + actionEditLower->addTo( rmbWidgets ); + actionEditRaise->addTo( rmbWidgets ); +#endif + rmbWidgets->insertSeparator(); + actionEditAdjustSize->addTo( rmbWidgets ); + actionEditHLayout->addTo( rmbWidgets ); + actionEditVLayout->addTo( rmbWidgets ); + actionEditGridLayout->addTo( rmbWidgets ); + actionEditSplitHorizontal->addTo( rmbWidgets ); + actionEditSplitVertical->addTo( rmbWidgets ); + actionEditBreakLayout->addTo( rmbWidgets ); + rmbWidgets->insertSeparator(); + if ( !singleProjectMode() ) + actionEditConnections->addTo( rmbWidgets ); + actionEditSource->addTo( rmbWidgets ); + + rmbFormWindow = new QPopupMenu( this ); + actionEditPaste->addTo( rmbFormWindow ); + actionEditSelectAll->addTo( rmbFormWindow ); + actionEditAccels->addTo( rmbFormWindow ); + rmbFormWindow->insertSeparator(); + actionEditAdjustSize->addTo( rmbFormWindow ); + actionEditHLayout->addTo( rmbFormWindow ); + actionEditVLayout->addTo( rmbFormWindow ); + actionEditGridLayout->addTo( rmbFormWindow ); + actionEditBreakLayout->addTo( rmbFormWindow ); + rmbFormWindow->insertSeparator(); + if ( !singleProjectMode() ) { + actionEditFunctions->addTo( rmbFormWindow ); + actionEditConnections->addTo( rmbFormWindow ); + } + actionEditSource->addTo( rmbFormWindow ); + rmbFormWindow->insertSeparator(); + actionEditFormSettings->addTo( rmbFormWindow ); +} + +void MainWindow::toolSelected( QAction* action ) +{ + actionCurrentTool = action; + emit currentToolChanged(); + if ( formWindow() ) + formWindow()->commandHistory()->emitUndoRedo(); +} + +int MainWindow::currentTool() const +{ + if ( !actionCurrentTool ) + return POINTER_TOOL; + return QString::fromLatin1(actionCurrentTool->name()).toInt(); +} + +void MainWindow::runProjectPrecondition() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + e->save(); + e->saveBreakPoints(); + } + fileSaveProject(); + + if ( currentTool() == ORDER_TOOL ) + resetTool(); + oWindow->clearErrorMessages(); + oWindow->clearDebug(); + oWindow->showDebugTab(); + previewing = TRUE; +} + +void MainWindow::runProjectPostcondition( QObjectList *l ) +{ + inDebugMode = TRUE; + debuggingForms = *l; + enableAll( FALSE ); + for ( SourceEditor *e2 = sourceEditors.first(); e2; e2 = sourceEditors.next() ) { + if ( e2->project() == currentProject ) + e2->editorInterface()->setMode( EditorInterface::Debugging ); + } +} + +QWidget* MainWindow::previewFormInternal( QStyle* style, QPalette* palet ) +{ + qwf_execute_code = FALSE; + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->save(); + if ( currentTool() == ORDER_TOOL ) + resetTool(); + + FormWindow *fw = formWindow(); + if ( !fw ) + return 0; + + QStringList databases; + QPtrDictIterator wit( *fw->widgets() ); + while ( wit.current() ) { + QStringList lst = MetaDataBase::fakeProperty( wit.current(), "database" ).toStringList(); + if ( !lst.isEmpty() ) + databases << lst [ 0 ]; + ++wit; + } + + if ( fw->project() ) { + QStringList::ConstIterator it; + for ( it = databases.begin(); it != databases.end(); ++it ) + fw->project()->openDatabase( *it, FALSE ); + } + QApplication::setOverrideCursor( WaitCursor ); + + QCString s; + QBuffer buffer( s ); + buffer.open( IO_WriteOnly ); + Resource resource( this ); + resource.setWidget( fw ); + QValueList images; + resource.save( &buffer ); + + buffer.close(); + buffer.open( IO_ReadOnly ); + + QWidget *w = QWidgetFactory::create( &buffer ); + if ( w ) { + previewedForm = w; + if ( palet ) { + if ( style ) + style->polish( *palet ); + w->setPalette( *palet ); + } + + if ( style ) + w->setStyle( style ); + + QObjectList *l = w->queryList( "QWidget" ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( style ) + ( (QWidget*)o )->setStyle( style ); + } + delete l; + + w->move( fw->mapToGlobal( QPoint(0,0) ) ); + ((MainWindow*)w )->setWFlags( WDestructiveClose ); + previewing = TRUE; + w->show(); + previewing = FALSE; + QApplication::restoreOverrideCursor(); + return w; + } + QApplication::restoreOverrideCursor(); + return 0; +} + +void MainWindow::previewForm() +{ + QWidget* w = previewFormInternal(); + if ( w ) + w->show(); +} + +void MainWindow::previewForm( const QString & style ) +{ + QStyle* st = QStyleFactory::create( style ); + QWidget* w = 0; + if ( style == "Motif" ) { + QPalette p( QColor( 192, 192, 192 ) ); + w = previewFormInternal( st, &p ); + } else if ( style == "Windows" ) { + QPalette p( QColor( 212, 208, 200 ) ); + w = previewFormInternal( st, &p ); + } else if ( style == "Platinum" ) { + QPalette p( QColor( 220, 220, 220 ) ); + w = previewFormInternal( st, &p ); + } else if ( style == "CDE" ) { + QPalette p( QColor( 75, 123, 130 ) ); + p.setColor( QPalette::Active, QColorGroup::Base, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Inactive, QColorGroup::Base, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Disabled, QColorGroup::Base, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Active, QColorGroup::Highlight, Qt::white ); + p.setColor( QPalette::Active, QColorGroup::HighlightedText, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Inactive, QColorGroup::Highlight, Qt::white ); + p.setColor( QPalette::Inactive, QColorGroup::HighlightedText, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Disabled, QColorGroup::Highlight, Qt::white ); + p.setColor( QPalette::Disabled, QColorGroup::HighlightedText, QColor( 55, 77, 78 ) ); + p.setColor( QPalette::Active, QColorGroup::Foreground, Qt::white ); + p.setColor( QPalette::Active, QColorGroup::Text, Qt::white ); + p.setColor( QPalette::Active, QColorGroup::ButtonText, Qt::white ); + p.setColor( QPalette::Inactive, QColorGroup::Foreground, Qt::white ); + p.setColor( QPalette::Inactive, QColorGroup::Text, Qt::white ); + p.setColor( QPalette::Inactive, QColorGroup::ButtonText, Qt::white ); + p.setColor( QPalette::Disabled, QColorGroup::Foreground, Qt::lightGray ); + p.setColor( QPalette::Disabled, QColorGroup::Text, Qt::lightGray ); + p.setColor( QPalette::Disabled, QColorGroup::ButtonText, Qt::lightGray ); + + w = previewFormInternal( st, &p ); + } else if ( style == "SGI" ) { + QPalette p( QColor( 220, 220, 220 ) ); + w = previewFormInternal( st, &p ); + } else if ( style == "MotifPlus" ) { + QColor gtkfg(0x00, 0x00, 0x00); + QColor gtkdf(0x75, 0x75, 0x75); + QColor gtksf(0xff, 0xff, 0xff); + QColor gtkbs(0xff, 0xff, 0xff); + QColor gtkbg(0xd6, 0xd6, 0xd6); + QColor gtksl(0x00, 0x00, 0x9c); + QColorGroup active(gtkfg, // foreground + gtkbg, // button + gtkbg.light(), // light + gtkbg.dark(142), // dark + gtkbg.dark(110), // mid + gtkfg, // text + gtkfg, // bright text + gtkbs, // base + gtkbg), // background + disabled(gtkdf, // foreground + gtkbg, // button + gtkbg.light(), // light + gtkbg.dark(156), // dark + gtkbg.dark(110), // mid + gtkdf, // text + gtkdf, // bright text + gtkbs, // base + gtkbg); // background + + QPalette pal(active, disabled, active); + + pal.setColor(QPalette::Active, QColorGroup::Highlight, + gtksl); + pal.setColor(QPalette::Active, QColorGroup::HighlightedText, + gtksf); + pal.setColor(QPalette::Inactive, QColorGroup::Highlight, + gtksl); + pal.setColor(QPalette::Inactive, QColorGroup::HighlightedText, + gtksf); + pal.setColor(QPalette::Disabled, QColorGroup::Highlight, + gtksl); + pal.setColor(QPalette::Disabled, QColorGroup::HighlightedText, + gtkdf); + w = previewFormInternal( st, &pal ); + } else { + w = previewFormInternal( st ); + } + + if ( !w ) + return; + w->insertChild( st ); + w->show(); +} + +void MainWindow::helpContents() +{ + QWidget *focusWidget = qApp->focusWidget(); + bool showClassDocu = TRUE; + while ( focusWidget ) { + if ( focusWidget->isA( "PropertyList" ) ) { + showClassDocu = FALSE; + break; + } + focusWidget = focusWidget->parentWidget(); + } + + QString source = "designer-manual.html"; + if ( propertyDocumentation.isEmpty() ) { + QString indexFile = documentationPath() + "/propertyindex"; + QFile f( indexFile ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + while ( !ts.eof() ) { + QString s = ts.readLine(); + int from = s.find( "\"" ); + if ( from == -1 ) + continue; + int to = s.findRev( "\"" ); + if ( to == -1 ) + continue; + propertyDocumentation[ s.mid( from + 1, to - from - 1 ) ] = s.mid( to + 2 ) + "-prop"; + } + f.close(); + } + } + + if ( propertyEditor->widget() && !showClassDocu ) { + if ( !propertyEditor->currentProperty().isEmpty() ) { + QMetaObject* mo = propertyEditor->metaObjectOfCurrentProperty(); + QString s; + QString cp = propertyEditor->currentProperty(); + if ( cp == "layoutMargin" ) { + source = propertyDocumentation[ "QLayout/margin" ]; + } else if ( cp == "layoutSpacing" ) { + source = propertyDocumentation[ "QLayout/spacing" ]; + } else if ( cp == "toolTip" ) { + source = "qtooltip.html#details"; + } else if ( mo && qstrcmp( mo->className(), "Spacer" ) == 0 ) { + if ( cp != "name" ) + source = "qsizepolicy.html#SizeType"; + else + source = propertyDocumentation[ "QObject/name" ]; + } else { + while ( mo && !propertyDocumentation.contains( ( s = QString( mo->className() ) + "/" + cp ) ) ) + mo = mo->superClass(); + if ( mo ) + source = "p:" + propertyDocumentation[s]; + } + } + + QString classname = WidgetFactory::classNameOf( propertyEditor->widget() ); + if ( source.isEmpty() || source == "designer-manual.html" ) { + if ( classname.lower() == "spacer" ) + source = "qspaceritem.html#details"; + else if ( classname == "QLayoutWidget" ) + source = "layout.html"; + else + source = QString( WidgetFactory::classNameOf( propertyEditor->widget() ) ).lower() + ".html#details"; + } + } else if ( propertyEditor->widget() ) { + source = QString( WidgetFactory::classNameOf( propertyEditor->widget() ) ).lower() + ".html#details"; + } + + if ( !source.isEmpty() ) + assistant->showPage( documentationPath() + source ); +} + +void MainWindow::helpManual() +{ + assistant->showPage( documentationPath() + "/designer-manual.html" ); +} + +void MainWindow::helpAbout() +{ + AboutDialog dlg( this, 0, TRUE ); + if ( singleProjectMode() ) { + dlg.aboutPixmap->setText( "" ); + dlg.aboutVersion->setText( "" ); + dlg.aboutCopyright->setText( "" ); + LanguageInterface *iface = MetaDataBase::languageInterface( eProject->language() ); + dlg.aboutLicense->setText( iface->aboutText() ); + } + dlg.aboutVersion->setText(QString("Version ") + QString(QT_VERSION_STR)); + dlg.resize( dlg.width(), dlg.layout()->heightForWidth(dlg.width()) ); + dlg.exec(); +} + +void MainWindow::helpAboutQt() +{ + QMessageBox::aboutQt( this, "Qt Designer" ); +} + +#if defined(_WS_WIN_) +#include +#include +#endif + +void MainWindow::helpRegister() +{ +#if defined(_WS_WIN_) + HKEY key; + HKEY subkey; + long res; + DWORD type; + DWORD size = 255; + QString command; + QString sub( "htmlfile\\shell" ); +#if defined(UNICODE) + if ( QApplication::winVersion() & Qt::WV_NT_based ) { + unsigned char data[256]; + res = RegOpenKeyExW( HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &key ); + res = RegOpenKeyExW( key, (TCHAR*)sub.ucs2(), 0, KEY_READ, &subkey ); + res = RegQueryValueExW( subkey, NULL, NULL, &type, data, &size ); + command = qt_winQString( data ) + "\\command"; + size = 255; + res = RegOpenKeyExW( subkey, (TCHAR*)command.ucs2(), 0, KEY_READ, &subkey ); + res = RegQueryValueExW( subkey, NULL, NULL, &type, data, &size ); + command = qt_winQString( data ); + } else +#endif + { + unsigned char data[256]; + res = RegOpenKeyExA( HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &key ); + res = RegOpenKeyExA( key, sub.local8Bit(), 0, KEY_READ, &subkey ); + res = RegQueryValueExA( subkey, NULL, NULL, &type, data, &size ); + command = QString::fromLocal8Bit( (const char*) data ) + "\\command"; + size = 255; + res = RegOpenKeyExA( subkey, command.local8Bit(), 0, KEY_READ, &subkey ); + res = RegQueryValueExA( subkey, NULL, NULL, &type, data, &size ); + command = QString::fromLocal8Bit( (const char*) data ); + } + + res = RegCloseKey( subkey ); + res = RegCloseKey( key ); + + QProcess process( command + " www.trolltech.com/products/download/eval/evaluation.html" ); + if ( !process.start() ) + QMessageBox::information( this, "Register Qt", "Launching your web browser failed.\n" + "To register Qt, point your browser to www.trolltech.com/products/download/eval/evaluation.html" ); +#endif +} + +void MainWindow::showProperties( QObject *o ) +{ + if ( !o->isWidgetType() ) { + propertyEditor->setWidget( o, lastActiveFormWindow ); + if ( lastActiveFormWindow ) + hierarchyView->setFormWindow( lastActiveFormWindow, lastActiveFormWindow->mainContainer() ); + else + hierarchyView->setFormWindow( 0, 0 ); + return; + } + QWidget *w = (QWidget*)o; + setupHierarchyView(); + FormWindow *fw = (FormWindow*)isAFormWindowChild( w ); + if ( fw ) { + if ( fw->numSelectedWidgets() > 1 ) { + QWidgetList wl = fw->selectedWidgets(); + if ( wl.first() != w ) { + wl.removeRef( w ); + wl.insert( 0, w ); + } + propertyEditor->setWidget( new PropertyObject( wl ), fw ); + } else { + propertyEditor->setWidget( w, fw ); + } + hierarchyView->setFormWindow( fw, w ); + } else { + propertyEditor->setWidget( 0, 0 ); + hierarchyView->setFormWindow( 0, 0 ); + } + + if ( currentTool() == POINTER_TOOL && fw && + ( !qworkspace->activeWindow() || !::qt_cast(qworkspace->activeWindow()) ) ) + fw->setFocus(); +} + +void MainWindow::resetTool() +{ + actionPointerTool->setOn( TRUE ); +} + +void MainWindow::updateProperties( QObject * ) +{ + if ( propertyEditor ) + propertyEditor->refetchData(); +} + +bool MainWindow::eventFilter( QObject *o, QEvent *e ) +{ + if ( ::qt_cast(o) || ::qt_cast(o) || + ( o && + ( ::qt_cast(o->parent()) || + ::qt_cast(o->parent()) ) ) ) { + + if ( e->type() == QEvent::Accel && ::qt_cast(o) ) { + return TRUE; // consume accel events + } else if ( e->type() == QEvent::MouseButtonPress && ::qt_cast(o) ) { + QPoint pos = ((QMouseEvent*)e)->pos(); + MenuBarEditor *m = ::qt_cast(o); + showProperties( o ); + if ( m->findItem( pos ) >= m->count() ) + m->setFocus(); + } else if ( e->type() == QEvent::MouseButtonPress && ::qt_cast(o) ) { + PopupMenuEditor *m = ::qt_cast(o); + PopupMenuEditorItem *i = m->at( ((QMouseEvent*)e)->pos() ); + if ( m->find( i->action() ) != -1 && !i->isSeparator() ) + showProperties( i->action() ); + } + return QMainWindow::eventFilter( o, e ); + } + + if ( !o || !e || !o->isWidgetType() ) + return QMainWindow::eventFilter( o, e ); + + QWidget *w = 0; + bool passiveInteractor; + switch ( e->type() ) { + case QEvent::AccelOverride: + if ( ( (QKeyEvent*)e )->key() == Key_F1 && + ( ( (QKeyEvent*)e )->state() & ShiftButton ) != ShiftButton ) { + w = (QWidget*)o; + while ( w ) { + if ( ::qt_cast(w) ) + break; + w = w->parentWidget( TRUE ); + } + if ( w ) { + propertyEditor->propertyList()->showCurrentWhatsThis(); + ( (QKeyEvent*)e )->accept(); + return TRUE; + } + } + break; + case QEvent::Accel: + if ( ( ( (QKeyEvent*)e )->key() == Key_A || + ( (QKeyEvent*)e )->key() == Key_E ) && + ( (QKeyEvent*)e )->state() & ControlButton ) { + if ( qWorkspace()->activeWindow() && + ::qt_cast(qWorkspace()->activeWindow()) ) { + ( (QKeyEvent*)e )->ignore(); + return TRUE; + } + } + break; + case QEvent::ContextMenu: + case QEvent::MouseButtonPress: + if ( o && currentTool() == POINTER_TOOL && + ( ::qt_cast(o) || + ::qt_cast(o) || + ::qt_cast(o) || + ( ::qt_cast(o) || + ::qt_cast(o) || + ::qt_cast(o) ) && + o->parent() + && ( ::qt_cast(o->parent()) + || ::qt_cast(o->parent())) ) ) { + QWidget *w = (QWidget*)o; + if ( ::qt_cast(w) || + ::qt_cast(w) || + ::qt_cast(w) || + ::qt_cast(w) ) + w = w->parentWidget(); + QWidget *pw = w->parentWidget(); + while ( pw ) { + if ( ::qt_cast(pw) ) { + ( (FormWindow*)pw )->emitShowProperties( w ); + if ( !::qt_cast(o) ) + return ( !::qt_cast(o) && + !::qt_cast(o) && + !::qt_cast(o) && + !::qt_cast(o) ); + } + pw = pw->parentWidget(); + } + } + if ( o && ( ::qt_cast(o) || o->inherits("QDockWindowHandle") ) + && e->type() == QEvent::ContextMenu ) + break; + if ( isAToolBarChild( o ) && currentTool() != CONNECT_TOOL && currentTool() != BUDDY_TOOL ) + break; + if ( ::qt_cast(o) ) + break; + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) ) + break; + if ( !w->hasFocus() ) + w->setFocus(); + passiveInteractor = WidgetFactory::isPassiveInteractor( o ); + if ( !passiveInteractor || currentTool() != ORDER_TOOL ) { + if( e->type() == QEvent::ContextMenu ) { + ( (FormWindow*)w )->handleContextMenu( (QContextMenuEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + return TRUE; + } else { + ( (FormWindow*)w )->handleMousePress( (QMouseEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + } + } + lastPressWidget = (QWidget*)o; + if ( passiveInteractor ) + QTimer::singleShot( 0, formWindow(), SLOT( visibilityChanged() ) ); + if ( currentTool() == CONNECT_TOOL || currentTool() == BUDDY_TOOL ) + return TRUE; + return !passiveInteractor; + case QEvent::MouseButtonRelease: + lastPressWidget = 0; + if ( isAToolBarChild( o ) && currentTool() != CONNECT_TOOL && currentTool() != BUDDY_TOOL ) + break; + if ( ::qt_cast(o) ) + break; + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) ) + break; + passiveInteractor = WidgetFactory::isPassiveInteractor( o ); + if ( !passiveInteractor ) + ( (FormWindow*)w )->handleMouseRelease( (QMouseEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + if ( passiveInteractor ) { + QTimer::singleShot( 0, this, SLOT( selectionChanged() ) ); + QTimer::singleShot( 0, formWindow(), SLOT( visibilityChanged() ) ); + } + return !passiveInteractor; + case QEvent::MouseMove: + if ( isAToolBarChild( o ) && currentTool() != CONNECT_TOOL && currentTool() != BUDDY_TOOL ) + break; + w = isAFormWindowChild( o ); + if ( lastPressWidget != (QWidget*)o && w && + !::qt_cast(o) && !::qt_cast(o) && + !::qt_cast(o) && !::qt_cast(o) && + !::qt_cast(o) ) + return TRUE; + if ( o && ::qt_cast(o) ) + break; + if ( lastPressWidget != (QWidget*)o || + ( !w || ::qt_cast(o) ) || + ::qt_cast(o) ) + break; + passiveInteractor = WidgetFactory::isPassiveInteractor( o ); + if ( !passiveInteractor ) + ( (FormWindow*)w )->handleMouseMove( (QMouseEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + return !passiveInteractor; + case QEvent::KeyPress: + if ( ( (QKeyEvent*)e )->key() == Key_Escape && currentTool() != POINTER_TOOL ) { + resetTool(); + return FALSE; + } + if ( ( (QKeyEvent*)e )->key() == Key_Escape && incrementalSearch->hasFocus() ) { + if ( ::qt_cast(qWorkspace()->activeWindow()) ) { + qWorkspace()->activeWindow()->setFocus(); + return TRUE; + } + } + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) ) + break; + ( (FormWindow*)w )->handleKeyPress( (QKeyEvent*)e, ( (FormWindow*)w )->designerWidget( o ) ); + if ( ((QKeyEvent*)e)->isAccepted() ) + return TRUE; + break; + case QEvent::MouseButtonDblClick: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) ) { + if ( ::qt_cast(o) && ((QToolButton*)o)->isOn() && + o->parent() && ::qt_cast(o->parent()) && formWindow() ) + formWindow()->setToolFixed(); + break; + } + if ( currentTool() == ORDER_TOOL ) { + ( (FormWindow*)w )->handleMouseDblClick( (QMouseEvent*)e, + ( (FormWindow*)w )->designerWidget( o ) ); + return TRUE; + } + if ( !WidgetFactory::isPassiveInteractor( o ) && ( (FormWindow*)w )->formFile() ) + return openEditor( ( (FormWindow*)w )->designerWidget( o ), (FormWindow*)w ); + return TRUE; + case QEvent::KeyRelease: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) ) + break; + ( (FormWindow*)w )->handleKeyRelease( (QKeyEvent*)e, ( (FormWindow*)w )->designerWidget( o ) ); + if ( ((QKeyEvent*)e)->isAccepted() ) + return TRUE; + break; + case QEvent::Hide: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) ) + break; + if ( ( (FormWindow*)w )->isWidgetSelected( (QWidget*)o ) ) + ( (FormWindow*)w )->selectWidget( (QWidget*)o, FALSE ); + break; + case QEvent::Enter: + case QEvent::Leave: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) || + ::qt_cast(o) ) + break; + return TRUE; + case QEvent::Resize: + case QEvent::Move: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) ) + break; + if ( WidgetFactory::layoutType( (QWidget*)o->parent() ) != WidgetFactory::NoLayout ) { + ( (FormWindow*)w )->updateSelection( (QWidget*)o ); + if ( e->type() != QEvent::Resize ) + ( (FormWindow*)w )->updateChildSelections( (QWidget*)o ); + } + break; + case QEvent::Close: + if ( o->isWidgetType() && (QWidget*)o == (QWidget*)previewedForm ) { + if ( lastActiveFormWindow && lastActiveFormWindow->project() ) { + QStringList lst = + MetaDataBase::fakeProperty( lastActiveFormWindow, "database" ).toStringList(); + lastActiveFormWindow->project()->closeDatabase( lst[ 0 ] ); + } + } + break; + case QEvent::DragEnter: + if ( o == qWorkspace() || o == workspace() || o == workspace()->viewport() ) { + workspace()->contentsDragEnterEvent( (QDragEnterEvent*)e ); + return TRUE; + } + break; + case QEvent::DragMove: + if ( o == qWorkspace() || o == workspace() || o == workspace()->viewport() ) { + workspace()->contentsDragMoveEvent( (QDragMoveEvent*)e ); + return TRUE; + } + break; + case QEvent::Drop: + if ( o == qWorkspace() || o == workspace() || o == workspace()->viewport() ) { + workspace()->contentsDropEvent( (QDropEvent*)e ); + return TRUE; + } + break; + case QEvent::Show: + if ( o != this ) + break; + if ( ((QShowEvent*)e)->spontaneous() ) + break; + QApplication::sendPostedEvents( qworkspace, QEvent::ChildInserted ); + showEvent( (QShowEvent*)e ); + checkTempFiles(); + return TRUE; + case QEvent::Wheel: + if ( !( w = isAFormWindowChild( o ) ) || + ::qt_cast(o) || + ::qt_cast(o) ) + break; + return TRUE; + case QEvent::FocusIn: + if ( !::qt_cast(o) && isAFormWindowChild( o ) ) + return TRUE; //FIXME + if ( hierarchyView->formDefinitionView()->isRenaming() + && ( o->inherits( "Editor" ) || ::qt_cast(o) ) ) + QApplication::sendPostedEvents(); + if ( o->inherits( "Editor" ) ) { + QWidget *w = (QWidget*)o; + while ( w ) { + if ( ::qt_cast(w) ) + break; + w = w->parentWidget( TRUE ); + } + if ( ::qt_cast(w) ) + ( (SourceEditor*)w )->checkTimeStamp(); + } else if ( ::qt_cast(o) ) { + FormWindow *fw = (FormWindow*)o; + if ( fw->formFile() && fw->formFile()->editor() ) + fw->formFile()->editor()->checkTimeStamp(); + } + break; + case QEvent::FocusOut: + if ( !::qt_cast(o) && isAFormWindowChild( o ) ) + return TRUE; + break; + default: + return QMainWindow::eventFilter( o, e ); + } + + return QMainWindow::eventFilter( o, e ); +} + +QWidget *MainWindow::isAFormWindowChild( QObject *o ) const +{ + if ( ::qt_cast(o->parent()) && !::qt_cast(o) ) + return 0; + while ( o ) { + if ( ::qt_cast(o) ) + return (QWidget*)o; + o = o->parent(); + } + return 0; +} + +QWidget *MainWindow::isAToolBarChild( QObject *o ) const +{ + while ( o ) { + if ( ::qt_cast(o) ) + return (QWidget*)o; + if ( ::qt_cast(o) ) + return 0; + o = o->parent(); + } + return 0; +} + +FormWindow *MainWindow::formWindow() +{ + if ( qworkspace->activeWindow() ) { + FormWindow *fw = 0; + if ( ::qt_cast(qworkspace->activeWindow()) ) + fw = (FormWindow*)qworkspace->activeWindow(); + else if ( lastActiveFormWindow && + qworkspace->windowList().find( lastActiveFormWindow ) != -1) + fw = lastActiveFormWindow; + return fw; + } + return 0; +} + +void MainWindow::emitProjectSignals() +{ + emit hasNonDummyProject( !currentProject->isDummy() ); + emit hasActiveWindowOrProject( !!qworkspace->activeWindow() || !currentProject->isDummy() ); +} + +void MainWindow::insertFormWindow( FormWindow *fw ) +{ + if ( fw ) + QWhatsThis::add( fw, tr( "The Form Window" + "

Use the various tools to add widgets or to change the layout " + "and behavior of the components in the form. Select one or multiple " + "widgets to move them or lay them out. If a single widget is chosen it can " + "be resized using the resize handles.

" + "

Changes in the Property Editor are visible at design time, " + "and you can preview the form in different styles.

" + "

You can change the grid resolution, or turn the grid off in the " + "Preferences dialog in the Edit menu." + "

You can have several forms open, and all open forms are listed " + "in the Form List.") ); + + connect( fw, SIGNAL( showProperties( QObject * ) ), + this, SLOT( showProperties( QObject * ) ) ); + connect( fw, SIGNAL( updateProperties( QObject * ) ), + this, SLOT( updateProperties( QObject * ) ) ); + connect( this, SIGNAL( currentToolChanged() ), + fw, SLOT( currentToolChanged() ) ); + connect( fw, SIGNAL( selectionChanged() ), + this, SLOT( selectionChanged() ) ); + connect( fw, SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ), + this, SLOT( updateUndoRedo( bool, bool, const QString &, const QString & ) ) ); + + if ( !mblockNewForms ) { + } else { + fw->setProject( currentProject ); + } + fw->show(); + fw->currentToolChanged(); + if ( fw->caption().isEmpty() && qstrlen( fw->name() ) ) + fw->setCaption( fw->name() ); + fw->mainContainer()->setCaption( fw->caption() ); + WidgetFactory::saveDefaultProperties( fw->mainContainer(), + WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( fw->mainContainer() ) ) ); + activeWindowChanged( fw ); + emit formWindowsChanged(); + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->project() == fw->project() ) + e->resetContext(); + } +} + +void MainWindow::createNewProject( const QString &lang ) +{ + Project *pro = new Project( "", "", projectSettingsPluginManager ); + pro->setLanguage( lang ); + + + if ( !openProjectSettings( pro ) ) { + delete pro; + return; + } + + if ( !pro->isValid() ) { + QMessageBox::information( this, tr("New Project"), tr( "Cannot create an invalid project." ) ); + delete pro; + return; + } + + QAction *a = new QAction( pro->makeRelative( pro->fileName() ), + pro->makeRelative( pro->fileName() ), 0, actionGroupProjects, 0, TRUE ); + projects.insert( a, pro ); + addRecentlyOpened( pro->makeAbsolute( pro->fileName() ), recentlyProjects ); + projectSelected( a ); +} + + +bool MainWindow::unregisterClient( FormWindow *w ) +{ + propertyEditor->closed( w ); + objectHierarchy()->closed( w ); + if ( w == lastActiveFormWindow ) + lastActiveFormWindow = 0; + + QPtrList waitingForDelete; + waitingForDelete.setAutoDelete( TRUE ); + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->object() == w ) + waitingForDelete.append( e ); + } + + if ( actionEditor->form() == w ) { + actionEditor->setFormWindow( 0 ); + actionEditor->parentWidget()->hide(); + } + + return TRUE; +} + +void MainWindow::activeWindowChanged( QWidget *w ) +{ + QWidget *old = formWindow(); + if ( ::qt_cast(w) ) { + FormWindow *fw = (FormWindow*)w; + FormWindow *ofw = lastActiveFormWindow; + lastActiveFormWindow = fw; + lastActiveFormWindow->updateUndoInfo(); + emit hasActiveForm( TRUE ); + if ( formWindow() ) { + formWindow()->emitShowProperties(); + emit formModified( formWindow()->commandHistory()->isModified() ); + if ( currentTool() != POINTER_TOOL ) + formWindow()->clearSelection(); + } + workspace()->activeFormChanged( fw ); + setAppropriate( (QDockWindow*)actionEditor->parentWidget(), + ::qt_cast(lastActiveFormWindow->mainContainer()) ); + if ( appropriate( (QDockWindow*)actionEditor->parentWidget() ) ) { + if ( actionEditor->wantToBeShown() ) + actionEditor->parentWidget()->show(); + } else { + QWidget *mc = 0; + if ( ofw && (mc = ofw->mainContainer()) && ::qt_cast(mc) ) + actionEditor->setWantToBeShown( !actionEditor->parentWidget()->isHidden() ); + actionEditor->parentWidget()->hide(); + } + + actionEditor->setFormWindow( lastActiveFormWindow ); + if ( wspace && fw->project() && fw->project() != currentProject ) { + for ( QMap::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( *it == fw->project() ) { + projectSelected( it.key() ); + break; + } + } + } + emit formWindowChanged(); + + } else if ( w == propertyEditor ) { + propertyEditor->resetFocus(); + } else if ( !lastActiveFormWindow ) { + emit formWindowChanged(); + emit hasActiveForm( FALSE ); + actionEditUndo->setEnabled( FALSE ); + actionEditRedo->setEnabled( FALSE ); + } + + if ( !w ) { + emit formWindowChanged(); + emit hasActiveForm( FALSE ); + propertyEditor->clear(); + hierarchyView->clear(); + updateUndoRedo( FALSE, FALSE, QString::null, QString::null ); + } + + selectionChanged(); + + if ( ::qt_cast(w) ) { + SourceEditor *se = (SourceEditor*)w; + QGuardedPtr fw = se->formWindow(); + if ( se->formWindow() && + lastActiveFormWindow != fw ) { + activeWindowChanged( se->formWindow() ); + } + actionSearchFind->setEnabled( TRUE ); + actionSearchIncremetal->setEnabled( TRUE ); + actionSearchReplace->setEnabled( TRUE ); + actionSearchGotoLine->setEnabled( TRUE ); + incrementalSearch->setEnabled( TRUE ); + + actionEditUndo->setEnabled( FALSE ); + actionEditRedo->setEnabled( FALSE ); + actionEditCut->setEnabled( TRUE ); + actionEditCopy->setEnabled( TRUE ); + // actionEditPaste will be updated by calling clipboardChanged() + actionEditSelectAll->setEnabled( TRUE ); + actionEditUndo->setMenuText( tr( "&Undo" ) ); + actionEditUndo->setToolTip( textNoAccel( actionEditUndo->menuText()) ); + actionEditRedo->setMenuText( tr( "&Redo" ) ); + actionEditRedo->setToolTip( textNoAccel( actionEditRedo->menuText()) ); + if ( hierarchyView->sourceEditor() != w ) + hierarchyView->showClasses( se ); + actionEditor->setFormWindow( 0 ); + if ( wspace && se->project() && se->project() != currentProject ) { + for ( QMap::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( *it == se->project() ) { + projectSelected( it.key() ); + break; + } + } + } + workspace()->activeEditorChanged( se ); + } else { + actionSearchFind->setEnabled( FALSE ); + actionSearchIncremetal->setEnabled( FALSE ); + actionSearchReplace->setEnabled( FALSE ); + actionSearchGotoLine->setEnabled( FALSE ); + incrementalSearch->setEnabled( FALSE ); + } + + clipboardChanged(); // update actionEditPaste + + if ( currentTool() == ORDER_TOOL && w != old ) + emit currentToolChanged(); + + emit hasActiveWindow( !!qworkspace->activeWindow() ); +} + +void MainWindow::updateUndoRedo( bool undoAvailable, bool redoAvailable, + const QString &undoCmd, const QString &redoCmd ) +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast(qWorkspace()->activeWindow()) ) + return; // do not set a formWindow related command + actionEditUndo->setEnabled( undoAvailable ); + actionEditRedo->setEnabled( redoAvailable ); + if ( !undoCmd.isEmpty() ) + actionEditUndo->setMenuText( tr( "&Undo: %1" ).arg( undoCmd ) ); + else + actionEditUndo->setMenuText( tr( "&Undo: Not Available" ) ); + if ( !redoCmd.isEmpty() ) + actionEditRedo->setMenuText( tr( "&Redo: %1" ).arg( redoCmd ) ); + else + actionEditRedo->setMenuText( tr( "&Redo: Not Available" ) ); + + actionEditUndo->setToolTip( textNoAccel( actionEditUndo->menuText()) ); + actionEditRedo->setToolTip( textNoAccel( actionEditRedo->menuText()) ); + + if ( currentTool() == ORDER_TOOL ) { + actionEditUndo->setEnabled( FALSE ); + actionEditRedo->setEnabled( FALSE ); + } +} + +void MainWindow::updateEditorUndoRedo() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast(qWorkspace()->activeWindow()) ) + return; + SourceEditor *editor = (SourceEditor*)qWorkspace()->activeWindow(); + actionEditUndo->setEnabled( editor->editIsUndoAvailable() ); + actionEditRedo->setEnabled( editor->editIsRedoAvailable() ); +} + +QWorkspace *MainWindow::qWorkspace() const +{ + return qworkspace; +} + +void MainWindow::popupFormWindowMenu( const QPoint & gp, FormWindow *fw ) +{ + QValueList ids; + QMap commands; + + setupRMBSpecialCommands( ids, commands, fw ); + setupRMBProperties( ids, commands, fw ); + + qApp->processEvents(); + int r = rmbFormWindow->exec( gp ); + + handleRMBProperties( r, commands, fw ); + handleRMBSpecialCommands( r, commands, fw ); + + for ( QValueList::ConstIterator i = ids.begin(); i != ids.end(); ++i ) + rmbFormWindow->removeItem( *i ); +} + +void MainWindow::popupWidgetMenu( const QPoint &gp, FormWindow * /*fw*/, QWidget * w) +{ + QValueList ids; + QMap commands; + + setupRMBSpecialCommands( ids, commands, w ); + setupRMBProperties( ids, commands, w ); + + qApp->processEvents(); + int r = rmbWidgets->exec( gp ); + + handleRMBProperties( r, commands, w ); + handleRMBSpecialCommands( r, commands, w ); + + for ( QValueList::ConstIterator i = ids.begin(); i != ids.end(); ++i ) + rmbWidgets->removeItem( *i ); +} + +void MainWindow::setupRMBProperties( QValueList &ids, QMap &props, QWidget *w ) +{ + const QMetaProperty* text = w->metaObject()->property( w->metaObject()->findProperty( "text", TRUE ), TRUE ); + if ( text && qstrcmp( text->type(), "QString") != 0 ) + text = 0; + const QMetaProperty* title = w->metaObject()->property( w->metaObject()->findProperty( "title", TRUE ), TRUE ); + if ( title && qstrcmp( title->type(), "QString") != 0 ) + title = 0; + const QMetaProperty* pagetitle = + w->metaObject()->property( w->metaObject()->findProperty( "pageTitle", TRUE ), TRUE ); + if ( pagetitle && qstrcmp( pagetitle->type(), "QString") != 0 ) + pagetitle = 0; + const QMetaProperty* pixmap = + w->metaObject()->property( w->metaObject()->findProperty( "pixmap", TRUE ), TRUE ); + if ( pixmap && qstrcmp( pixmap->type(), "QPixmap") != 0 ) + pixmap = 0; + + if ( text && text->designable(w) || + title && title->designable(w) || + pagetitle && pagetitle->designable(w) || + pixmap && pixmap->designable(w) ) { + int id = 0; + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator(0); + if ( pixmap && pixmap->designable(w) ) { + ids << ( id = rmbWidgets->insertItem( tr("Choose Pixmap..."), -1, 0) ); + props.insert( "pixmap", id ); + } + if ( text && text->designable(w) && !::qt_cast(w) ) { + ids << ( id = rmbWidgets->insertItem( tr("Edit Text..."), -1, 0) ); + props.insert( "text", id ); + } + if ( title && title->designable(w) ) { + ids << ( id = rmbWidgets->insertItem( tr("Edit Title..."), -1, 0) ); + props.insert( "title", id ); + } + if ( pagetitle && pagetitle->designable(w) ) { + ids << ( id = rmbWidgets->insertItem( tr("Edit Page Title..."), -1, 0) ); + props.insert( "pagetitle", id ); + } + } +} + +#ifdef QT_CONTAINER_CUSTOM_WIDGETS +static QWidgetContainerInterfacePrivate *containerWidgetInterface( QWidget *w ) +{ + WidgetInterface *iface = 0; + widgetManager()->queryInterface( WidgetFactory::classNameOf( w ), &iface ); + if ( !iface ) + return 0; + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( !iface2 ) + return 0; + iface->release(); + return iface2; +} +#endif + +void MainWindow::setupRMBSpecialCommands( QValueList &ids, + QMap &commands, QWidget *w ) +{ + int id; + + if ( ::qt_cast(w) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + if ( ( (QDesignerTabWidget*)w )->count() > 1) { + ids << ( id = rmbWidgets->insertItem( tr("Delete Page"), -1, 0 ) ); + commands.insert( "remove", id ); + } + ids << ( id = rmbWidgets->insertItem( tr("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); + } else if ( ::qt_cast(w) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + if ( ( (QDesignerWidgetStack*)w )->count() > 1) { + ids << ( id = rmbWidgets->insertItem( tr("Previous Page"), -1, 0 ) ); + commands.insert( "prevpage", id ); + ids << ( id = rmbWidgets->insertItem( tr("Next Page"), -1, 0 ) ); + ids << rmbWidgets->insertSeparator( 0 ); + commands.insert( "nextpage", id ); + ids << ( id = rmbWidgets->insertItem( tr("Delete Page"), -1, 0 ) ); + commands.insert( "remove", id ); + } + ids << ( id = rmbWidgets->insertItem( tr("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); + } else if ( ::qt_cast(w) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + if ( ( (QToolBox*)w )->count() > 1 ) { + ids << ( id = rmbWidgets->insertItem( tr("Delete Page"), -1, 0 ) ); + commands.insert( "remove", id ); + } + ids << ( id = rmbWidgets->insertItem( tr("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } else if ( WidgetDatabase:: + isCustomPluginWidget( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) { + QWidgetContainerInterfacePrivate *iface = containerWidgetInterface( w ); + if ( iface && iface->supportsPages( WidgetFactory::classNameOf( w ) ) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + + if ( iface->count( WidgetFactory::classNameOf( w ), w ) > 1 ) { + ids << ( id = rmbWidgets->insertItem( tr( "Delete Page" ), -1, 0 ) ); + commands.insert( "remove", id ); + } + ids << ( id = rmbWidgets->insertItem( tr("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); + if ( iface->currentIndex( WidgetFactory::classNameOf( w ), w ) != -1 ) { + ids << ( id = rmbWidgets->insertItem( tr("Rename Current Page..."), -1, 0 ) ); + commands.insert( "rename", id ); + } + } + if ( iface ) + iface->release(); +#endif // QT_CONTAINER_CUSTOM_WIDGETS + } + + if ( WidgetFactory::hasSpecialEditor( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ), w ) ) { + if ( ids.isEmpty() ) + ids << rmbWidgets->insertSeparator( 0 ); + ids << ( id = rmbWidgets->insertItem( tr("Edit..."), -1, 0 ) ); + commands.insert( "edit", id ); + } +} + +void MainWindow::setupRMBSpecialCommands( QValueList &ids, + QMap &commands, FormWindow *fw ) +{ + int id; + + if ( ::qt_cast(fw->mainContainer()) ) { + if ( ids.isEmpty() ) + ids << rmbFormWindow->insertSeparator( 0 ); + + if ( ( (QWizard*)fw->mainContainer() )->pageCount() > 1) { + ids << ( id = rmbFormWindow->insertItem( tr("Delete Page"), -1, 0 ) ); + commands.insert( "remove", id ); + } + + ids << ( id = rmbFormWindow->insertItem( tr("Add Page"), -1, 0 ) ); + commands.insert( "add", id ); + + ids << ( id = rmbFormWindow->insertItem( tr("Edit Page Title..."), -1, 0 ) ); + commands.insert( "rename", id ); + + ids << ( id = rmbFormWindow->insertItem( tr("Edit Pages..."), -1, 0 ) ); + commands.insert( "edit", id ); + + } else if ( ::qt_cast(fw->mainContainer()) ) { + if ( ids.isEmpty() ) + ids << rmbFormWindow->insertSeparator( 0 ); + ids << ( id = rmbFormWindow->insertItem( tr( "Add Menu Item" ), -1, 0 ) ); + commands.insert( "add_menu_item", id ); + ids << ( id = rmbFormWindow->insertItem( tr( "Add Toolbar" ), -1, 0 ) ); + commands.insert( "add_toolbar", id ); + } +} + +void MainWindow::handleRMBProperties( int id, QMap &props, QWidget *w ) +{ + if ( id == props[ "text" ] ) { + bool ok = FALSE; + bool oldDoWrap = FALSE; + if ( ::qt_cast(w) ) { + int align = w->property( "alignment" ).toInt(); + if ( align & WordBreak ) + oldDoWrap = TRUE; + } + bool doWrap = oldDoWrap; + + QString text; + if ( ::qt_cast(w) || ::qt_cast(w) || ::qt_cast(w) ) { + text = MultiLineEditor::getText( this, w->property( "text" ).toString(), !::qt_cast(w), &doWrap ); + ok = !text.isNull(); + } else { + text = QInputDialog::getText( tr("Text"), tr( "New text" ), + QLineEdit::Normal, w->property("text").toString(), &ok, this ); + } + if ( ok ) { + if ( oldDoWrap != doWrap ) { + QString pn( tr( "Set 'wordwrap' of '%1'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "wordwrap", QVariant( oldDoWrap, 0 ), + QVariant( doWrap, 0 ), QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "wordwrap", TRUE ); + } + + QString pn( tr( "Set the 'text' of '%1'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "text", w->property( "text" ), + text, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "text", TRUE ); + } + } else if ( id == props[ "title" ] ) { + bool ok = FALSE; + QString title = QInputDialog::getText( tr("Title"), tr( "New title" ), + QLineEdit::Normal, w->property("title").toString(), &ok, this ); + if ( ok ) { + QString pn( tr( "Set the 'title' of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "title", w->property( "title" ), + title, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "title", TRUE ); + } + } else if ( id == props[ "pagetitle" ] ) { + bool ok = FALSE; + QString text = QInputDialog::getText( tr("Page Title"), tr( "New page title" ), + QLineEdit::Normal, w->property("pageTitle").toString(), &ok, this ); + if ( ok ) { + QString pn( tr( "Set the 'pageTitle' of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "pageTitle", + w->property( "pageTitle" ), + text, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "pageTitle", TRUE ); + } + } else if ( id == props[ "pixmap" ] ) { + QPixmap oldPix = w->property( "pixmap" ).toPixmap(); + QPixmap pix = qChoosePixmap( this, formWindow(), oldPix ); + if ( !pix.isNull() ) { + QString pn( tr( "Set the 'pixmap' of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "pixmap", w->property( "pixmap" ), + pix, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "pixmap", TRUE ); + } + } +} + +void MainWindow::handleRMBSpecialCommands( int id, QMap &commands, QWidget *w ) +{ + if ( ::qt_cast(w) ) { + QTabWidget *tw = (QTabWidget*)w; + if ( id == commands[ "add" ] ) { + AddTabPageCommand *cmd = + new AddTabPageCommand( tr( "Add Page to %1" ).arg( tw->name() ), formWindow(), + tw, "Tab" ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + if ( tw->currentPage() ) { + QDesignerTabWidget *dtw = (QDesignerTabWidget*)tw; + DeleteTabPageCommand *cmd = + new DeleteTabPageCommand( tr( "Delete Page %1 of %2" ). + arg( dtw->pageTitle() ).arg( tw->name() ), + formWindow(), tw, tw->currentPage() ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } + } else if ( ::qt_cast(w) ) { + QToolBox *tb = (QToolBox*)w; + if ( id == commands[ "add" ] ) { + AddToolBoxPageCommand *cmd = + new AddToolBoxPageCommand( tr( "Add Page to %1" ).arg( tb->name() ), + formWindow(), + tb, "Page" ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + if ( tb->currentItem() ) { + DeleteToolBoxPageCommand *cmd = + new DeleteToolBoxPageCommand( tr( "Delete Page %1 of %2" ). + arg( tb->itemLabel( tb->currentIndex() ) ). + arg( tb->name() ), + formWindow(), tb, tb->currentItem() ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } + } else if ( ::qt_cast(w) ) { + QDesignerWidgetStack *ws = (QDesignerWidgetStack*)w; + if ( id == commands[ "add" ] ) { + AddWidgetStackPageCommand *cmd = + new AddWidgetStackPageCommand( tr( "Add Page to %1" ).arg( ws->name() ), + formWindow(), ws ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + if ( ws->visibleWidget() ) { + DeleteWidgetStackPageCommand *cmd = + new DeleteWidgetStackPageCommand( tr( "Delete Page %1 of %2" ). + arg( ws->currentPage() ).arg( ws->name() ), + formWindow(), ws, ws->visibleWidget() ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } else if ( id == commands[ "nextpage" ] ) { + int currentPage = w->property( "currentPage" ).toInt(); + QString pn( tr( "Raise next page of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = + new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "currentPage", currentPage, + currentPage + 1, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "currentPage", TRUE ); + } else if ( id == commands[ "prevpage" ] ) { + int currentPage = w->property( "currentPage" ).toInt(); + QString pn( tr( "Raise previous page of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = + new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "currentPage", currentPage, + currentPage -1, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "currentPage", TRUE ); + } +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } else if ( WidgetDatabase:: + isCustomPluginWidget( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ) ) ) { + if ( id == commands[ "add" ] ) { + AddContainerPageCommand *cmd = + new AddContainerPageCommand( tr( "Add Page to %1" ).arg( w->name() ), + formWindow(), w, "Page" ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + QWidgetContainerInterfacePrivate *iface = containerWidgetInterface( w ); + if ( iface ) { + QString wClassName = WidgetFactory::classNameOf( w ); + int index = iface->currentIndex( wClassName, w ); + DeleteContainerPageCommand *cmd = + new DeleteContainerPageCommand( tr( "Delete Page %1 of %2" ). + arg( iface->pageLabel( wClassName, + w, index ) ). + arg( w->name() ), + formWindow(), w, index ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + iface->release(); + } + } else if ( id == commands[ "rename" ] ) { + QWidgetContainerInterfacePrivate *iface = containerWidgetInterface( w ); + if ( iface ) { + bool ok = FALSE; + QString wClassName = WidgetFactory::classNameOf( w ); + int index = iface->currentIndex( wClassName, w ); + QString text = QInputDialog::getText( tr("Page Title"), tr( "New page title" ), + QLineEdit::Normal, + iface->pageLabel( wClassName, w, + index ), + &ok, this ); + if ( ok ) { + RenameContainerPageCommand *cmd = + new RenameContainerPageCommand( tr( "Rename Page %1 to %2" ). + arg( iface-> + pageLabel( wClassName, w, + index ) ). + arg( text ), formWindow(), + w, index, text ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + iface->release(); + } + } +#endif // QT_CONTAINER_CUSTOM_WIDGETS + } + + if ( WidgetFactory::hasSpecialEditor( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ), w ) ) { + if ( id == commands[ "edit" ] ) + WidgetFactory::editWidget( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ), this, w, formWindow() ); + } +} + +void MainWindow::handleRMBSpecialCommands( int id, QMap &commands, FormWindow *fw ) +{ + if ( ::qt_cast(fw->mainContainer()) ) { + QWizard *wiz = (QWizard*)fw->mainContainer(); + if ( id == commands[ "add" ] ) { + AddWizardPageCommand *cmd = + new AddWizardPageCommand( tr( "Add Page to %1" ).arg( wiz->name() ), + formWindow(), wiz, "WizardPage" ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "remove" ] ) { + if ( wiz->currentPage() ) { + QDesignerWizard *dw = (QDesignerWizard*)wiz; + DeleteWizardPageCommand *cmd = + new DeleteWizardPageCommand( tr( "Delete Page %1 of %2" ). + arg( dw->pageTitle() ).arg( wiz->name() ), + formWindow(), wiz, + wiz->indexOf( wiz->currentPage() ) ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } else if ( id == commands[ "edit" ] ) { + WizardEditor *e = new WizardEditor( this, wiz, fw ); + e->exec(); + delete e; + } else if ( id == commands[ "rename" ] ) { + + bool ok = FALSE; + QDesignerWizard *dw = (QDesignerWizard*)wiz; + QString text = QInputDialog::getText( tr("Page Title"), tr( "New page title" ), + QLineEdit::Normal, dw->pageTitle(), &ok, this ); + if ( ok ) { + QString pn( tr( "Rename page %1 of %2" ).arg( dw->pageTitle() ).arg( wiz->name() ) ); + RenameWizardPageCommand *cmd = + new RenameWizardPageCommand( pn, formWindow() + , wiz, wiz->indexOf( wiz->currentPage() ), text ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } + } else if ( ::qt_cast(fw->mainContainer()) ) { + QMainWindow *mw = (QMainWindow*)fw->mainContainer(); + if ( id == commands[ "add_toolbar" ] ) { + AddToolBarCommand *cmd = + new AddToolBarCommand( tr( "Add Toolbar to '%1'" ).arg( formWindow()->name() ), + formWindow(), mw ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( id == commands[ "add_menu_item" ] ) { + AddMenuCommand *cmd = + new AddMenuCommand( tr( "Add Menu to '%1'" ).arg( formWindow()->name() ), + formWindow(), mw ); + formWindow()->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + } +} + +void MainWindow::clipboardChanged() +{ + QString text( qApp->clipboard()->text() ); + if (qWorkspace()->activeWindow() && ::qt_cast(qWorkspace()->activeWindow())) { + actionEditPaste->setEnabled(!text.isEmpty()); + } else { + QString start( "" ); + actionEditPaste->setEnabled( text.left( start.length() ) == start ); + } +} + +void MainWindow::selectionChanged() +{ + layoutChilds = FALSE; + layoutSelected = FALSE; + breakLayout = FALSE; + if ( !formWindow() ) { + actionEditCut->setEnabled( FALSE ); + actionEditCopy->setEnabled( FALSE ); + actionEditDelete->setEnabled( FALSE ); + actionEditAdjustSize->setEnabled( FALSE ); + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditSplitHorizontal->setEnabled( FALSE ); + actionEditSplitVertical->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( FALSE ); + actionEditLower->setEnabled( FALSE ); + actionEditRaise->setEnabled( FALSE ); + actionEditAdjustSize->setEnabled( FALSE ); + return; + } + + int selectedWidgets = formWindow()->numSelectedWidgets(); + bool enable = selectedWidgets > 0; + actionEditCut->setEnabled( enable ); + actionEditCopy->setEnabled( enable ); + actionEditDelete->setEnabled( enable ); + actionEditLower->setEnabled( enable ); + actionEditRaise->setEnabled( enable ); + + actionEditAdjustSize->setEnabled( FALSE ); + actionEditSplitHorizontal->setEnabled( FALSE ); + actionEditSplitVertical->setEnabled( FALSE ); + + enable = FALSE; + QWidgetList widgets = formWindow()->selectedWidgets(); + if ( selectedWidgets > 1 ) { + int unlaidout = 0; + int laidout = 0; + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + if ( !w->parentWidget() || WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ) + unlaidout++; + else + laidout++; + } + actionEditHLayout->setEnabled( unlaidout > 1 ); + actionEditVLayout->setEnabled( unlaidout > 1 ); + actionEditSplitHorizontal->setEnabled( unlaidout > 1 ); + actionEditSplitVertical->setEnabled( unlaidout > 1 ); + actionEditGridLayout->setEnabled( unlaidout > 1 ); + actionEditBreakLayout->setEnabled( laidout > 0 ); + actionEditAdjustSize->setEnabled( laidout > 0 ); + layoutSelected = unlaidout > 1; + breakLayout = laidout > 0; + } else if ( selectedWidgets == 1 ) { + QWidget *w = widgets.first(); + bool isContainer = WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) || + w == formWindow()->mainContainer(); + actionEditAdjustSize->setEnabled( !w->parentWidget() || + WidgetFactory::layoutType( w->parentWidget() ) == WidgetFactory::NoLayout ); + + if ( !isContainer ) { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) { + actionEditBreakLayout->setEnabled( !isAToolBarChild( w ) ); + breakLayout = TRUE; + } else { + actionEditBreakLayout->setEnabled( FALSE ); + } + } else { + if ( WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) { + if ( !formWindow()->hasInsertedChildren( w ) ) { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( FALSE ); + } else { + actionEditHLayout->setEnabled( TRUE ); + actionEditVLayout->setEnabled( TRUE ); + actionEditGridLayout->setEnabled( TRUE ); + actionEditBreakLayout->setEnabled( FALSE ); + layoutChilds = TRUE; + } + if ( w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) { + actionEditBreakLayout->setEnabled( !isAToolBarChild( w ) ); + breakLayout = TRUE; + } + } else { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( !isAToolBarChild( w ) ); + breakLayout = TRUE; + } + } + } else if ( selectedWidgets == 0 ) { + actionEditAdjustSize->setEnabled( TRUE ); + QWidget *w = formWindow()->mainContainer(); + if ( WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) { + if ( !formWindow()->hasInsertedChildren( w ) ) { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( FALSE ); + } else { + actionEditHLayout->setEnabled( TRUE ); + actionEditVLayout->setEnabled( TRUE ); + actionEditGridLayout->setEnabled( TRUE ); + actionEditBreakLayout->setEnabled( FALSE ); + layoutChilds = TRUE; + } + } else { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( TRUE ); + breakLayout = TRUE; + } + } else { + actionEditHLayout->setEnabled( FALSE ); + actionEditVLayout->setEnabled( FALSE ); + actionEditGridLayout->setEnabled( FALSE ); + actionEditBreakLayout->setEnabled( FALSE ); + } +} + +static QString fixArgs( const QString &s2 ) +{ + QString s = s2; + return s.replace( ',', ';' ); +} + +void MainWindow::writeConfig() +{ + QSettings config; + + // No search path for unix, only needs application name + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + QString keybase = DesignerApplication::settingsKey(); + + if (savePluginPaths) { + QStringList pluginPaths = QApplication::libraryPaths(); + config.writeEntry( keybase + "PluginPaths", pluginPaths ); + } + config.writeEntry( keybase + "RestoreWorkspace", restoreConfig ); + config.writeEntry( keybase + "SplashScreen", splashScreen ); + config.writeEntry( keybase + "ShowStartDialog", shStartDialog ); + config.writeEntry( keybase + "FileFilter", fileFilter ); + config.writeEntry( keybase + "TemplatePath", templPath ); + config.writeEntry( keybase + "RecentlyOpenedFiles", recentlyFiles ); + config.writeEntry( keybase + "RecentlyOpenedProjects", recentlyProjects ); + config.writeEntry( keybase + "DatabaseAutoEdit", databaseAutoEdit ); + + config.writeEntry( keybase + "AutoSave/Enabled", autoSaveEnabled ); + config.writeEntry( keybase + "AutoSave/Interval", autoSaveInterval ); + + config.writeEntry( keybase + "Grid/Snap", snGrid ); + config.writeEntry( keybase + "Grid/Show", sGrid ); + config.writeEntry( keybase + "Grid/x", grid().x() ); + config.writeEntry( keybase + "Grid/y", grid().y() ); + config.writeEntry( keybase + "LastToolPage", + toolBox->itemLabel( toolBox->currentIndex() ) ); + + config.writeEntry( keybase + "Background/UsePixmap", backPix ); + config.writeEntry( keybase + "Background/Color", (int)qworkspace->backgroundColor().rgb() ); + if ( qworkspace->backgroundPixmap() ) + qworkspace->backgroundPixmap()->save( QDir::home().absPath() + "/.designer/" + "background.xpm", "PNG" ); + + config.writeEntry( keybase + "Geometries/MainwindowX", x() ); + config.writeEntry( keybase + "Geometries/MainwindowY", y() ); + config.writeEntry( keybase + "Geometries/MainwindowWidth", width() ); + config.writeEntry( keybase + "Geometries/MainwindowHeight", height() ); + config.writeEntry( keybase + "Geometries/MainwindowMaximized", isMaximized() ); + config.writeEntry( keybase + "Geometries/PropertyEditorX", propertyEditor->parentWidget()->x() ); + config.writeEntry( keybase + "Geometries/PropertyEditorY", propertyEditor->parentWidget()->y() ); + config.writeEntry( keybase + "Geometries/PropertyEditorWidth", propertyEditor->parentWidget()->width() ); + config.writeEntry( keybase + "Geometries/PropertyEditorHeight", propertyEditor->parentWidget()->height() ); + config.writeEntry( keybase + "Geometries/HierarchyViewX", hierarchyView->parentWidget()->x() ); + config.writeEntry( keybase + "Geometries/HierarchyViewY", hierarchyView->parentWidget()->y() ); + config.writeEntry( keybase + "Geometries/HierarchyViewWidth", hierarchyView->parentWidget()->width() ); + config.writeEntry( keybase + "Geometries/HierarchyViewHeight", hierarchyView->parentWidget()->height() ); + config.writeEntry( keybase + "Geometries/WorkspaceX", wspace->parentWidget()->x() ); + config.writeEntry( keybase + "Geometries/WorkspaceY", wspace->parentWidget()->y() ); + config.writeEntry( keybase + "Geometries/WorkspaceWidth", wspace->parentWidget()->width() ); + config.writeEntry( keybase + "Geometries/WorkspaceHeight", wspace->parentWidget()->height() ); + + config.writeEntry( keybase + "View/TextLabels", usesTextLabel() ); + config.writeEntry( keybase + "View/BigIcons", usesBigPixmaps() ); + + QString mwlKey = "MainwindowLayout"; + if ( singleProjectMode() ) + mwlKey += "S"; + QString mainWindowLayout; + QTextStream ts( &mainWindowLayout, IO_WriteOnly ); + ts << *this; + config.writeEntry( keybase + mwlKey, mainWindowLayout ); + + + QPtrList *lst = MetaDataBase::customWidgets(); + config.writeEntry( keybase + "CustomWidgets/num", (int)lst->count() ); + int j = 0; + QDir::home().mkdir( ".designer" ); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + QStringList l; + l << w->className; + l << w->includeFile; + l << QString::number( (int)w->includePolicy ); + l << QString::number( w->sizeHint.width() ); + l << QString::number( w->sizeHint.height() ); + l << QString::number( w->lstSignals.count() ); + for ( QValueList::ConstIterator it = w->lstSignals.begin(); it != w->lstSignals.end(); ++it ) + l << QString( fixArgs( *it ) ); + l << QString::number( w->lstSlots.count() ); + for ( QValueList::ConstIterator it2 = w->lstSlots.begin(); it2 != w->lstSlots.end(); ++it2 ) { + l << fixArgs( (*it2).function ); + l << (*it2).access; + } + l << QString::number( w->lstProperties.count() ); + for ( QValueList::ConstIterator it3 = w->lstProperties.begin(); it3 != w->lstProperties.end(); ++it3 ) { + l << (*it3).property; + l << (*it3).type; + } + l << QString::number( size_type_to_int( w->sizePolicy.horData() ) ); + l << QString::number( size_type_to_int( w->sizePolicy.verData() ) ); + l << QString::number( (int)w->isContainer ); + config.writeEntry( keybase + "CustomWidgets/Widget" + QString::number( j++ ), l, ',' ); + w->pixmap->save( QDir::home().absPath() + "/.designer/" + w->className, "XPM" ); + } + + QStringList l; + for ( QAction *a = commonWidgetsPage.first(); a; a = commonWidgetsPage.next() ) + l << a->text(); + config.writeEntry( keybase + "ToolBox/CommonWidgets", l ); +} + +static QString fixArgs2( const QString &s2 ) +{ + QString s = s2; + return s.replace( ';', ',' ); +} + +void MainWindow::readConfig() +{ + QString keybase = DesignerApplication::settingsKey(); + QSettings config; + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + bool ok; + bool readPreviousConfig = FALSE; + QString backPixName( QDir::home().absPath() + "/.designer/" + "background.xpm" ); + restoreConfig = config.readBoolEntry( keybase + "RestoreWorkspace", TRUE, &ok ); + if ( !ok ) { + keybase = DesignerApplication::oldSettingsKey(); + restoreConfig = config.readBoolEntry( keybase + "RestoreWorkspace", TRUE, &ok ); + if ( !ok ) { + if ( oWindow ) { + oWindow->shuttingDown(); + ( (QDockWindow*)oWindow->parent() )->hide(); + } + QPixmap pix; + pix.load( backPixName ); + if ( !pix.isNull() ) + qworkspace->setBackgroundPixmap( pix ); + return; + } + readPreviousConfig = TRUE; + } + if ( !readPreviousConfig ) { + fileFilter = config.readEntry( keybase + "FileFilter", fileFilter ); + templPath = config.readEntry( keybase + "TemplatePath", QString::null ); + databaseAutoEdit = config.readBoolEntry( keybase + "DatabaseAutoEdit", databaseAutoEdit ); + shStartDialog = config.readBoolEntry( keybase + "ShowStartDialog", shStartDialog ); + autoSaveEnabled = config.readBoolEntry( keybase + "AutoSave/Enabled", autoSaveEnabled ); + autoSaveInterval = config.readNumEntry( keybase + "AutoSave/Interval", autoSaveInterval ); + } + + if ( restoreConfig || readPreviousConfig ) { + QString s = config.readEntry( keybase + "LastToolPage" ); + for ( int i = 0; i < toolBox->count(); ++i ) { + if ( toolBox->itemLabel(i) == s ) { + toolBox->setCurrentIndex( i ); + break; + } + } + // We know that the oldSettingsKey() will return 3.1 + if ( keybase == DesignerApplication::oldSettingsKey() ) { + if (keybase.contains("3.1")) + recentlyFiles = config.readListEntry( keybase + "RecentlyOpenedFiles", ',' ); + else + recentlyFiles = config.readListEntry(keybase + "RecentlyOpenedFiles"); + + if ( recentlyFiles.count() == 1 && recentlyFiles[0].isNull() ) + recentlyFiles.clear(); + if (keybase.contains("3.1")) + recentlyProjects = config.readListEntry( keybase + "RecentlyOpenedProjects", ',' ); + else + recentlyProjects = config.readListEntry( keybase + "RecentlyOpenedProjects"); + if ( recentlyProjects.count() == 1 && recentlyProjects[0].isNull() ) + recentlyProjects.clear(); + } else { + recentlyFiles = config.readListEntry( keybase + "RecentlyOpenedFiles" ); + recentlyProjects = config.readListEntry( keybase + "RecentlyOpenedProjects" ); + } + + backPix = config.readBoolEntry( keybase + "Background/UsePixmap", TRUE ) | readPreviousConfig; + if ( backPix ) { + QPixmap pix; + pix.load( backPixName ); + if ( !pix.isNull() ) + qworkspace->setBackgroundPixmap( pix ); + } else { + qworkspace->setBackgroundColor( QColor( (QRgb)config.readNumEntry( keybase + "Background/Color" ) ) ); + } + + if ( !readPreviousConfig ) { + splashScreen = config.readBoolEntry( keybase + "SplashScreen", TRUE ); + + sGrid = config.readBoolEntry( keybase + "Grid/Show", TRUE ); + snGrid = config.readBoolEntry( keybase + "Grid/Snap", TRUE ); + grd.setX( config.readNumEntry( keybase + "Grid/x", 10 ) ); + grd.setY( config.readNumEntry( keybase + "Grid/y", 10 ) ); + + if ( !config.readBoolEntry( DesignerApplication::settingsKey() + "Geometries/MainwindowMaximized", FALSE ) ) { + QRect r( pos(), size() ); + r.setX( config.readNumEntry( keybase + "Geometries/MainwindowX", r.x() ) ); + r.setY( config.readNumEntry( keybase + "Geometries/MainwindowY", r.y() ) ); + r.setWidth( config.readNumEntry( keybase + "Geometries/MainwindowWidth", r.width() ) ); + r.setHeight( config.readNumEntry( keybase + "Geometries/MainwindowHeight", r.height() ) ); + + QRect desk = QApplication::desktop()->geometry(); + QRect inter = desk.intersect( r ); + resize( r.size() ); + if ( inter.width() * inter.height() > ( r.width() * r.height() / 20 ) ) { + move( r.topLeft() ); + } + } + setUsesTextLabel( config.readBoolEntry( keybase + "View/TextLabels", FALSE ) ); + setUsesBigPixmaps( FALSE /*config.readBoolEntry( "BigIcons", FALSE )*/ ); // ### disabled for now + } + } + int num = config.readNumEntry( keybase + "CustomWidgets/num" ); + for ( int j = 0; j < num; ++j ) { + MetaDataBase::CustomWidget *w = new MetaDataBase::CustomWidget; + QStringList l = config.readListEntry( keybase + "CustomWidgets/Widget" + QString::number( j ), ',' ); + w->className = l[ 0 ]; + w->includeFile = l[ 1 ]; + w->includePolicy = (MetaDataBase::CustomWidget::IncludePolicy)l[ 2 ].toInt(); + w->sizeHint.setWidth( l[ 3 ].toInt() ); + w->sizeHint.setHeight( l[ 4 ].toInt() ); + uint c = 5; + if ( l.count() > c ) { + int numSignals = l[ c ].toInt(); + c++; + for ( int i = 0; i < numSignals; ++i, c++ ) + w->lstSignals.append( fixArgs2( l[ c ] ).latin1() ); + } + if ( l.count() > c ) { + int numSlots = l[ c ].toInt(); + c++; + for ( int i = 0; i < numSlots; ++i ) { + MetaDataBase::Function slot; + slot.function = fixArgs2( l[ c ] ); + c++; + slot.access = l[ c ]; + c++; + w->lstSlots.append( slot ); + } + } + if ( l.count() > c ) { + int numProperties = l[ c ].toInt(); + c++; + for ( int i = 0; i < numProperties; ++i ) { + MetaDataBase::Property prop; + prop.property = l[ c ]; + c++; + prop.type = l[ c ]; + c++; + w->lstProperties.append( prop ); + } + } if ( l.count() > c ) { + QSizePolicy::SizeType h, v; + h = int_to_size_type( l[ c++ ].toInt() ); + v = int_to_size_type( l[ c++ ].toInt() ); + w->sizePolicy = QSizePolicy( h, v ); + } + if ( l.count() > c ) { + w->isContainer = (bool)l[ c++ ].toInt(); + } + w->pixmap = new QPixmap( QPixmap::fromMimeSource( QDir::home().absPath() + "/.designer/" + w->className ) ); + MetaDataBase::addCustomWidget( w ); + } + if ( num > 0 ) + rebuildCustomWidgetGUI(); + + if ( !restoreConfig ) + return; + +#ifndef Q_WS_MAC + /* I'm sorry to make this not happen on the Mac, but it seems to hang somewhere deep + in QLayout, it gets into a very large loop - and seems it has to do with clever + things the designer does ###Sam */ + QApplication::sendPostedEvents(); +#endif + + if ( !readPreviousConfig ) { + QString mwlKey = "MainwindowLayout"; + if ( singleProjectMode() ) + mwlKey += "S"; + QString mainWindowLayout = config.readEntry( keybase + mwlKey ); + QTextStream ts( &mainWindowLayout, IO_ReadOnly ); + ts >> *this; + } + if ( readPreviousConfig && oWindow ) { + oWindow->shuttingDown(); + ( (QDockWindow*)oWindow->parent() )->hide(); + } + + rebuildCustomWidgetGUI(); + + QStringList l = config.readListEntry( keybase + "ToolBox/CommonWidgets" ); + if ( !l.isEmpty() ) { + QPtrList lst; + commonWidgetsPage.clear(); + for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { + for ( QAction *a = toolActions.first(); a; a = toolActions.next() ) { + if ( *it == a->text() ) { + lst.append( a ); + break; + } + } + } + if ( lst != commonWidgetsPage ) { + commonWidgetsPage = lst; + rebuildCommonWidgetsToolBoxPage(); + } + } +} + +HierarchyView *MainWindow::objectHierarchy() const +{ + if ( !hierarchyView ) + ( (MainWindow*)this )->setupHierarchyView(); + return hierarchyView; +} + +QPopupMenu *MainWindow::setupNormalHierarchyMenu( QWidget *parent ) +{ + QPopupMenu *menu = new QPopupMenu( parent ); + + actionEditCut->addTo( menu ); + actionEditCopy->addTo( menu ); + actionEditPaste->addTo( menu ); + actionEditDelete->addTo( menu ); + + return menu; +} + +QPopupMenu *MainWindow::setupTabWidgetHierarchyMenu( QWidget *parent, const char *addSlot, const char *removeSlot ) +{ + QPopupMenu *menu = new QPopupMenu( parent ); + + menu->insertItem( tr( "Add Page" ), parent, addSlot ); + menu->insertItem( tr( "Delete Page" ), parent, removeSlot ); + menu->insertSeparator(); + actionEditCut->addTo( menu ); + actionEditCopy->addTo( menu ); + actionEditPaste->addTo( menu ); + actionEditDelete->addTo( menu ); + + return menu; +} + +void MainWindow::closeEvent( QCloseEvent *e ) +{ + if ( singleProject ) { + hide(); + e->ignore(); + return; + } + + QWidgetList windows = qWorkspace()->windowList(); + QWidgetListIt wit( windows ); + while ( wit.current() ) { + QWidget *w = wit.current(); + ++wit; + if ( ::qt_cast(w) ) { + if ( ( (FormWindow*)w )->formFile()->editor() ) + windows.removeRef( ( (FormWindow*)w )->formFile()->editor() ); + if ( ( (FormWindow*)w )->formFile()->formWindow() ) + windows.removeRef( ( (FormWindow*)w )->formFile()->formWindow() ); + if ( !( (FormWindow*)w )->formFile()->close() ) { + e->ignore(); + return; + } + } else if ( ::qt_cast(w) ) { + if ( !( (SourceEditor*)w )->close() ) { + e->ignore(); + return; + } + } + w->close(); + } + + QMapConstIterator it = projects.begin(); + while( it != projects.end() ) { + Project *pro = it.data(); + ++it; + if ( pro->isModified() ) { + switch ( QMessageBox::warning( this, tr( "Save Project Settings" ), + tr( "Save changes to '%1'?" ).arg( pro->fileName() ), + tr( "&Yes" ), tr( "&No" ), tr( "&Cancel" ), 0, 2 ) ) { + case 0: // save + pro->save(); + break; + case 1: // don't save + break; + case 2: // cancel + e->ignore(); + return; + default: + break; + } + } + } + + writeConfig(); + hide(); + e->accept(); + + if ( client ) { + QDir home( QDir::homeDirPath() ); + home.remove( ".designerpid" ); + } +} + +Workspace *MainWindow::workspace() const +{ + if ( !wspace ) + ( (MainWindow*)this )->setupWorkspace(); + return wspace; +} + +PropertyEditor *MainWindow::propertyeditor() const +{ + if ( !propertyEditor ) + ( (MainWindow*)this )->setupPropertyEditor(); + return propertyEditor; +} + +ActionEditor *MainWindow::actioneditor() const +{ + if ( !actionEditor ) + ( (MainWindow*)this )->setupActionEditor(); + return actionEditor; +} + +bool MainWindow::openEditor( QWidget *w, FormWindow *f ) +{ + if ( f && !f->project()->isCpp() && !WidgetFactory::isPassiveInteractor( w ) ) { + QString defSignal = WidgetFactory::defaultSignal( w ); + if ( defSignal.isEmpty() ) { + editSource(); + } else { + QString s = QString( w->name() ) + "_" + defSignal; + LanguageInterface *iface = MetaDataBase::languageInterface( f->project()->language() ); + if ( iface ) { + QStrList sigs = iface->signalNames( w ); + QString fullSignal; + for ( int i = 0; i < (int)sigs.count(); ++i ) { + QString sig = sigs.at( i ); + if ( sig.left( sig.find( '(' ) ) == defSignal ) { + fullSignal = sig; + break; + } + } + + if ( !fullSignal.isEmpty() ) { + QString signl = fullSignal; + fullSignal = fullSignal.mid( fullSignal.find( '(' ) + 1 ); + fullSignal.remove( (int)fullSignal.length() - 1, 1 ); + fullSignal = iface->createArguments( fullSignal.simplifyWhiteSpace() ); + s += "(" + fullSignal + ")"; + if ( !MetaDataBase::hasFunction( f, s.latin1() ) ) + MetaDataBase::addFunction( f, s.latin1(), "", "public", "slot", + f->project()->language(), "void" ); + s = s.left( s.find( '(' ) ).latin1(); + if ( !MetaDataBase::hasConnection( f, w, defSignal.latin1(), f->mainContainer(), s.latin1() ) ) { + MetaDataBase::Connection conn; + conn.sender = w; + conn.receiver = f->mainContainer(); + conn.signal = signl; + conn.slot = s; + AddConnectionCommand *cmd = + new AddConnectionCommand( tr( "Add connection" ), f, conn ); + f->commandHistory()->addCommand( cmd ); + cmd->execute(); + f->formFile()->setModified( TRUE ); + } + } + } + editFunction( s, TRUE ); + } + return TRUE; + } + if ( WidgetFactory::hasSpecialEditor( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ), w ) ) { + statusBar()->message( tr( "Edit %1..." ).arg( w->className() ) ); + WidgetFactory::editWidget( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ), + this, w, formWindow() ); + statusBar()->clear(); + return TRUE; + } + + const QMetaProperty* text = w->metaObject()->property( w->metaObject()->findProperty( "text", TRUE ), TRUE ); + const QMetaProperty* title = w->metaObject()->property( w->metaObject()->findProperty( "title", TRUE ), TRUE ); + if ( text && text->designable(w) ) { + bool ok = FALSE; + bool oldDoWrap = FALSE; + if ( ::qt_cast(w) ) { + int align = w->property( "alignment" ).toInt(); + if ( align & WordBreak ) + oldDoWrap = TRUE; + } + bool doWrap = oldDoWrap; + + QString text; + if ( ::qt_cast(w) || ::qt_cast(w) || ::qt_cast(w) ) { + text = MultiLineEditor::getText( this, w->property( "text" ).toString(), + !::qt_cast(w), &doWrap ); + ok = !text.isNull(); + } else { + text = QInputDialog::getText( tr("Text"), tr( "New text" ), + QLineEdit::Normal, w->property("text").toString(), &ok, this ); + } + if ( ok ) { + if ( oldDoWrap != doWrap ) { + QString pn( tr( "Set 'wordwrap' of '%1'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "wordwrap", QVariant( oldDoWrap, 0 ), + QVariant( doWrap, 0 ), QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "wordwrap", TRUE ); + } + + QString pn( tr( "Set the 'text' of '%1'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "text", w->property( "text" ), + text, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "text", TRUE ); + } + return TRUE; + } + if ( title && title->designable(w) ) { + bool ok = FALSE; + QString text; + text = QInputDialog::getText( tr("Title"), tr( "New title" ), QLineEdit::Normal, w->property("title").toString(), &ok, this ); + if ( ok ) { + QString pn( tr( "Set the 'title' of '%2'" ).arg( w->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, formWindow(), w, propertyEditor, + "title", w->property( "title" ), + text, QString::null, QString::null ); + cmd->execute(); + formWindow()->commandHistory()->addCommand( cmd ); + MetaDataBase::setPropertyChanged( w, "title", TRUE ); + } + return TRUE; + } + + if ( !WidgetFactory::isPassiveInteractor( w ) ) + editSource(); + + return TRUE; +} + +void MainWindow::rebuildCustomWidgetGUI() +{ + customWidgetToolBar->clear(); + customWidgetMenu->clear(); + customWidgetToolBar2->clear(); + int count = 0; + + QPtrListIterator it( toolActions ); + QAction *action; + while ( ( action = it.current() ) ) { + ++it; + if ( ( (WidgetAction*)action )->group() == "Custom Widgets" ) + delete action; + } + + QPtrList *lst = MetaDataBase::customWidgets(); + + actionToolsCustomWidget->addTo( customWidgetMenu ); + customWidgetMenu->insertSeparator(); + + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + WidgetAction* a = new WidgetAction( "Custom Widgets", actionGroupTools, QString::number( w->id ).latin1() ); + a->setToggleAction( TRUE ); + a->setText( w->className ); + a->setIconSet( *w->pixmap ); + a->setStatusTip( tr( "Insert a " +w->className + " (custom widget)" ) ); + a->setWhatsThis( tr("" + w->className + " (custom widget)" + "

Click Edit Custom Widgets... in the Tools|Custom menu to " + "add and change custom widgets. You can add properties as well as " + "signals and slots to integrate them into Qt Designer, " + "and provide a pixmap which will be used to represent the widget on the form.

") ); + + a->addTo( customWidgetToolBar ); + a->addTo( customWidgetToolBar2 ); + a->addTo( customWidgetMenu ); + count++; + } + QWidget *wid; + customWidgetToolBar2->setStretchableWidget( ( wid = new QWidget( customWidgetToolBar2 ) ) ); + wid->setBackgroundMode( customWidgetToolBar2->backgroundMode() ); + + if ( count == 0 ) + customWidgetToolBar->hide(); + else if ( customWidgetToolBar->isVisible() ) + customWidgetToolBar->show(); +} + +void MainWindow::rebuildCommonWidgetsToolBoxPage() +{ + toolBox->setUpdatesEnabled( FALSE ); + commonWidgetsToolBar->setUpdatesEnabled( FALSE ); + commonWidgetsToolBar->clear(); + for ( QAction *a = commonWidgetsPage.first(); a; a = commonWidgetsPage.next() ) + a->addTo( commonWidgetsToolBar ); + QWidget *w; + commonWidgetsToolBar->setStretchableWidget( ( w = new QWidget( commonWidgetsToolBar ) ) ); + w->setBackgroundMode( commonWidgetsToolBar->backgroundMode() ); + toolBox->setUpdatesEnabled( TRUE ); + commonWidgetsToolBar->setUpdatesEnabled( TRUE ); +} + +bool MainWindow::isCustomWidgetUsed( MetaDataBase::CustomWidget *wid ) +{ + QWidgetList windows = qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( ::qt_cast(w) ) { + if ( ( (FormWindow*)w )->isCustomWidgetUsed( wid ) ) + return TRUE; + } + } + return FALSE; +} + +void MainWindow::setGrid( const QPoint &p ) +{ + if ( p == grd ) + return; + grd = p; + QWidgetList windows = qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( !::qt_cast(w) ) + continue; + ( (FormWindow*)w )->mainContainer()->update(); + } +} + +void MainWindow::setShowGrid( bool b ) +{ + if ( b == sGrid ) + return; + sGrid = b; + QWidgetList windows = qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( !::qt_cast(w) ) + continue; + ( (FormWindow*)w )->mainContainer()->update(); + } +} + +void MainWindow::setSnapGrid( bool b ) +{ + if ( b == snGrid ) + return; + snGrid = b; +} + +QString MainWindow::documentationPath() const +{ + return QString( qInstallPathDocs() ) + "/html/"; +} + +void MainWindow::windowsMenuActivated( int id ) +{ + QWidget* w = qworkspace->windowList().at( id ); + if ( w ) + w->setFocus(); +} + +void MainWindow::projectSelected( QAction *a ) +{ + a->setOn( TRUE ); + if ( currentProject ) + currentProject->setActive( FALSE ); + Project *p = *projects.find( a ); + p->setActive( TRUE ); + if ( currentProject == p ) + return; + currentProject = p; + if ( wspace ) + wspace->setCurrentProject( currentProject ); +} + +void MainWindow::openProject( const QString &fn ) +{ + for ( QMap::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( (*it)->fileName() == fn ) { + projectSelected( it.key() ); + return; + } + } + QApplication::setOverrideCursor( waitCursor ); + Project *pro = new Project( fn, "", projectSettingsPluginManager ); + pro->setModified( FALSE ); + QAction *a = new QAction( pro->projectName(), pro->projectName(), 0, actionGroupProjects, 0, TRUE ); + projects.insert( a, pro ); + projectSelected( a ); + QApplication::restoreOverrideCursor(); +} + +void MainWindow::checkTempFiles() +{ + QString s = QDir::homeDirPath() + "/.designer"; + QString baseName = s+ "/saved-form-"; + if ( !QFile::exists( baseName + "1.ui" ) ) + return; + DesignerApplication::closeSplash(); + QDir d( s ); + d.setNameFilter( "*.ui" ); + QStringList lst = d.entryList(); + QApplication::restoreOverrideCursor(); + bool load = QMessageBox::information( this, tr( "Restoring the Last Session" ), + tr( "Qt Designer found some temporary saved files, which were\n" + "written when Qt Designer crashed last time. Do you want to\n" + "load these files?" ), tr( "&Yes" ), tr( "&No" ) ) == 0; + QApplication::setOverrideCursor( waitCursor ); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + if ( load ) + openFormWindow( s + "/" + *it, FALSE ); + d.remove( *it ); + } +} + +void MainWindow::showDialogHelp() +{ + QWidget *w = (QWidget*)sender(); + w = w->topLevelWidget(); + + QString link = documentationPath() + "/designer-manual-13.html#"; + + if ( ::qt_cast(w) || ::qt_cast(w) ) // own doc for startdialog? + link += "dialog-file-new"; + else if ( ::qt_cast(w) ) + link += "dialog-file-create-template"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-functions"; +// else if ( ::qt_cast(w) ) + else if ( w->inherits("ConnectionViewerBase") ) + link += "dialog-view-connections"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-form-settings"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-preferences"; + else if ( ::qt_cast(w) ) + link += "dialog-image-collection"; +// else if ( ::qt_cast(w) ) + else if ( w->inherits( "DatabaseConnectionBase" ) ) + link += "dialog-edit-database-connections"; + else if ( ::qt_cast(w) ) + link += "dialog-project-settings"; + else if ( ::qt_cast(w) ) + link += "dialog-find-text"; + else if ( ::qt_cast(w) ) + link += "dialog-replace-text"; + else if ( ::qt_cast(w) ) + link += "dialog-go-to-line"; +// else if ( ::qt_cast(w) ) + else if ( w->inherits("ConnectionEditorBase") ) + link += "dialog-edit-connections"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-custom-widgets"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-palette"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-listbox"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-listview"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-iconview"; + else if ( ::qt_cast(w) ) + link += "dialog-edit-table"; + else if ( ::qt_cast(w) ) + link += "dialog-text"; + + else { + QMessageBox::information( this, tr( "Help" ), + tr( "There is no help available for this dialog at the moment." ) ); + return; + } + + assistant->showPage( link ); +} + +void MainWindow::setupActionManager() +{ + actionPluginManager = new QPluginManager( IID_Action, QApplication::libraryPaths(), pluginDirectory() ); + + QStringList lst = actionPluginManager->featureList(); + for ( QStringList::ConstIterator ait = lst.begin(); ait != lst.end(); ++ait ) { + ActionInterface *iface = 0; + actionPluginManager->queryInterface( *ait, &iface ); + if ( !iface ) + continue; + + iface->connectTo( desInterface ); + QAction *a = iface->create( *ait, this ); + if ( !a ) + continue; + + QString grp = iface->group( *ait ); + if ( grp.isEmpty() ) + grp = "3rd party actions"; + QPopupMenu *menu = 0; + QToolBar *tb = 0; + + if ( !( menu = (QPopupMenu*)child( grp.latin1(), "QPopupMenu" ) ) ) { + menu = new QPopupMenu( this, grp.latin1() ); + menuBar()->insertItem( tr( grp ), menu ); + } + if ( !( tb = (QToolBar*)child( grp.latin1(), "QToolBar" ) ) ) { + tb = new QToolBar( this, grp.latin1() ); + tb->setCloseMode( QDockWindow::Undocked ); + addToolBar( tb, grp ); + } + + if ( iface->location( *ait, ActionInterface::Menu ) ) + a->addTo( menu ); + if ( iface->location( *ait, ActionInterface::Toolbar ) ) + a->addTo( tb ); + + iface->release(); + } +} + +void MainWindow::editFunction( const QString &func, bool rereadSource ) +{ + if ( !formWindow() ) + return; + + if ( formWindow()->formFile()->codeFileState() != FormFile::Ok ) + if ( !formWindow()->formFile()->setupUihFile(FALSE) ) + return; + + QString lang = currentProject->language(); + if ( !MetaDataBase::hasEditor( lang ) ) { + QMessageBox::information( this, tr( "Edit Source" ), + tr( "There is no plugin for editing " + lang + " code installed!\n" + "Note: Plugins are not available in static Qt configurations." ) ); + return; + } + + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->language() == lang && e->formWindow() == formWindow() ) { + e->show(); + e->setFunction( func ); + return; + } + } + + createSourceEditor( formWindow(), formWindow()->project(), lang, func, rereadSource ); +} + +void MainWindow::setupRecentlyFilesMenu() +{ + recentlyFilesMenu->clear(); + int id = 0; + for ( QStringList::ConstIterator it = recentlyFiles.begin(); it != recentlyFiles.end(); ++it ) { + recentlyFilesMenu->insertItem( *it, id ); + id++; + } +} + +void MainWindow::setupRecentlyProjectsMenu() +{ + recentlyProjectsMenu->clear(); + int id = 0; + for ( QStringList::ConstIterator it = recentlyProjects.begin(); it != recentlyProjects.end(); ++it ) { + recentlyProjectsMenu->insertItem( *it, id ); + id++; + } +} + +QPtrList MainWindow::projectList() const +{ + QPtrList list; + QMapConstIterator it = projects.begin(); + + while( it != projects.end() ) { + Project *p = it.data(); + ++it; + list.append( p->iFace() ); + } + + return list; +} + +QStringList MainWindow::projectNames() const +{ + QStringList res; + for ( QMap::ConstIterator it = projects.begin(); it != projects.end(); ++it ) + res << (*it)->projectName(); + return res; +} + +QStringList MainWindow::projectFileNames() const +{ + QStringList res; + for ( QMap::ConstIterator it = projects.begin(); it != projects.end(); ++it ) + res << (*it)->makeRelative( (*it)->fileName() ); + return res; +} + +Project *MainWindow::findProject( const QString &projectName ) const +{ + for ( QMap::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( (*it)->projectName() == projectName ) + return *it; + } + return 0; +} + +void MainWindow::setCurrentProject( Project *pro ) +{ + for ( QMap::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( *it == pro ) { + projectSelected( it.key() ); + return; + } + } +} + +void MainWindow::setCurrentProjectByFilename( const QString& proFilename ) +{ + for ( QMap::ConstIterator it = projects.begin(); it != projects.end(); ++it ) { + if ( (*it)->makeRelative( (*it)->fileName() ) == proFilename ) { + projectSelected( it.key() ); + return; + } + } +} + + +void MainWindow::recentlyFilesMenuActivated( int id ) +{ + if ( id != -1 ) { + if ( !QFile::exists( *recentlyFiles.at( id ) ) ) { + QMessageBox::warning( this, tr( "Open File" ), + tr( "Could not open '%1'. File does not exist." ). + arg( *recentlyFiles.at( id ) ) ); + recentlyFiles.remove( recentlyFiles.at( id ) ); + return; + } + fileOpen( "", "", *recentlyFiles.at( id ) ); + QString fn( *recentlyFiles.at( id ) ); + addRecentlyOpened( fn, recentlyFiles ); + } +} + +void MainWindow::recentlyProjectsMenuActivated( int id ) +{ + if ( id != -1 ) { + if ( !QFile::exists( *recentlyProjects.at( id ) ) ) { + QMessageBox::warning( this, tr( "Open Project" ), + tr( "Could not open '%1'. File does not exist." ). + arg( *recentlyProjects.at( id ) ) ); + recentlyProjects.remove( recentlyProjects.at( id ) ); + return; + } + openProject( *recentlyProjects.at( id ) ); + QString fn( *recentlyProjects.at( id ) ); + addRecentlyOpened( fn, recentlyProjects ); + } +} + +void MainWindow::addRecentlyOpened( const QString &fn, QStringList &lst ) +{ + QFileInfo fi( fn ); + fi.convertToAbs(); + QString f = fi.filePath(); + if ( lst.find( f ) != lst.end() ) + lst.remove( f ); + if ( lst.count() >= 10 ) + lst.pop_back(); + lst.prepend( f ); +} + +TemplateWizardInterface * MainWindow::templateWizardInterface( const QString& className ) +{ + TemplateWizardInterface* iface = 0; + templateWizardPluginManager->queryInterface( className, & iface ); + return iface; +} + +void MainWindow::setupPluginManagers() +{ + editorPluginManager = new QPluginManager( IID_Editor, QApplication::libraryPaths(), pluginDirectory() ); + MetaDataBase::setEditor( editorPluginManager->featureList() ); + + templateWizardPluginManager = + new QPluginManager( IID_TemplateWizard, QApplication::libraryPaths(), pluginDirectory() ); + + MetaDataBase::setupInterfaceManagers( pluginDirectory() ); + preferencePluginManager = + new QPluginManager( IID_Preference, QApplication::libraryPaths(), pluginDirectory() ); + projectSettingsPluginManager = + new QPluginManager( IID_ProjectSettings, QApplication::libraryPaths(), pluginDirectory() ); + sourceTemplatePluginManager = + new QPluginManager( IID_SourceTemplate, QApplication::libraryPaths(), pluginDirectory() ); + + if ( preferencePluginManager ) { + QStringList lst = preferencePluginManager->featureList(); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + PreferenceInterface *i = 0; + preferencePluginManager->queryInterface( *it, &i ); + if ( !i ) + continue; + i->connectTo( designerInterface() ); + PreferenceInterface::Preference *pf = i->preference(); + if ( pf ) + addPreferencesTab( pf->tab, pf->title, pf->receiver, pf->init_slot, pf->accept_slot ); + i->deletePreferenceObject( pf ); + + i->release(); + } + } + if ( projectSettingsPluginManager ) { + QStringList lst = projectSettingsPluginManager->featureList(); + for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { + ProjectSettingsInterface *i = 0; + projectSettingsPluginManager->queryInterface( *it, &i ); + if ( !i ) + continue; + i->connectTo( designerInterface() ); + + ProjectSettingsInterface::ProjectSettings *pf = i->projectSetting(); + if ( pf ) + addProjectTab( pf->tab, pf->title, pf->receiver, pf->init_slot, pf->accept_slot ); + i->deleteProjectSettingsObject( pf ); + i->release(); + } + } +} + +void MainWindow::addPreferencesTab( QWidget *tab, const QString &title, QObject *receiver, const char *init_slot, const char *accept_slot ) +{ + Tab t; + t.w = tab; + t.title = title; + t.receiver = receiver; + t.init_slot = init_slot; + t.accept_slot = accept_slot; + preferenceTabs << t; +} + +void MainWindow::addProjectTab( QWidget *tab, const QString &title, QObject *receiver, const char *init_slot, const char *accept_slot ) +{ + Tab t; + t.w = tab; + t.title = title; + t.receiver = receiver; + t.init_slot = init_slot; + t.accept_slot = accept_slot; + projectTabs << t; +} + +void MainWindow::setModified( bool b, QWidget *window ) +{ + QWidget *w = window; + while ( w ) { + if ( ::qt_cast(w) ) { + ( (FormWindow*)w )->modificationChanged( b ); + return; + } else if ( ::qt_cast(w) ) { + FormWindow *fw = ( (SourceEditor*)w )->formWindow(); + if ( fw && !fw->isFake() ) { + //fw->commandHistory()->setModified( b ); + //fw->modificationChanged( b ); + fw->formFile()->setModified( b, FormFile::WFormCode ); + wspace->update( fw->formFile() ); + } else { + wspace->update(); + } + return; + } + w = w->parentWidget( TRUE ); + } +} + +void MainWindow::editorClosed( SourceEditor *e ) +{ + sourceEditors.take( sourceEditors.findRef( e ) ); +} + +void MainWindow::functionsChanged() +{ + updateFunctionsTimer->start( 0, TRUE ); +} + +void MainWindow::doFunctionsChanged() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->refresh( FALSE ); + hierarchyView->formDefinitionView()->refresh(); +} + +void MainWindow::updateFunctionList() +{ + if ( !qWorkspace()->activeWindow() || !::qt_cast(qWorkspace()->activeWindow()) ) + return; + SourceEditor *se = (SourceEditor*)qWorkspace()->activeWindow(); + se->save(); + hierarchyView->formDefinitionView()->refresh(); + if ( !currentProject->isCpp() && se->formWindow() ) { + LanguageInterface *iface = MetaDataBase::languageInterface( currentProject->language() ); + if ( !iface ) + return; + QValueList conns; + iface->connections( se->text(), &conns ); + MetaDataBase::setupConnections( se->formWindow(), conns ); + propertyEditor->eventList()->setup(); + } +} + +void MainWindow::updateWorkspace() +{ + wspace->setCurrentProject( currentProject ); +} + +void MainWindow::showDebugStep( QObject *o, int line ) +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->clearStep(); + if ( !o || line == -1 ) + return; + showSourceLine( o, line, Step ); +} + +void MainWindow::showStackFrame( QObject *o, int line ) +{ + if ( !o || line == -1 ) + return; + showSourceLine( o, line, StackFrame ); +} + +void MainWindow::showErrorMessage( QObject *o, int errorLine, const QString &errorMessage ) +{ + if ( o ) { + errorLine--; // ###### + QValueList l; + l << ( errorLine + 1 ); + QStringList l2; + l2 << errorMessage; + QObjectList ol; + ol.append( o ); + QStringList ll; + ll << currentProject->locationOfObject( o ); + oWindow->setErrorMessages( l2, l, TRUE, ll, ol ); + showSourceLine( o, errorLine, Error ); + } +} + +void MainWindow::finishedRun() +{ + inDebugMode = FALSE; + previewing = FALSE; + debuggingForms.clear(); + enableAll( TRUE ); + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->project() == currentProject ) + e->editorInterface()->setMode( EditorInterface::Editing ); + e->clearStackFrame(); + } + outputWindow()->clearErrorMessages(); +} + +void MainWindow::enableAll( bool enable ) +{ + menuBar()->setEnabled( enable ); + QObjectList *l = queryList( "QDockWindow" ); + for ( QObject *o = l->first(); o; o = l->next() ) { + if ( o == wspace->parentWidget() || + o == oWindow->parentWidget() || + o == hierarchyView->parentWidget() ) + continue; + ( (QWidget*)o )->setEnabled( enable ); + } + delete l; +} + +void MainWindow::showSourceLine( QObject *o, int line, LineMode lm ) +{ + QWidgetList windows = qworkspace->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + FormWindow *fw = 0; + SourceEditor *se = 0; + SourceFile *sf = 0; + if ( ::qt_cast(w) ) { + fw = (FormWindow*)w; + } else if ( ::qt_cast(w) ) { + se = (SourceEditor*)w; + if ( !se->object() ) + continue; + if ( se->formWindow() ) + fw = se->formWindow(); + else + sf = se->sourceFile(); + } + + if ( fw ) { + if ( fw->project() != currentProject ) + continue; + if ( qstrcmp( fw->name(), o->name() ) == 0 || + fw->isFake() && currentProject->objectForFakeForm( fw ) == o ) { + if ( se ) { + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + return; + } else { + fw->showNormal(); + fw->setFocus(); + lastActiveFormWindow = fw; + qApp->processEvents(); + se = editSource(); + if ( se ) { + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + return; + } + } + } + } else if ( se ) { + if ( o != sf ) + continue; + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + return; + } + } + + if ( ::qt_cast(o) ) { + for ( QPtrListIterator sources = currentProject->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + if ( f == o ) { + SourceEditor *se = editSource( f ); + if ( se ) { + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + } + return; + } + } + } + + FormFile *ff = currentProject->fakeFormFileFor( o ); + FormWindow *fw = 0; + if ( ff ) + fw = ff->formWindow(); + + if ( !fw && !qwf_forms ) { + qWarning( "MainWindow::showSourceLine: qwf_forms is NULL!" ); + return; + } + + mblockNewForms = TRUE; + if ( !fw ) + openFormWindow( currentProject->makeAbsolute( *qwf_forms->find( (QWidget*)o ) ) ); + else + fw->formFile()->showEditor( FALSE ); + qApp->processEvents(); // give all views the chance to get the formwindow + SourceEditor *se = editSource(); + if ( se ) { + switch ( lm ) { + case Error: + se->editorInterface()->setError( line ); + break; + case Step: + se->editorInterface()->setStep( line ); + break; + case StackFrame: + se->editorInterface()->setStackFrame( line ); + break; + } + } + mblockNewForms = FALSE; +} + + +QObject *MainWindow::findRealObject( QObject *o ) +{ + QWidgetList windows = qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if ( ::qt_cast(w) && QString( w->name() ) == QString( o->name() ) ) + return w; + else if ( ::qt_cast(w) && ( (SourceEditor*)w )->formWindow() && + QString( ( (SourceEditor*)w )->formWindow()->name() ) == QString( o->name() ) ) + return w; + else if ( ::qt_cast(w) && ( (SourceEditor*)w )->sourceFile() && + ( (SourceEditor*)w )->sourceFile() == o ) + return o; + } + return 0; +} + +void MainWindow::formNameChanged( FormWindow *fw ) +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->object() == fw ) + e->refresh( TRUE ); + if ( e->project() == fw->project() ) + e->resetContext(); + } +} + +void MainWindow::breakPointsChanged() +{ + if ( !inDebugMode ) + return; + if ( !qWorkspace()->activeWindow() || !::qt_cast(qWorkspace()->activeWindow()) ) + return; + SourceEditor *e = (SourceEditor*)qWorkspace()->activeWindow(); + if ( !e->object() || !e->project() ) + return; + if ( e->project() != currentProject ) + return; + + if ( !interpreterPluginManager ) { + interpreterPluginManager = + new QPluginManager( IID_Interpreter, + QApplication::libraryPaths(), + "/qsa" ); + } + + InterpreterInterface *iiface = 0; + if ( interpreterPluginManager ) { + QString lang = currentProject->language(); + iiface = 0; + interpreterPluginManager->queryInterface( lang, &iiface ); + if ( !iiface ) + return; + } + + e->saveBreakPoints(); + + for ( QObject *o = debuggingForms.first(); o; o = debuggingForms.next() ) { + if ( qstrcmp( o->name(), e->object()->name() ) == 0 ) { + iiface->setBreakPoints( o, MetaDataBase::breakPoints( e->object() ) ); + break; + } + } + + for ( e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->project() == currentProject && e->sourceFile() ) { + QValueList bps = MetaDataBase::breakPoints( e->sourceFile() ); + iiface->setBreakPoints( e->object(), bps ); + } + } + + iiface->release(); +} + +int MainWindow::currentLayoutDefaultSpacing() const +{ + if ( ( (MainWindow*)this )->formWindow() ) + return ( (MainWindow*)this )->formWindow()->layoutDefaultSpacing(); + return BOXLAYOUT_DEFAULT_SPACING; +} + +int MainWindow::currentLayoutDefaultMargin() const +{ + if ( ( (MainWindow*)this )->formWindow() ) + return ( (MainWindow*)this )->formWindow()->layoutDefaultMargin(); + return BOXLAYOUT_DEFAULT_MARGIN; +} + +void MainWindow::saveAllBreakPoints() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + e->save(); + e->saveBreakPoints(); + } +} + +void MainWindow::resetBreakPoints() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->resetBreakPoints(); +} + +SourceFile *MainWindow::sourceFile() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( qworkspace->activeWindow() == e ) { + if ( e->sourceFile() ) + return e->sourceFile(); + } + } + return 0; +} + +bool MainWindow::openProjectSettings( Project *pro ) +{ + ProjectSettings dia( pro, this, 0, TRUE ); + SenderObject *senderObject = new SenderObject( designerInterface() ); + QValueList::ConstIterator it; + for ( it = projectTabs.begin(); it != projectTabs.end(); ++it ) { + Tab t = *it; + if ( t.title != pro->language() ) + continue; + dia.tabWidget->addTab( t.w, t.title ); + if ( t.receiver ) { + connect( dia.buttonOk, SIGNAL( clicked() ), senderObject, SLOT( emitAcceptSignal() ) ); + connect( senderObject, SIGNAL( acceptSignal( QUnknownInterface * ) ), t.receiver, t.accept_slot ); + connect( senderObject, SIGNAL( initSignal( QUnknownInterface * ) ), t.receiver, t.init_slot ); + senderObject->emitInitSignal(); + disconnect( senderObject, SIGNAL( initSignal( QUnknownInterface * ) ), t.receiver, t.init_slot ); + } + } + + if ( singleProject ) + dia.tabWidget->setTabEnabled( dia.tabSettings, FALSE ); + + int res = dia.exec(); + + delete senderObject; + + for ( it = projectTabs.begin(); it != projectTabs.end(); ++it ) { + Tab t = *it; + dia.tabWidget->removePage( t.w ); + t.w->reparent( 0, QPoint(0,0), FALSE ); + } + + return res == QDialog::Accepted; +} + +void MainWindow::popupProjectMenu( const QPoint &pos ) +{ + projectMenu->exec( pos ); +} + +QStringList MainWindow::sourceTemplates() const +{ + return sourceTemplatePluginManager->featureList(); +} + +SourceTemplateInterface* MainWindow::sourceTemplateInterface( const QString& templ ) +{ + SourceTemplateInterface *iface = 0; + sourceTemplatePluginManager->queryInterface( templ, &iface); + return iface; +} + +QString MainWindow::whatsThisFrom( const QString &key ) +{ + if ( menuHelpFile.isEmpty() ) { + QString fn( documentationPath() ); + fn += "/designer-manual-11.html"; + QFile f( fn ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + menuHelpFile = ts.read(); + } + } + + int i = menuHelpFile.find( key ); + if ( i == -1 ) + return QString::null; + int start = i; + int end = i; + start = menuHelpFile.findRev( "
  • ", i ) + 4; + end = menuHelpFile.find( '\n', i ) - 1; + return menuHelpFile.mid( start, end - start + 1 ); +} + +void MainWindow::setSingleProject( Project *pro ) +{ + if ( eProject ) { + Project *pro = eProject; + pro->save(); + QWidgetList windows = qWorkspace()->windowList(); + qWorkspace()->blockSignals( TRUE ); + QWidgetListIt wit( windows ); + while ( wit.current() ) { + QWidget *w = wit.current(); + ++wit; + if ( ::qt_cast(w) ) { + if ( ( (FormWindow*)w )->project() == pro ) { + if ( ( (FormWindow*)w )->formFile()->editor() ) + windows.removeRef( ( (FormWindow*)w )->formFile()->editor() ); + ( (FormWindow*)w )->formFile()->close(); + } + } else if ( ::qt_cast(w) ) { + ( (SourceEditor*)w )->close(); + } + } + hierarchyView->clear(); + windows = qWorkspace()->windowList(); + qWorkspace()->blockSignals( FALSE ); + currentProject = 0; + updateUndoRedo( FALSE, FALSE, QString::null, QString::null ); + } + + singleProject = TRUE; + projects.clear(); + QAction *a = new QAction( tr( pro->name() ), tr( pro->name() ), 0, + actionGroupProjects, 0, TRUE ); + eProject = pro; + projects.insert( a, eProject ); + a->setOn( TRUE ); + actionGroupProjects->removeFrom( projectMenu ); + actionGroupProjects->removeFrom( projectToolBar ); + currentProject = eProject; + currentProject->designerCreated(); +} + +void MainWindow::shuttingDown() +{ + outputWindow()->shuttingDown(); +} + +void MainWindow::showGUIStuff( bool b ) +{ + if ( (bool)guiStuffVisible == b ) + return; + guiStuffVisible = b; + if ( !b ) { + setAppropriate( (QDockWindow*)toolBox->parentWidget(), FALSE ); + toolBox->parentWidget()->hide(); + for ( QToolBar *tb = widgetToolBars.first(); tb; tb = widgetToolBars.next() ) { + tb->hide(); + setAppropriate( tb, FALSE ); + } + propertyEditor->setPropertyEditorEnabled( FALSE ); + setAppropriate( layoutToolBar, FALSE ); + layoutToolBar->hide(); + setAppropriate( toolsToolBar, FALSE ); + toolsToolBar->hide(); + menubar->removeItem( toolsMenuId ); + menubar->removeItem( toolsMenuId + 1 ); + menubar->removeItem( toolsMenuId + 2 ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditAccels, SLOT( setEnabled(bool) ) ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditFunctions, SLOT( setEnabled(bool) ) ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditConnections, SLOT( setEnabled(bool) ) ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditSource, SLOT( setEnabled(bool) ) ); + disconnect( this, SIGNAL( hasActiveForm(bool) ), actionEditFormSettings, SLOT( setEnabled(bool) ) ); + actionEditFormSettings->setEnabled( FALSE ); + actionEditSource->setEnabled( FALSE ); + actionEditConnections->setEnabled( FALSE ); + actionEditFunctions->setEnabled( FALSE ); + actionEditAccels->setEnabled( FALSE ); + ( (QDockWindow*)propertyEditor->parentWidget() )-> + setCaption( tr( "Signal Handlers" ) ); + actionGroupNew->removeFrom( fileMenu ); + actionGroupNew->removeFrom( projectToolBar ); + actionFileSave->removeFrom( fileMenu ); + actionFileSave->removeFrom( projectToolBar ); + actionFileExit->removeFrom( fileMenu ); + actionNewFile->addTo( fileMenu ); + actionNewFile->addTo( projectToolBar ); + actionFileSave->addTo( fileMenu ); + actionFileSave->addTo( projectToolBar ); + actionFileExit->addTo( fileMenu ); + } else { + setAppropriate( (QDockWindow*)toolBox->parentWidget(), TRUE ); + toolBox->parentWidget()->show(); + for ( QToolBar *tb = widgetToolBars.first(); tb; tb = widgetToolBars.next() ) { + setAppropriate( tb, TRUE ); + tb->hide(); + } + propertyEditor->setPropertyEditorEnabled( TRUE ); + setAppropriate( layoutToolBar, TRUE ); + layoutToolBar->show(); + setAppropriate( toolsToolBar, TRUE ); + toolsToolBar->show(); + menubar->insertItem( tr( "&Tools" ), toolsMenu, toolsMenuId, toolsMenuIndex ); + menubar->insertItem( tr( "&Layout" ), layoutMenu, toolsMenuId + 1, toolsMenuIndex + 1 ); + menubar->insertItem( tr( "&Preview" ), previewMenu, toolsMenuId + 2, toolsMenuIndex + 2 ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditAccels, SLOT( setEnabled(bool) ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditFunctions, SLOT( setEnabled(bool) ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditConnections, SLOT( setEnabled(bool) ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditSource, SLOT( setEnabled(bool) ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditFormSettings, SLOT( setEnabled(bool) ) ); + actionEditFormSettings->setEnabled( TRUE ); + actionEditSource->setEnabled( TRUE ); + actionEditConnections->setEnabled( TRUE ); + actionEditFunctions->setEnabled( TRUE ); + actionEditAccels->setEnabled( TRUE ); + ( (QDockWindow*)propertyEditor->parentWidget() )-> + setCaption( tr( "Property Editor/Signal Handlers" ) ); + actionFileSave->removeFrom( fileMenu ); + actionFileSave->removeFrom( projectToolBar ); + actionFileExit->removeFrom( fileMenu ); + actionGroupNew->addTo( fileMenu ); + actionGroupNew->addTo( projectToolBar ); + actionFileSave->addTo( fileMenu ); + actionFileSave->addTo( projectToolBar ); + actionFileExit->addTo( fileMenu ); + } +} + +void MainWindow::setEditorsReadOnly( bool b ) +{ + editorsReadOnly = b; +} + +void MainWindow::setPluginDirectory( const QString &pd ) +{ + pluginDir = pd; + if ( !qwf_plugin_dir ) + qwf_plugin_dir = new QString( pd ); + else + *qwf_plugin_dir = pd; +} + +void MainWindow::toggleSignalHandlers( bool show ) +{ + if ( sSignalHandlers == show ) + return; + sSignalHandlers = show; + propertyEditor->setSignalHandlersEnabled( show ); +} diff --git a/tools/designer/designer/mainwindow.h b/tools/designer/designer/mainwindow.h new file mode 100644 index 0000000..cffae68 --- /dev/null +++ b/tools/designer/designer/mainwindow.h @@ -0,0 +1,503 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include "metadatabase.h" +#include "../interfaces/actioninterface.h" // for GCC 2.7.* compatibility +#include "../interfaces/editorinterface.h" +#include "../interfaces/templatewizardiface.h" +#include "../interfaces/languageinterface.h" +#include "../interfaces/filterinterface.h" +#include "../interfaces/interpreterinterface.h" +#include "../interfaces/preferenceinterface.h" +#include "../interfaces/projectsettingsiface.h" +#include "../interfaces/sourcetemplateiface.h" +#include "sourceeditor.h" + +#include +#include +#include +#include +#include +#include + +class QToolBox; +class PropertyEditor; +class QWorkspace; +class QMenuBar; +class FormWindow; +class QPopupMenu; +class HierarchyView; +class QCloseEvent; +class Workspace; +class ActionEditor; +class Project; +class OutputWindow; +class QTimer; +class FindDialog; +struct DesignerProject; +class ReplaceDialog; +class GotoLineDialog; +class SourceFile; +class FormFile; +class QAssistantClient; + +#if defined(Q_FULL_TEMPLATE_INSTANTIATION) +#include +#else +class QToolBar; +#endif +class Preferences; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + enum LineMode { Error, Step, StackFrame }; + + MainWindow( bool asClient, bool single = FALSE, const QString &plgDir = "/designer" ); + ~MainWindow(); + + HierarchyView *objectHierarchy() const; + Workspace *workspace() const; + PropertyEditor *propertyeditor() const; + ActionEditor *actioneditor() const; + + void resetTool(); + int currentTool() const; + + FormWindow *formWindow(); + + bool unregisterClient( FormWindow *w ); + void editorClosed( SourceEditor *e ); + QWidget *isAFormWindowChild( QObject *o ) const; + QWidget *isAToolBarChild( QObject *o ) const; + + void insertFormWindow( FormWindow *fw ); + QWorkspace *qWorkspace() const; + + void popupFormWindowMenu( const QPoint &gp, FormWindow *fw ); + void popupWidgetMenu( const QPoint &gp, FormWindow *fw, QWidget *w ); + + QPopupMenu *setupNormalHierarchyMenu( QWidget *parent ); + QPopupMenu *setupTabWidgetHierarchyMenu( QWidget *parent, const char *addSlot, const char *removeSlot ); + + FormWindow *openFormWindow( const QString &fn, bool validFileName = TRUE, FormFile *ff = 0 ); + bool isCustomWidgetUsed( MetaDataBase::CustomWidget *w ); + + void setGrid( const QPoint &p ); + void setShowGrid( bool b ); + void setSnapGrid( bool b ); + QPoint grid() const { return grd; } + bool showGrid() const { return sGrid; } + bool snapGrid() const { return snGrid && sGrid; } + + QString documentationPath() const; + + static MainWindow *self; + + QString templatePath() const { return templPath; } + + void editFunction( const QString &func, bool rereadSource = FALSE ); + + bool isPreviewing() const { return previewing; } + + Project *currProject() const { return currentProject; } + + FormWindow *activeForm() const { return lastActiveFormWindow; } + + TemplateWizardInterface* templateWizardInterface( const QString& className ); + QStringList sourceTemplates() const; + SourceTemplateInterface* sourceTemplateInterface( const QString& templ ); + QUnknownInterface* designerInterface() const { return desInterface; } + QPtrList projectList() const; + QStringList projectNames() const; + QStringList projectFileNames() const; + Project *findProject( const QString &projectName ) const; + void setCurrentProject( Project *pro ); + void setCurrentProjectByFilename( const QString& proFilename ); + OutputWindow *outputWindow() const { return oWindow; } + void addPreferencesTab( QWidget *tab, const QString &title, QObject *receiver, const char *init_slot, const char *accept_slot ); + void addProjectTab( QWidget *tab, const QString &title, QObject *receiver, const char *init_slot, const char *accept_slot ); + void setModified( bool b, QWidget *window ); + void functionsChanged(); + void updateFunctionList(); + void updateWorkspace(); + void runProjectPrecondition(); + void runProjectPostcondition( QObjectList *l ); + + void formNameChanged( FormWindow *fw ); + + int currentLayoutDefaultSpacing() const; + int currentLayoutDefaultMargin() const; + + void saveAllBreakPoints(); + void resetBreakPoints(); + + SourceFile *sourceFile(); + void createNewProject( const QString &lang ); + + void popupProjectMenu( const QPoint &pos ); + QObject *findRealObject( QObject *o ); + + void setSingleProject( Project *pro ); + bool singleProjectMode() const { return singleProject; } + + void showSourceLine( QObject *o, int line, LineMode lm ); + + void shuttingDown(); + void showGUIStuff( bool b ); + void setEditorsReadOnly( bool b ); + bool areEditorsReadOnly() const { return editorsReadOnly; } + void toggleSignalHandlers( bool show ); + bool showSignalHandlers() const { return sSignalHandlers; } + void writeConfig(); + + void openProject( const QString &fn ); + void setPluginDirectory( const QString &pd ); + QString pluginDirectory() const { return pluginDir; } + + QAssistantClient* assistantClient() const { return assistant; } + + void addRecentlyOpenedFile( const QString &fn ) { addRecentlyOpened( fn, recentlyFiles ); } + +public slots: + void showProperties( QObject *w ); + void updateProperties( QObject *w ); + void showDialogHelp(); + void showDebugStep( QObject *o, int line ); + void showStackFrame( QObject *o, int line ); + void showErrorMessage( QObject *o, int line, const QString &errorMessage ); + void finishedRun(); + void breakPointsChanged(); + +signals: + void currentToolChanged(); + void hasActiveForm( bool ); + void hasActiveWindow( bool ); + void hasActiveWindowOrProject( bool ); + void hasNonDummyProject( bool ); + void formModified( bool ); + void formWindowsChanged(); + void formWindowChanged(); + void projectChanged(); + void editorChanged(); + +protected: + bool eventFilter( QObject *o, QEvent *e ); + void closeEvent( QCloseEvent *e ); + +public slots: + void fileNew(); + void fileNewDialog(); + void fileNewFile(); + void fileClose(); + void fileQuit(); + void fileCloseProject(); // not visible in menu, called from fileClose + void fileOpen(); + void fileOpen( const QString &filter, const QString &extension, const QString &filename = "" , bool inProject = TRUE ); + bool fileSave(); + bool fileSaveForm(); // not visible in menu, called from fileSave + bool fileSaveProject(); // not visible in menu, called from fileSaveProject + bool fileSaveAs(); + void fileSaveAll(); + void fileCreateTemplate(); + +public slots: + void editUndo(); + void editRedo(); + void editCut(); + void editCopy(); + void editPaste(); + void editDelete(); + void editSelectAll(); + void editLower(); + void editRaise(); + void editAdjustSize(); + void editLayoutHorizontal(); + void editLayoutVertical(); + void editLayoutHorizontalSplit(); + void editLayoutVerticalSplit(); + void editLayoutGrid(); + void editLayoutContainerHorizontal(); + void editLayoutContainerVertical(); + void editLayoutContainerGrid(); + void editBreakLayout(); + void editAccels(); + void editFunctions(); + void editConnections(); + SourceEditor *editSource(); + SourceEditor *editSource( SourceFile *f ); + SourceEditor *openSourceEditor(); + SourceEditor *createSourceEditor( QObject *object, Project *project, + const QString &lang = QString::null, + const QString &func = QString::null, + bool rereadSource = FALSE ); + void editFormSettings(); + void editProjectSettings(); + void editPixmapCollection(); + void editDatabaseConnections(); + void editPreferences(); + + void projectInsertFile(); + + void searchFind(); + void searchIncremetalFindMenu(); + void searchIncremetalFind(); + void searchIncremetalFindNext(); + void searchReplace(); + void searchGotoLine(); + + void previewForm(); + void previewForm( const QString& ); + + void toolsCustomWidget(); + void toolsConfigure(); + + void helpContents(); + void helpManual(); + void helpAbout(); + void helpAboutQt(); + void helpRegister(); + +private slots: + void activeWindowChanged( QWidget *w ); + void updateUndoRedo( bool, bool, const QString &, const QString & ); + void updateEditorUndoRedo(); + + void toolSelected( QAction* ); + + void clipboardChanged(); + void selectionChanged(); + + void windowsMenuActivated( int id ); + void setupWindowActions(); + + void createNewTemplate(); + void projectSelected( QAction *a ); + + void setupRecentlyFilesMenu(); + void setupRecentlyProjectsMenu(); + void recentlyFilesMenuActivated( int id ); + void recentlyProjectsMenuActivated( int id ); + + void emitProjectSignals(); + + void showStartDialog(); + +private: + void setupMDI(); + void setupMenuBar(); + void setupEditActions(); + void setupProjectActions(); + void setupSearchActions(); + void setupToolActions(); + void setupLayoutActions(); + void setupFileActions(); + void setupPreviewActions(); + void setupHelpActions(); + void setupRMBMenus(); + + void setupPropertyEditor(); + void setupHierarchyView(); + void setupWorkspace(); + void setupActionEditor(); + void setupOutputWindow(); + void setupToolbox(); + + void setupActionManager(); + void setupPluginManagers(); + + void enableAll( bool enable ); + + QWidget* previewFormInternal( QStyle* style = 0, QPalette* pal = 0 ); + + void readConfig(); + + void setupRMBProperties( QValueList &ids, QMap &props, QWidget *w ); + void handleRMBProperties( int id, QMap &props, QWidget *w ); + void setupRMBSpecialCommands( QValueList &ids, QMap &commands, QWidget *w ); + void handleRMBSpecialCommands( int id, QMap &commands, QWidget *w ); + void setupRMBSpecialCommands( QValueList &ids, QMap &commands, FormWindow *w ); + void handleRMBSpecialCommands( int id, QMap &commands, FormWindow *w ); + bool openEditor( QWidget *w, FormWindow *fw ); + void rebuildCustomWidgetGUI(); + void rebuildCommonWidgetsToolBoxPage(); + void checkTempFiles(); + + void addRecentlyOpened( const QString &fn, QStringList &lst ); + + QString whatsThisFrom( const QString &key ); + +private slots: + void doFunctionsChanged(); + bool openProjectSettings( Project *pro ); + +private: + struct Tab + { + QWidget *w; + QString title; + QObject *receiver; + const char *init_slot, *accept_slot; + Q_DUMMY_COMPARISON_OPERATOR( Tab ) + }; + +private: + PropertyEditor *propertyEditor; + HierarchyView *hierarchyView; + Workspace *wspace; + QWidget *lastPressWidget; + QWorkspace *qworkspace; + QMenuBar *menubar; + QGuardedPtr lastActiveFormWindow; + bool breakLayout, layoutChilds, layoutSelected; + QPoint grd; + bool sGrid, snGrid; + bool restoreConfig; + bool backPix; + bool splashScreen; + QString fileFilter; + + QMap projects; + QAction *actionEditUndo, *actionEditRedo, *actionEditCut, *actionEditCopy, + *actionEditPaste, *actionEditDelete, + *actionEditAdjustSize, + *actionEditHLayout, *actionEditVLayout, *actionEditGridLayout, + *actionEditSplitHorizontal, *actionEditSplitVertical, + *actionEditSelectAll, *actionEditBreakLayout, *actionEditFunctions, *actionEditConnections, + *actionEditLower, *actionEditRaise, *actionInsertSpacer; + QActionGroup *actionGroupTools, *actionGroupProjects; + QAction* actionPointerTool, *actionConnectTool, *actionOrderTool, *actionBuddyTool; + QAction* actionCurrentTool; + QAction *actionHelpContents, *actionHelpAbout, *actionHelpAboutQt, *actionHelpWhatsThis; + QAction *actionHelpManual; +#if defined(QT_NON_COMMERCIAL) + QAction *actionHelpRegister; +#endif + QAction *actionToolsCustomWidget, *actionEditPreferences; + QAction *actionWindowTile, *actionWindowCascade, *actionWindowClose, *actionWindowCloseAll; + QAction *actionWindowNext, *actionWindowPrevious; + QAction *actionEditFormSettings, *actionEditAccels; + QAction *actionEditSource, *actionNewFile, *actionFileSave, *actionFileExit; + QAction *actionSearchFind, *actionSearchIncremetal, *actionSearchReplace, *actionSearchGotoLine; + QActionGroup *actionGroupNew; + + QPopupMenu *rmbWidgets; + QPopupMenu *rmbFormWindow; + QPopupMenu *customWidgetMenu, *windowMenu, *fileMenu, *recentlyFilesMenu, *recentlyProjectsMenu; + QPopupMenu *toolsMenu, *layoutMenu, *previewMenu; + QToolBar *customWidgetToolBar, *layoutToolBar, *projectToolBar, *customWidgetToolBar2, *toolsToolBar; + QToolBar *commonWidgetsToolBar; + QPtrList widgetToolBars; + + Preferences *prefDia; + QMap propertyDocumentation; + bool client; + QString templPath; + ActionEditor *actionEditor; + Project *currentProject; + QPluginManager *actionPluginManager; + QPluginManager *editorPluginManager; + QPluginManager *templateWizardPluginManager; + QPluginManager *interpreterPluginManager; + QPluginManager *preferencePluginManager; + QPluginManager *projectSettingsPluginManager; + QPluginManager *sourceTemplatePluginManager; + QPtrList sourceEditors; + bool previewing; + QUnknownInterface *desInterface; + QStringList recentlyFiles; + QStringList recentlyProjects; + OutputWindow *oWindow; + QValueList preferenceTabs; + QValueList projectTabs; + bool databaseAutoEdit; + QTimer *updateFunctionsTimer; + QTimer *autoSaveTimer; + bool autoSaveEnabled; + int autoSaveInterval; + QLineEdit *incrementalSearch; + QGuardedPtr findDialog; + QGuardedPtr replaceDialog; + QGuardedPtr gotoLineDialog; + Project *eProject; + bool inDebugMode; + QObjectList debuggingForms; + QString lastOpenFilter; + QGuardedPtr previewedForm; + QPopupMenu *projectMenu; + QString menuHelpFile; + bool singleProject; + QToolBox *toolBox; + int toolsMenuId, toolsMenuIndex; + uint guiStuffVisible : 1; + uint editorsReadOnly : 1; + uint savePluginPaths : 1; + QAssistantClient *assistant; + bool shStartDialog; + QString pluginDir; + bool sSignalHandlers; + +public: + QString lastSaveFilter; + QPtrList toolActions; + QPtrList commonWidgetsPage; + +}; + +class SenderObject : public QObject +{ + Q_OBJECT + +public: + SenderObject( QUnknownInterface *i ) : iface( i ) { iface->addRef(); } + ~SenderObject() { iface->release(); } + +public slots: + void emitInitSignal() { emit initSignal( iface ); } + void emitAcceptSignal() { emit acceptSignal( iface ); } + +signals: + void initSignal( QUnknownInterface * ); + void acceptSignal( QUnknownInterface * ); + +private: + QUnknownInterface *iface; + +}; + +#endif diff --git a/tools/designer/designer/mainwindowactions.cpp b/tools/designer/designer/mainwindowactions.cpp new file mode 100644 index 0000000..d8d99aa --- /dev/null +++ b/tools/designer/designer/mainwindowactions.cpp @@ -0,0 +1,2061 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defs.h" +#include "project.h" +#include "widgetdatabase.h" +#include "widgetfactory.h" +#include "preferences.h" +#include "formwindow.h" +#include "newformimpl.h" +#include "resource.h" +#include "projectsettingsimpl.h" +#include "workspace.h" +#include "createtemplate.h" +#include "hierarchyview.h" +#include "editfunctionsimpl.h" +#include "finddialog.h" +#include "replacedialog.h" +#include "gotolinedialog.h" +#include "formsettingsimpl.h" +#include "pixmapcollectioneditor.h" +#include "styledbutton.h" +#include "customwidgeteditorimpl.h" +#ifndef QT_NO_SQL +#include "dbconnectionsimpl.h" +#include "dbconnectionimpl.h" +#endif +#include "widgetaction.h" +#include +#include "startdialogimpl.h" +#include "designerappiface.h" +#include "connectiondialog.h" +#include "configtoolboxdialog.h" + +static const char * whatsthis_image[] = { + "16 16 3 1", + " c None", + "o c #000000", + "a c #000080", + "o aaaaa ", + "oo aaa aaa ", + "ooo aaa aaa", + "oooo aa aa", + "ooooo aa aa", + "oooooo a aaa", + "ooooooo aaa ", + "oooooooo aaa ", + "ooooooooo aaa ", + "ooooo aaa ", + "oo ooo ", + "o ooo aaa ", + " ooo aaa ", + " ooo ", + " ooo ", + " ooo "}; + +const QString toolbarHelp = "

    Toolbars contain a number of buttons to " +"provide quick access to often used functions.%1" +"
    Click on the toolbar handle to hide the toolbar, " +"or drag and place the toolbar to a different location.

    "; + +static QIconSet createIconSet( const QString &name ) +{ + QIconSet ic( QPixmap::fromMimeSource( "" + name ) ); + QString prefix = "designer_"; + int right = name.length() - prefix.length(); + ic.setPixmap( QPixmap::fromMimeSource( prefix + "d_" + name.right( right ) ), + QIconSet::Small, QIconSet::Disabled ); + return ic; +} + +void MainWindow::setupEditActions() +{ + actionEditUndo = new QAction( tr("Undo"), createIconSet( "designer_undo.png" ),tr("&Undo: Not Available"), CTRL + Key_Z, this, 0 ); + actionEditUndo->setStatusTip( tr( "Undoes the last action" ) ); + actionEditUndo->setWhatsThis( whatsThisFrom( "Edit|Undo" ) ); + connect( actionEditUndo, SIGNAL( activated() ), this, SLOT( editUndo() ) ); + actionEditUndo->setEnabled( FALSE ); + + actionEditRedo = new QAction( tr( "Redo" ), createIconSet("designer_redo.png"), tr( "&Redo: Not Available" ), CTRL + Key_Y, this, 0 ); + actionEditRedo->setStatusTip( tr( "Redoes the last undone operation") ); + actionEditRedo->setWhatsThis( whatsThisFrom( "Edit|Redo" ) ); + connect( actionEditRedo, SIGNAL( activated() ), this, SLOT( editRedo() ) ); + actionEditRedo->setEnabled( FALSE ); + + actionEditCut = new QAction( tr( "Cut" ), createIconSet("designer_editcut.png"), tr( "Cu&t" ), CTRL + Key_X, this, 0 ); + actionEditCut->setStatusTip( tr( "Cuts the selected widgets and puts them on the clipboard" ) ); + actionEditCut->setWhatsThis( whatsThisFrom( "Edit|Cut" ) ); + connect( actionEditCut, SIGNAL( activated() ), this, SLOT( editCut() ) ); + actionEditCut->setEnabled( FALSE ); + + actionEditCopy = new QAction( tr( "Copy" ), createIconSet("designer_editcopy.png"), tr( "&Copy" ), CTRL + Key_C, this, 0 ); + actionEditCopy->setStatusTip( tr( "Copies the selected widgets to the clipboard" ) ); + actionEditCopy->setWhatsThis( whatsThisFrom( "Edit|Copy" ) ); + connect( actionEditCopy, SIGNAL( activated() ), this, SLOT( editCopy() ) ); + actionEditCopy->setEnabled( FALSE ); + + actionEditPaste = new QAction( tr( "Paste" ), createIconSet("designer_editpaste.png"), tr( "&Paste" ), CTRL + Key_V, this, 0 ); + actionEditPaste->setStatusTip( tr( "Pastes the clipboard's contents" ) ); + actionEditPaste->setWhatsThis( whatsThisFrom( "Edit|Paste" ) ); + connect( actionEditPaste, SIGNAL( activated() ), this, SLOT( editPaste() ) ); + actionEditPaste->setEnabled( FALSE ); + + actionEditDelete = new QAction( tr( "Delete" ), QPixmap(), tr( "&Delete" ), Key_Delete, this, 0 ); + actionEditDelete->setStatusTip( tr( "Deletes the selected widgets" ) ); + actionEditDelete->setWhatsThis( whatsThisFrom( "Edit|Delete" ) ); + connect( actionEditDelete, SIGNAL( activated() ), this, SLOT( editDelete() ) ); + actionEditDelete->setEnabled( FALSE ); +#ifdef Q_WS_MAC + QAction *macDelete = new QAction( tr( "Delete" ), QPixmap(), tr( "&Delete" ), Key_Backspace, this, 0 ); + connect( macDelete, SIGNAL( activated() ), this, SLOT( editDelete() ) ); +#endif + + actionEditSelectAll = new QAction( tr( "Select All" ), QPixmap(), tr( "Select &All" ), CTRL + Key_A, this, 0 ); + actionEditSelectAll->setStatusTip( tr( "Selects all widgets" ) ); + actionEditSelectAll->setWhatsThis( whatsThisFrom( "Edit|Select All" ) ); + connect( actionEditSelectAll, SIGNAL( activated() ), this, SLOT( editSelectAll() ) ); + actionEditSelectAll->setEnabled( TRUE ); + + actionEditRaise = new QAction( tr( "Bring to Front" ), createIconSet("designer_editraise.png"), tr( "Bring to &Front" ), 0, this, 0 ); + actionEditRaise->setStatusTip( tr( "Raises the selected widgets" ) ); + actionEditRaise->setWhatsThis( tr( "Raises the selected widgets" ) ); + connect( actionEditRaise, SIGNAL( activated() ), this, SLOT( editRaise() ) ); + actionEditRaise->setEnabled( FALSE ); + + actionEditLower = new QAction( tr( "Send to Back" ), createIconSet("designer_editlower.png"), tr( "Send to &Back" ), 0, this, 0 ); + actionEditLower->setStatusTip( tr( "Lowers the selected widgets" ) ); + actionEditLower->setWhatsThis( tr( "Lowers the selected widgets" ) ); + connect( actionEditLower, SIGNAL( activated() ), this, SLOT( editLower() ) ); + actionEditLower->setEnabled( FALSE ); + + actionEditAccels = new QAction( tr( "Check Accelerators" ), QPixmap(), + tr( "Chec&k Accelerators" ), ALT + Key_R, this, 0 ); + actionEditAccels->setStatusTip( tr("Checks if the accelerators used in the form are unique") ); + actionEditAccels->setWhatsThis( whatsThisFrom( "Edit|Check Accelerator" ) ); + connect( actionEditAccels, SIGNAL( activated() ), this, SLOT( editAccels() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditAccels, SLOT( setEnabled(bool) ) ); + + actionEditFunctions = new QAction( tr( "Slots" ), createIconSet("designer_editslots.png"), + tr( "S&lots..." ), 0, this, 0 ); + actionEditFunctions->setStatusTip( tr("Opens a dialog for editing slots") ); + actionEditFunctions->setWhatsThis( whatsThisFrom( "Edit|Slots" ) ); + connect( actionEditFunctions, SIGNAL( activated() ), this, SLOT( editFunctions() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditFunctions, SLOT( setEnabled(bool) ) ); + + actionEditConnections = new QAction( tr( "Connections" ), createIconSet("designer_connecttool.png"), + tr( "Co&nnections..." ), 0, this, 0 ); + actionEditConnections->setStatusTip( tr("Opens a dialog for editing connections") ); + actionEditConnections->setWhatsThis( whatsThisFrom( "Edit|Connections" ) ); + connect( actionEditConnections, SIGNAL( activated() ), this, SLOT( editConnections() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditConnections, SLOT( setEnabled(bool) ) ); + + actionEditSource = new QAction( tr( "Source" ), QIconSet(), + tr( "&Source..." ), CTRL + Key_E, this, 0 ); + actionEditSource->setStatusTip( tr("Opens an editor to edit the form's source code") ); + actionEditSource->setWhatsThis( whatsThisFrom( "Edit|Source" ) ); + connect( actionEditSource, SIGNAL( activated() ), this, SLOT( editSource() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditSource, SLOT( setEnabled(bool) ) ); + + actionEditFormSettings = new QAction( tr( "Form Settings" ), QPixmap(), + tr( "&Form Settings..." ), 0, this, 0 ); + actionEditFormSettings->setStatusTip( tr("Opens a dialog to change the form's settings") ); + actionEditFormSettings->setWhatsThis( whatsThisFrom( "Edit|Form Settings" ) ); + connect( actionEditFormSettings, SIGNAL( activated() ), this, SLOT( editFormSettings() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), actionEditFormSettings, SLOT( setEnabled(bool) ) ); + + actionEditPreferences = new QAction( tr( "Preferences" ), QPixmap(), + tr( "Preferences..." ), 0, this, 0 ); + actionEditPreferences->setStatusTip( tr("Opens a dialog to change preferences") ); + actionEditPreferences->setWhatsThis( whatsThisFrom( "Edit|Preferences" ) ); + connect( actionEditPreferences, SIGNAL( activated() ), this, SLOT( editPreferences() ) ); + + QToolBar *tb = new QToolBar( this, "Edit" ); + tb->setCloseMode( QDockWindow::Undocked ); + QWhatsThis::add( tb, tr( "The Edit toolbar%1").arg(tr(toolbarHelp).arg("")) ); + addToolBar( tb, tr( "Edit" ) ); + actionEditUndo->addTo( tb ); + actionEditRedo->addTo( tb ); + tb->addSeparator(); + actionEditCut->addTo( tb ); + actionEditCopy->addTo( tb ); + actionEditPaste->addTo( tb ); +#if 0 + tb->addSeparator(); + actionEditLower->addTo( tb ); + actionEditRaise->addTo( tb ); +#endif + + QPopupMenu *menu = new QPopupMenu( this, "Edit" ); + connect( menu, SIGNAL( aboutToShow() ), this, SLOT( updateEditorUndoRedo() ) ); + menubar->insertItem( tr( "&Edit" ), menu ); + actionEditUndo->addTo( menu ); + actionEditRedo->addTo( menu ); + menu->insertSeparator(); + actionEditCut->addTo( menu ); + actionEditCopy->addTo( menu ); + actionEditPaste->addTo( menu ); + actionEditDelete->addTo( menu ); + actionEditSelectAll->addTo( menu ); + actionEditAccels->addTo( menu ); +#if 0 + menu->insertSeparator(); + actionEditLower->addTo( menu ); + actionEditRaise->addTo( menu ); +#endif + menu->insertSeparator(); + if ( !singleProjectMode() ) { + actionEditFunctions->addTo( menu ); + actionEditConnections->addTo( menu ); + } + actionEditFormSettings->addTo( menu ); + menu->insertSeparator(); + actionEditPreferences->addTo( menu ); +} + +void MainWindow::setupSearchActions() +{ + actionSearchFind = new QAction( tr( "Find" ), createIconSet( "designer_searchfind.png" ), + tr( "&Find..." ), CTRL + Key_F, this, 0 ); + connect( actionSearchFind, SIGNAL( activated() ), this, SLOT( searchFind() ) ); + actionSearchFind->setEnabled( FALSE ); + actionSearchFind->setWhatsThis( whatsThisFrom( "Search|Find" ) ); + + actionSearchIncremetal = new QAction( tr( "Find Incremental" ), QIconSet(), + tr( "Find &Incremental" ), ALT + Key_I, this, 0 ); + connect( actionSearchIncremetal, SIGNAL( activated() ), this, SLOT( searchIncremetalFindMenu() ) ); + actionSearchIncremetal->setEnabled( FALSE ); + actionSearchIncremetal->setWhatsThis( whatsThisFrom( "Search|Find Incremental" ) ); + + actionSearchReplace = new QAction( tr( "Replace" ), QIconSet(), + tr( "&Replace..." ), CTRL + Key_R, this, 0 ); + connect( actionSearchReplace, SIGNAL( activated() ), this, SLOT( searchReplace() ) ); + actionSearchReplace->setEnabled( FALSE ); + actionSearchReplace->setWhatsThis( whatsThisFrom( "Search|Replace" ) ); + + actionSearchGotoLine = new QAction( tr( "Goto Line" ), QIconSet(), + tr( "&Goto Line..." ), ALT + Key_G, this, 0 ); + connect( actionSearchGotoLine, SIGNAL( activated() ), this, SLOT( searchGotoLine() ) ); + actionSearchGotoLine->setEnabled( FALSE ); + actionSearchGotoLine->setWhatsThis( whatsThisFrom( "Search|Goto line" ) ); + + QToolBar *tb = new QToolBar( this, "Search" ); + tb->setCloseMode( QDockWindow::Undocked ); + addToolBar( tb, tr( "Search" ) ); + + actionSearchFind->addTo( tb ); + incrementalSearch = new QLineEdit( tb ); + QToolTip::add( incrementalSearch, tr( "Incremetal Search (Alt+I)" ) ); + connect( incrementalSearch, SIGNAL( textChanged( const QString & ) ), + this, SLOT( searchIncremetalFind() ) ); + connect( incrementalSearch, SIGNAL( returnPressed() ), + this, SLOT( searchIncremetalFindNext() ) ); + incrementalSearch->setEnabled( FALSE ); + + QPopupMenu *menu = new QPopupMenu( this, "Search" ); + menubar->insertItem( tr( "&Search" ), menu ); + actionSearchFind->addTo( menu ); + actionSearchIncremetal->addTo( menu ); + actionSearchReplace->addTo( menu ); + menu->insertSeparator(); + actionSearchGotoLine->addTo( menu ); +} + +void MainWindow::setupLayoutActions() +{ + if ( !actionGroupTools ) { + actionGroupTools = new QActionGroup( this ); + actionGroupTools->setExclusive( TRUE ); + connect( actionGroupTools, SIGNAL( selected(QAction*) ), this, SLOT( toolSelected(QAction*) ) ); + } + + actionEditAdjustSize = new QAction( tr( "Adjust Size" ), createIconSet("designer_adjustsize.png"), + tr( "Adjust &Size" ), CTRL + Key_J, this, 0 ); + actionEditAdjustSize->setStatusTip(tr("Adjusts the size of the selected widget") ); + actionEditAdjustSize->setWhatsThis( whatsThisFrom( "Layout|Adjust Size" ) ); + connect( actionEditAdjustSize, SIGNAL( activated() ), this, SLOT( editAdjustSize() ) ); + actionEditAdjustSize->setEnabled( FALSE ); + + actionEditHLayout = new QAction( tr( "Lay Out Horizontally" ), createIconSet("designer_edithlayout.png"), + tr( "Lay Out &Horizontally" ), CTRL + Key_H, this, 0 ); + actionEditHLayout->setStatusTip(tr("Lays out the selected widgets horizontally") ); + actionEditHLayout->setWhatsThis( whatsThisFrom( "Layout|Lay Out Horizontally" ) ); + connect( actionEditHLayout, SIGNAL( activated() ), this, SLOT( editLayoutHorizontal() ) ); + actionEditHLayout->setEnabled( FALSE ); + + actionEditVLayout = new QAction( tr( "Lay Out Vertically" ), createIconSet("designer_editvlayout.png"), + tr( "Lay Out &Vertically" ), CTRL + Key_L, this, 0 ); + actionEditVLayout->setStatusTip(tr("Lays out the selected widgets vertically") ); + actionEditVLayout->setWhatsThis( whatsThisFrom( "Layout|Lay Out Vertically" ) ); + connect( actionEditVLayout, SIGNAL( activated() ), this, SLOT( editLayoutVertical() ) ); + actionEditVLayout->setEnabled( FALSE ); + + actionEditGridLayout = new QAction( tr( "Lay Out in a Grid" ), createIconSet("designer_editgrid.png"), + tr( "Lay Out in a &Grid" ), CTRL + Key_G, this, 0 ); + actionEditGridLayout->setStatusTip(tr("Lays out the selected widgets in a grid") ); + actionEditGridLayout->setWhatsThis( whatsThisFrom( "Layout|Lay Out in a Grid" ) ); + connect( actionEditGridLayout, SIGNAL( activated() ), this, SLOT( editLayoutGrid() ) ); + actionEditGridLayout->setEnabled( FALSE ); + + actionEditSplitHorizontal = new QAction( tr( "Lay Out Horizontally (in Splitter)" ), createIconSet("designer_editvlayoutsplit.png"), + tr( "Lay Out Horizontally (in S&plitter)" ), 0, this, 0 ); + actionEditSplitHorizontal->setStatusTip(tr("Lays out the selected widgets horizontally in a splitter") ); + actionEditSplitHorizontal->setWhatsThis( whatsThisFrom( "Layout|Lay Out Horizontally (in Splitter)" ) ); + connect( actionEditSplitHorizontal, SIGNAL( activated() ), this, SLOT( editLayoutHorizontalSplit() ) ); + actionEditSplitHorizontal->setEnabled( FALSE ); + + actionEditSplitVertical = new QAction( tr( "Lay Out Vertically (in Splitter)" ), createIconSet("designer_edithlayoutsplit.png"), + tr( "Lay Out Vertically (in Sp&litter)" ), 0, this, 0 ); + actionEditSplitVertical->setStatusTip(tr("Lays out the selected widgets vertically in a splitter") ); + actionEditSplitVertical->setWhatsThis( whatsThisFrom( "Layout|Lay Out Vertically (in Splitter)" ) ); + connect( actionEditSplitVertical, SIGNAL( activated() ), this, SLOT( editLayoutVerticalSplit() ) ); + actionEditSplitVertical->setEnabled( FALSE ); + + actionEditBreakLayout = new QAction( tr( "Break Layout" ), createIconSet("designer_editbreaklayout.png"), + tr( "&Break Layout" ), CTRL + Key_B, this, 0 ); + actionEditBreakLayout->setStatusTip(tr("Breaks the selected layout") ); + actionEditBreakLayout->setWhatsThis( whatsThisFrom( "Layout|Break Layout" ) ); + connect( actionEditBreakLayout, SIGNAL( activated() ), this, SLOT( editBreakLayout() ) ); + actionEditBreakLayout->setEnabled( FALSE ); + + int id = WidgetDatabase::idFromClassName( "Spacer" ); + actionInsertSpacer = new WidgetAction( "Layout", actionGroupTools, QString::number( id ).latin1() ); + actionInsertSpacer->setToggleAction( TRUE ); + actionInsertSpacer->setText( WidgetDatabase::className( id ) ); + actionInsertSpacer->setMenuText( tr( "Add ") + WidgetDatabase::className( id ) ); + actionInsertSpacer->setIconSet( WidgetDatabase::iconSet( id ) ); + actionInsertSpacer->setToolTip( WidgetDatabase::toolTip( id ) ); + actionInsertSpacer->setStatusTip( tr( "Insert a %1").arg(WidgetDatabase::toolTip( id )) ); + actionInsertSpacer->setWhatsThis( QString("A %1

    %2

    " + "

    Click to insert a single %3," + "or double click to keep the tool selected.") + .arg(WidgetDatabase::toolTip( id )) + .arg(WidgetDatabase::whatsThis( id )) + .arg(WidgetDatabase::toolTip( id ) )); + + actionInsertSpacer->addTo( commonWidgetsToolBar ); + commonWidgetsPage.append( actionInsertSpacer ); + QWidget *w; + commonWidgetsToolBar->setStretchableWidget( ( w = new QWidget( commonWidgetsToolBar ) ) ); + w->setBackgroundMode( commonWidgetsToolBar->backgroundMode() ); + QWhatsThis::add( layoutToolBar, tr( "The Layout toolbar%1" ).arg(tr(toolbarHelp).arg("")) ); + actionEditAdjustSize->addTo( layoutToolBar ); + layoutToolBar->addSeparator(); + actionEditHLayout->addTo( layoutToolBar ); + actionEditVLayout->addTo( layoutToolBar ); + actionEditGridLayout->addTo( layoutToolBar ); + actionEditSplitHorizontal->addTo( layoutToolBar ); + actionEditSplitVertical->addTo( layoutToolBar ); + actionEditBreakLayout->addTo( layoutToolBar ); + layoutToolBar->addSeparator(); + actionInsertSpacer->addTo( layoutToolBar ); + + QPopupMenu *menu = new QPopupMenu( this, "Layout" ); + layoutMenu = menu; + menubar->insertItem( tr( "&Layout" ), menu, toolsMenuId + 1 ); + actionEditAdjustSize->addTo( menu ); + menu->insertSeparator(); + actionEditHLayout->addTo( menu ); + actionEditVLayout->addTo( menu ); + actionEditGridLayout->addTo( menu ); + actionEditSplitHorizontal->addTo( menu ); + actionEditSplitVertical->addTo( menu ); + actionEditBreakLayout->addTo( menu ); + menu->insertSeparator(); + actionInsertSpacer->addTo( menu ); +} + +void MainWindow::setupToolActions() +{ + if ( !actionGroupTools ) { + actionGroupTools = new QActionGroup( this ); + actionGroupTools->setExclusive( TRUE ); + connect( actionGroupTools, SIGNAL( selected(QAction*) ), + this, SLOT( toolSelected(QAction*) ) ); + } + + actionPointerTool = new QAction( tr("Pointer"), createIconSet("designer_pointer.png"), + tr("&Pointer"), Key_F2, + actionGroupTools, + QString::number(POINTER_TOOL).latin1(), TRUE ); + actionPointerTool->setStatusTip( tr("Selects the pointer tool") ); + actionPointerTool->setWhatsThis( whatsThisFrom( "Tools|Pointer" ) ); + + actionConnectTool = new QAction( tr("Connect Signal/Slots"), + createIconSet("designer_connecttool.png"), + tr("&Connect Signal/Slots"), + singleProjectMode() ? 0 : Key_F3, + actionGroupTools, + QString::number(CONNECT_TOOL).latin1(), TRUE ); + actionConnectTool->setStatusTip( tr("Selects the connection tool") ); + actionConnectTool->setWhatsThis( whatsThisFrom( "Tools|Connect Signals and Slots" ) ); + + actionOrderTool = new QAction( tr("Tab Order"), createIconSet("designer_ordertool.png"), + tr("Tab &Order"), Key_F4, + actionGroupTools, + QString::number(ORDER_TOOL).latin1(), TRUE ); + actionOrderTool->setStatusTip( tr("Selects the tab order tool") ); + actionOrderTool->setWhatsThis( whatsThisFrom( "Tools|Tab Order" ) ); + + actionBuddyTool = new QAction( tr( "Set Buddy" ), createIconSet( "designer_setbuddy.png" ), + tr( "Set &Buddy" ), Key_F12, + actionGroupTools, QString::number( BUDDY_TOOL ).latin1(), + TRUE ); + actionBuddyTool->setStatusTip( tr( "Sets a buddy to a label" ) ); + actionBuddyTool->setWhatsThis( whatsThisFrom( "Tools|Set Buddy" ) ); + + QToolBar *tb = new QToolBar( this, "Tools" ); + tb->setCloseMode( QDockWindow::Undocked ); + toolsToolBar = tb; + QWhatsThis::add( tb, tr( "The Tools toolbar%1" ).arg(tr(toolbarHelp).arg("")) ); + + addToolBar( tb, tr( "Tools" ), QMainWindow::DockTop, FALSE ); + actionPointerTool->addTo( tb ); + if ( !singleProjectMode() ) + actionConnectTool->addTo( tb ); + actionOrderTool->addTo( tb ); + actionBuddyTool->addTo( tb ); + + QPopupMenu *mmenu = new QPopupMenu( this, "Tools" ); + toolsMenu = mmenu; + toolsMenuId = 100; + menubar->insertItem( tr( "&Tools" ), mmenu, toolsMenuId ); + toolsMenuIndex = menubar->indexOf( toolsMenuId ); + actionPointerTool->addTo( mmenu ); + if ( !singleProjectMode() ) + actionConnectTool->addTo( mmenu ); + actionOrderTool->addTo( mmenu ); + actionBuddyTool->addTo( mmenu ); + mmenu->insertSeparator(); + + customWidgetToolBar = 0; + customWidgetMenu = 0; + + actionToolsCustomWidget = new QAction( tr("Custom Widgets"), + createIconSet( "designer_customwidget.png" ), + tr("Edit &Custom Widgets..."), 0, this, 0 ); + actionToolsCustomWidget->setStatusTip( tr("Opens a dialog to add and change " + "custom widgets") ); + actionToolsCustomWidget->setWhatsThis( whatsThisFrom( "Tools|Custom|Edit Custom" + "Widgets" ) ); + connect( actionToolsCustomWidget, SIGNAL( activated() ), + this, SLOT( toolsCustomWidget() ) ); + + for ( int j = 0; j < WidgetDatabase::numWidgetGroups(); ++j ) { + QString grp = WidgetDatabase::widgetGroup( j ); + if ( !WidgetDatabase::isGroupVisible( grp ) || + WidgetDatabase::isGroupEmpty( grp ) ) + continue; + QToolBar *tb = new QToolBar( this, grp.latin1() ); + tb->setCloseMode( QDockWindow::Undocked ); + widgetToolBars.append( tb ); + bool plural = grp[(int)grp.length()-1] == 's'; + if ( plural ) { + QWhatsThis::add( tb, tr( "The %1%2" ).arg(grp).arg(tr(toolbarHelp). + arg( tr(" Click on a button to insert a single widget, " + "or double click to insert multiple %1.") ).arg(grp)) ); + } else { + QWhatsThis::add( tb, tr( "The %1 Widgets%2" ).arg(grp).arg(tr(toolbarHelp). + arg( tr(" Click on a button to insert a single %1 widget, " + "or double click to insert multiple widgets.") ).arg(grp)) ); + } + addToolBar( tb, grp ); + tb->hide(); + QPopupMenu *menu = new QPopupMenu( this, grp.latin1() ); + mmenu->insertItem( grp, menu ); + + QToolBar *tb2 = new QToolBar( grp, 0, toolBox, FALSE, grp.latin1() ); + tb2->setFrameStyle( QFrame::NoFrame ); + tb2->setOrientation( Qt::Vertical ); + tb2->setBackgroundMode( PaletteBase ); + toolBox->addItem( tb2, grp ); + + if ( grp == "Custom" ) { + if ( !customWidgetMenu ) + actionToolsCustomWidget->addTo( menu ); + else + menu->insertSeparator(); + customWidgetMenu = menu; + customWidgetToolBar = tb; + } + + for ( int i = 0; i < WidgetDatabase::count(); ++i ) { + if ( WidgetDatabase::group( i ) != grp ) + continue; // only widgets, i.e. not forms and temp stuff + WidgetAction* a = + new WidgetAction( grp, actionGroupTools, QString::number( i ).latin1() ); + a->setToggleAction( TRUE ); + QString atext = WidgetDatabase::className( i ); + if ( atext[0] == 'Q' ) + atext = atext.mid(1); + while ( atext.length() && atext[0] >= 'a' && atext[0] <= 'z' ) + atext = atext.mid(1); + if ( atext.isEmpty() ) + atext = WidgetDatabase::className( i ); + a->setText( atext ); + QString ttip = WidgetDatabase::toolTip( i ); + a->setIconSet( WidgetDatabase::iconSet( i ) ); + a->setToolTip( ttip ); + if ( !WidgetDatabase::isWhatsThisLoaded() ) + WidgetDatabase::loadWhatsThis( documentationPath() ); + a->setStatusTip( tr( "Insert a %1").arg(WidgetDatabase::className( i )) ); + + QString whats = QString("A %1").arg( WidgetDatabase::className( i ) ); + if ( !WidgetDatabase::whatsThis( i ).isEmpty() ) + whats += QString("

    %1

    ").arg(WidgetDatabase::whatsThis( i )); + a->setWhatsThis( whats+ tr("

    Double click on this tool to keep it selected.

    ") ); + + if ( grp != "KDE" ) + a->addTo( tb ); + a->addTo( menu ); + a->addTo( tb2 ); + if ( WidgetDatabase::isCommon( i ) ) { + a->addTo( commonWidgetsToolBar ); + commonWidgetsPage.append( a ); + } + } + QWidget *w; + tb2->setStretchableWidget( ( w = new QWidget( tb2 ) ) ); + w->setBackgroundMode( tb2->backgroundMode() ); + } + + if ( !customWidgetToolBar ) { + QToolBar *tb = new QToolBar( this, "Custom Widgets" ); + tb->setCloseMode( QDockWindow::Undocked ); + QWhatsThis::add( tb, tr( "The Custom Widgets toolbar%1" + "

    Click Edit Custom Widgets..." + "in the Tools|Custom menu to " + "add and change custom widgets

    " ). + arg(tr(toolbarHelp). + arg( tr(" Click on the buttons to insert a single widget, " + "or double click to insert multiple widgets.") )) ); + addToolBar( tb, "Custom" ); + tb->hide(); + widgetToolBars.append( tb ); + customWidgetToolBar = tb; + QPopupMenu *menu = new QPopupMenu( this, "Custom Widgets" ); + mmenu->insertItem( "Custom", menu ); + customWidgetMenu = menu; + customWidgetToolBar->hide(); + actionToolsCustomWidget->addTo( customWidgetMenu ); + customWidgetMenu->insertSeparator(); + QToolBar *tb2 = new QToolBar( "Custom Widgets", 0, + toolBox, FALSE, "Custom Widgets" ); + tb2->setBackgroundMode(PaletteBase); + tb2->setOrientation( Qt::Vertical ); + tb2->setFrameStyle( QFrame::NoFrame ); + toolBox->addItem( tb2, "Custom Widgets" ); + customWidgetToolBar2 = tb2; + } + + QAction *a = new QAction( tr( "Configure Toolbox" ), tr( "Configure Toolbox..." ), 0, this ); + a->setStatusTip( tr( "Opens a dialog to configure the common " + "widgets page of the toolbox") ); + connect( a, SIGNAL( activated() ), this, SLOT( toolsConfigure() ) ); + mmenu->insertSeparator(); + a->addTo( mmenu ); + resetTool(); +} + +void MainWindow::setupFileActions() +{ + QToolBar* tb = new QToolBar( this, "File" ); + tb->setCloseMode( QDockWindow::Undocked ); + projectToolBar = tb; + + QWhatsThis::add( tb, tr( "The File toolbar%1" ).arg(tr(toolbarHelp).arg("")) ); + addToolBar( tb, tr( "File" ) ); + fileMenu = new QPopupMenu( this, "File" ); + menubar->insertItem( tr( "&File" ), fileMenu ); + + QAction *a = 0; + + if ( !singleProject ) { + a = new QAction( this, 0 ); + a->setText( tr( "New" ) ); + a->setToolTip( tr( "New Dialog or File" ) ); + a->setMenuText( tr( "&New..." ) ); + a->setIconSet( createIconSet("designer_filenew.png") ); + a->setAccel( CTRL + Key_N ); + a->setStatusTip( tr( "Creates a new project, form or source file." ) ); + a->setWhatsThis( whatsThisFrom( "File|New" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) ); + a->addTo( tb ); + a->addTo( fileMenu ); + } else { + actionGroupNew = new QActionGroup( this, 0, FALSE ); + a = actionGroupNew; + ( (QActionGroup*)a )->setUsesDropDown( TRUE ); + a->setText( tr( "New" ) ); + a->setMenuText( tr( "&New..." ) ); + a->setIconSet( createIconSet("designer_form.png") ); + a->setStatusTip( tr( "Creates a new dialog or file" ) ); + a->setWhatsThis( whatsThisFrom( "File|New" ) ); + + QAction *newForm = new QAction( a, 0 ); + newForm->setText( tr( "New Dialog" ) ); + newForm->setMenuText( tr( "&Dialog..." ) ); + newForm->setIconSet( createIconSet("designer_form.png") ); + newForm->setAccel( CTRL + Key_N ); + newForm->setStatusTip( tr( "Creates a new dialog." ) ); + connect( newForm, SIGNAL( activated() ), this, SLOT( fileNewDialog() ) ); + + QAction *newFile = new QAction( a, 0 ); + newFile->setText( tr( "New File" ) ); + newFile->setMenuText( tr( "&File..." ) ); + newFile->setIconSet( createIconSet("designer_filenew.png") ); + newFile->setAccel( ALT + Key_N ); + newFile->setStatusTip( tr( "Creates a new file." ) ); + connect( newFile, SIGNAL( activated() ), this, SLOT( fileNewFile() ) ); + actionNewFile = newFile; + + a->addTo( tb ); + a->addTo( fileMenu ); + + fileMenu->insertSeparator(); + } + + a = new QAction( this, 0 ); + a->setText( tr( "Open" ) ); + a->setMenuText( tr( "&Open..." ) ); + a->setIconSet( createIconSet("designer_fileopen.png") ); + a->setAccel( CTRL + Key_O ); + a->setStatusTip( tr( "Opens an existing project, form or source file ") ); + a->setWhatsThis( whatsThisFrom( "File|Open" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileOpen() ) ); + if ( !singleProject ) { + a->addTo( tb ); + a->addTo( fileMenu ); + fileMenu->insertSeparator(); + } + + + a = new QAction( this, 0 ); + a->setText( tr( "Close" ) ); + a->setMenuText( tr( "&Close" ) ); + a->setStatusTip( tr( "Closes the current project or document" ) ); + a->setWhatsThis(whatsThisFrom( "File|Close" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileClose() ) ); + connect( this, SIGNAL( hasActiveWindowOrProject(bool) ), a, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) { + a->addTo( fileMenu ); + fileMenu->insertSeparator(); + } + + a = new QAction( this, 0 ); + actionFileSave = a; + a->setText( tr( "Save" ) ); + a->setMenuText( tr( "&Save" ) ); + a->setIconSet( createIconSet("designer_filesave.png") ); + a->setAccel( CTRL + Key_S ); + a->setStatusTip( tr( "Saves the current project or document" ) ); + a->setWhatsThis(whatsThisFrom( "File|Save" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileSave() ) ); + connect( this, SIGNAL( hasActiveWindowOrProject(bool) ), a, SLOT( setEnabled(bool) ) ); + a->addTo( tb ); + a->addTo( fileMenu ); + + a = new QAction( this, 0 ); + a->setText( tr( "Save As" ) ); + a->setMenuText( tr( "Save &As..." ) ); + a->setStatusTip( tr( "Saves the current form with a new filename" ) ); + a->setWhatsThis( whatsThisFrom( "File|Save As" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileSaveAs() ) ); + connect( this, SIGNAL( hasActiveWindow(bool) ), a, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) + a->addTo( fileMenu ); + + a = new QAction( this, 0 ); + a->setText( tr( "Save All" ) ); + a->setMenuText( tr( "Sa&ve All" ) ); + a->setStatusTip( tr( "Saves all open documents" ) ); + a->setWhatsThis( whatsThisFrom( "File|Save All" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileSaveAll() ) ); + connect( this, SIGNAL( hasActiveWindowOrProject(bool) ), a, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) { + a->addTo( fileMenu ); + fileMenu->insertSeparator(); + } + + a = new QAction( this, 0 ); + a->setText( tr( "Create Template" ) ); + a->setMenuText( tr( "Create &Template..." ) ); + a->setStatusTip( tr( "Creates a new template" ) ); + a->setWhatsThis( whatsThisFrom( "File|Create Template" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( fileCreateTemplate() ) ); + if ( !singleProject ) + a->addTo( fileMenu ); + + if ( !singleProject ) + fileMenu->insertSeparator(); + + recentlyFilesMenu = new QPopupMenu( this ); + recentlyProjectsMenu = new QPopupMenu( this ); + + if ( !singleProject ) { + fileMenu->insertItem( tr( "Recently opened files " ), recentlyFilesMenu ); + fileMenu->insertItem( tr( "Recently opened projects" ), recentlyProjectsMenu ); + } + + connect( recentlyFilesMenu, SIGNAL( aboutToShow() ), + this, SLOT( setupRecentlyFilesMenu() ) ); + connect( recentlyProjectsMenu, SIGNAL( aboutToShow() ), + this, SLOT( setupRecentlyProjectsMenu() ) ); + connect( recentlyFilesMenu, SIGNAL( activated( int ) ), + this, SLOT( recentlyFilesMenuActivated( int ) ) ); + connect( recentlyProjectsMenu, SIGNAL( activated( int ) ), + this, SLOT( recentlyProjectsMenuActivated( int ) ) ); + + if ( !singleProject ) + fileMenu->insertSeparator(); + + a = new QAction( this, 0 ); + actionFileExit = a; + a->setAccel(CTRL + Key_Q); + if ( !singleProjectMode() ) { + a->setText( tr( "Exit" ) ); + a->setMenuText( tr( "E&xit" ) ); + a->setStatusTip( tr( "Quits the application and prompts to save any changed forms, source files or project settings" ) ); + a->setWhatsThis( whatsThisFrom( "File|Exit" ) ); + } else { + a->setText( tr( "Close" ) ); + a->setMenuText( tr( "&Close" ) ); + } + connect( a, SIGNAL( activated() ), this, SLOT( fileQuit() ) ); + a->addTo( fileMenu ); +} + +void MainWindow::setupProjectActions() +{ + projectMenu = new QPopupMenu( this, "Project" ); + menubar->insertItem( tr( "Pr&oject" ), projectMenu ); + + QActionGroup *ag = new QActionGroup( this, 0 ); + ag->setText( tr( "Active Project" ) ); + ag->setMenuText( tr( "Active Project" ) ); + ag->setExclusive( TRUE ); + ag->setUsesDropDown( TRUE ); + connect( ag, SIGNAL( selected( QAction * ) ), this, SLOT( projectSelected( QAction * ) ) ); + connect( ag, SIGNAL( selected( QAction * ) ), this, SIGNAL( projectChanged() ) ); + QAction *a = new QAction( tr( "" ), tr( "" ), 0, ag, 0, TRUE ); + eProject = new Project( "", tr( "" ), projectSettingsPluginManager, TRUE ); + projects.insert( a, eProject ); + a->setOn( TRUE ); + ag->addTo( projectMenu ); + ag->addTo( projectToolBar ); + actionGroupProjects = ag; + + if ( !singleProject ) + projectMenu->insertSeparator(); + + a = new QAction( tr( "Add File" ), QPixmap(), tr( "&Add File..." ), 0, this, 0 ); + a->setStatusTip( tr("Adds a file to the current project") ); + a->setWhatsThis( whatsThisFrom( "Project|Add File" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( projectInsertFile() ) ); + a->setEnabled( FALSE ); + connect( this, SIGNAL( hasNonDummyProject(bool) ), a, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) + a->addTo( projectMenu ); + + QAction* actionEditPixmapCollection = new QAction( tr( "Image Collection..." ), QPixmap(), + tr( "&Image Collection..." ), 0, this, 0 ); + actionEditPixmapCollection->setStatusTip( tr("Opens a dialog for editing the current project's image collection") ); + actionEditPixmapCollection->setWhatsThis( whatsThisFrom( "Project|Image Collection" ) ); + connect( actionEditPixmapCollection, SIGNAL( activated() ), this, SLOT( editPixmapCollection() ) ); + actionEditPixmapCollection->setEnabled( FALSE ); + connect( this, SIGNAL( hasNonDummyProject(bool) ), actionEditPixmapCollection, SLOT( setEnabled(bool) ) ); + actionEditPixmapCollection->addTo( projectMenu ); + +#ifndef QT_NO_SQL + QAction* actionEditDatabaseConnections = new QAction( tr( "Database Connections..." ), QPixmap(), + tr( "&Database Connections..." ), 0, this, 0 ); + actionEditDatabaseConnections->setStatusTip( tr("Opens a dialog for editing the current project's database connections") ); + actionEditDatabaseConnections->setWhatsThis( whatsThisFrom( "Project|Database Connections" ) ); + connect( actionEditDatabaseConnections, SIGNAL( activated() ), this, SLOT( editDatabaseConnections() ) ); + //actionEditDatabaseConnections->setEnabled( FALSE ); + //connect( this, SIGNAL( hasNonDummyProject(bool) ), actionEditDatabaseConnections, SLOT( setEnabled(bool) ) ); + if ( !singleProject ) + actionEditDatabaseConnections->addTo( projectMenu ); +#endif + + QAction* actionEditProjectSettings = new QAction( tr( "Project Settings..." ), QPixmap(), + tr( "&Project Settings..." ), 0, this, 0 ); + actionEditProjectSettings->setStatusTip( tr("Opens a dialog to change the project's settings") ); + actionEditProjectSettings->setWhatsThis( whatsThisFrom( "Project|Project Settings" ) ); + connect( actionEditProjectSettings, SIGNAL( activated() ), this, SLOT( editProjectSettings() ) ); + actionEditProjectSettings->setEnabled( FALSE ); + connect( this, SIGNAL( hasNonDummyProject(bool) ), actionEditProjectSettings, SLOT( setEnabled(bool) ) ); + actionEditProjectSettings->addTo( projectMenu ); + +} + +void MainWindow::setupPreviewActions() +{ + QAction* a = 0; + QPopupMenu *menu = new QPopupMenu( this, "Preview" ); + layoutMenu = menu; + menubar->insertItem( tr( "&Preview" ), menu, toolsMenuId + 2 ); + + a = new QAction( tr( "Preview Form" ), QPixmap(), tr( "Preview &Form" ), 0, this, 0 ); + a->setAccel( CTRL + Key_T ); + a->setStatusTip( tr("Opens a preview") ); + a->setWhatsThis( whatsThisFrom( "Preview|Preview Form" ) ); + connect( a, SIGNAL( activated() ), this, SLOT( previewForm() ) ); + connect( this, SIGNAL( hasActiveForm(bool) ), a, SLOT( setEnabled(bool) ) ); + a->addTo( menu ); + + menu->insertSeparator(); + + QSignalMapper *mapper = new QSignalMapper( this ); + connect( mapper, SIGNAL(mapped(const QString&)), this, SLOT(previewForm(const QString&)) ); + QStringList styles = QStyleFactory::keys(); + for ( QStringList::Iterator it = styles.begin(); it != styles.end(); ++it ) { + QString info; + if ( *it == "Motif" ) + info = tr( "The preview will use the Motif look and feel which is used as the default style on most UNIX systems." ); + else if ( *it == "Windows" ) + info = tr( "The preview will use the Windows look and feel." ); + else if ( *it == "Platinum" ) + info = tr( "The preview will use the Platinum look and feel which is similar to the Macinosh GUI style." ); + else if ( *it == "CDE" ) + info = tr( "The preview will use the CDE look and feel which is similar to some versions of the Common Desktop Environment." ); + else if ( *it == "SGI" ) + info = tr( "The preview will use the Motif look and feel which is used as the default style on SGI systems." ); + else if ( *it == "MotifPlus" ) + info = tr( "The preview will use the advanced Motif look and feel used by the GIMP toolkit (GTK) on Linux." ); + + a = new QAction( tr( "Preview Form in %1 Style" ).arg( *it ), QPixmap(), + tr( "... in %1 Style" ).arg( *it ), 0, this, 0 ); + a->setStatusTip( tr("Opens a preview in %1 style").arg( *it ) ); + a->setWhatsThis( tr("Open a preview in %1 style." + "

    Use the preview to test the design and " + "signal-slot connections of the current form. %2

    ").arg( *it ).arg( info ) ); + mapper->setMapping( a, *it ); + connect( a, SIGNAL(activated()), mapper, SLOT(map()) ); + connect( this, SIGNAL( hasActiveForm(bool) ), a, SLOT( setEnabled(bool) ) ); + a->addTo( menu ); + } +} + +void MainWindow::setupWindowActions() +{ + static bool windowActionsSetup = FALSE; + if ( !windowActionsSetup ) { + windowActionsSetup = TRUE; + + actionWindowTile = new QAction( tr( "Tile" ), tr( "&Tile" ), 0, this ); + actionWindowTile->setStatusTip( tr("Tiles the windows so that they are all visible") ); + actionWindowTile->setWhatsThis( whatsThisFrom( "Window|Tile" ) ); + connect( actionWindowTile, SIGNAL( activated() ), qworkspace, SLOT( tile() ) ); + actionWindowCascade = new QAction( tr( "Cascade" ), tr( "&Cascade" ), 0, this ); + actionWindowCascade->setStatusTip( tr("Cascades the windows so that all their title bars are visible") ); + actionWindowCascade->setWhatsThis( whatsThisFrom( "Window|Cascade" ) ); + connect( actionWindowCascade, SIGNAL( activated() ), qworkspace, SLOT( cascade() ) ); + + actionWindowClose = new QAction( tr( "Close" ), tr( "Cl&ose" ), CTRL + Key_F4, this ); + actionWindowClose->setStatusTip( tr( "Closes the active window") ); + actionWindowClose->setWhatsThis( whatsThisFrom( "Window|Close" ) ); + connect( actionWindowClose, SIGNAL( activated() ), qworkspace, SLOT( closeActiveWindow() ) ); + + actionWindowCloseAll = new QAction( tr( "Close All" ), tr( "Close Al&l" ), 0, this ); + actionWindowCloseAll->setStatusTip( tr( "Closes all form windows") ); + actionWindowCloseAll->setWhatsThis( whatsThisFrom( "Window|Close All" ) ); + connect( actionWindowCloseAll, SIGNAL( activated() ), qworkspace, SLOT( closeAllWindows() ) ); + + actionWindowNext = new QAction( tr( "Next" ), tr( "Ne&xt" ), CTRL + Key_F6, this ); + actionWindowNext->setStatusTip( tr( "Activates the next window" ) ); + actionWindowNext->setWhatsThis( whatsThisFrom( "Window|Next" ) ); + connect( actionWindowNext, SIGNAL( activated() ), qworkspace, SLOT( activateNextWindow() ) ); + + actionWindowPrevious = new QAction( tr( "Previous" ), tr( "Pre&vious" ), CTRL + SHIFT + Key_F6, this ); + actionWindowPrevious->setStatusTip( tr( "Activates the previous window" ) ); + actionWindowPrevious->setWhatsThis( whatsThisFrom( "Window|Previous" ) ); + connect( actionWindowPrevious, SIGNAL( activated() ), qworkspace, SLOT( activatePreviousWindow() ) ); + } + + if ( !windowMenu ) { + windowMenu = new QPopupMenu( this, "Window" ); + menubar->insertItem( tr( "&Window" ), windowMenu ); + connect( windowMenu, SIGNAL( aboutToShow() ), + this, SLOT( setupWindowActions() ) ); + } else { + windowMenu->clear(); + } + + actionWindowClose->addTo( windowMenu ); + actionWindowCloseAll->addTo( windowMenu ); + windowMenu->insertSeparator(); + actionWindowNext->addTo( windowMenu ); + actionWindowPrevious->addTo( windowMenu ); + windowMenu->insertSeparator(); + actionWindowTile->addTo( windowMenu ); + actionWindowCascade->addTo( windowMenu ); + windowMenu->insertSeparator(); + windowMenu->insertItem( tr( "Vie&ws" ), createDockWindowMenu( NoToolBars ) ); + windowMenu->insertItem( tr( "Tool&bars" ), createDockWindowMenu( OnlyToolBars ) ); + QWidgetList windows = qworkspace->windowList(); + if ( windows.count() && formWindow() ) + windowMenu->insertSeparator(); + int j = 0; + for ( int i = 0; i < int( windows.count() ); ++i ) { + QWidget *w = windows.at( i ); + if ( !::qt_cast(w) && !::qt_cast(w) ) + continue; + if ( ::qt_cast(w) && ( ( (FormWindow*)w )->isFake() ) ) + continue; + j++; + QString itemText; + if ( j < 10 ) + itemText = QString("&%1 ").arg( j ); + if ( ::qt_cast(w) ) + itemText += w->name(); + else + itemText += w->caption(); + + int id = windowMenu->insertItem( itemText, this, SLOT( windowsMenuActivated( int ) ) ); + windowMenu->setItemParameter( id, i ); + windowMenu->setItemChecked( id, qworkspace->activeWindow() == windows.at( i ) ); + } +} + +void MainWindow::setupHelpActions() +{ + actionHelpContents = new QAction( tr( "Contents" ), tr( "&Contents" ), Key_F1, this, 0 ); + actionHelpContents->setStatusTip( tr("Opens the online help") ); + actionHelpContents->setWhatsThis( whatsThisFrom( "Help|Contents" ) ); + connect( actionHelpContents, SIGNAL( activated() ), this, SLOT( helpContents() ) ); + + actionHelpManual = new QAction( tr( "Manual" ), tr( "&Manual" ), CTRL + Key_M, this, 0 ); + actionHelpManual->setStatusTip( tr("Opens the Qt Designer manual") ); + actionHelpManual->setWhatsThis( whatsThisFrom( "Help|Manual" ) ); + connect( actionHelpManual, SIGNAL( activated() ), this, SLOT( helpManual() ) ); + + actionHelpAbout = new QAction( tr("About"), QPixmap(), tr("&About"), 0, this, 0 ); + actionHelpAbout->setStatusTip( tr("Displays information about Qt Designer") ); + actionHelpAbout->setWhatsThis( whatsThisFrom( "Help|About" ) ); + connect( actionHelpAbout, SIGNAL( activated() ), this, SLOT( helpAbout() ) ); + + actionHelpAboutQt = new QAction( tr("About Qt"), QPixmap(), tr("About &Qt"), 0, this, 0 ); + actionHelpAboutQt->setStatusTip( tr("Displays information about the Qt Toolkit") ); + actionHelpAboutQt->setWhatsThis( whatsThisFrom( "Help|About Qt" ) ); + connect( actionHelpAboutQt, SIGNAL( activated() ), this, SLOT( helpAboutQt() ) ); + +#if 0 //defined(QT_NON_COMMERCIAL) + // ### not used anymore -- should be deleted? + actionHelpRegister = new QAction( tr("Register Qt"), QPixmap(), tr("&Register Qt..."), 0, this, 0 ); + actionHelpRegister->setStatusTip( tr("Opens a web browser at the evaluation form on www.trolltech.com") ); + actionHelpRegister->setWhatsThis( tr("Register with Trolltech") ); + connect( actionHelpRegister, SIGNAL( activated() ), this, SLOT( helpRegister() ) ); +#endif + + actionHelpWhatsThis = new QAction( tr("What's This?"), QIconSet( whatsthis_image, whatsthis_image ), + tr("What's This?"), SHIFT + Key_F1, this, 0 ); + actionHelpWhatsThis->setStatusTip( tr("\"What's This?\" context sensitive help") ); + actionHelpWhatsThis->setWhatsThis( whatsThisFrom( "Help|What's This?" ) ); + connect( actionHelpWhatsThis, SIGNAL( activated() ), this, SLOT( whatsThis() ) ); + + QToolBar *tb = new QToolBar( this, "Help" ); + tb->setCloseMode( QDockWindow::Undocked ); + QWhatsThis::add( tb, tr( "The Help toolbar%1" ).arg(tr(toolbarHelp).arg("") )); + addToolBar( tb, tr( "Help" ) ); + actionHelpWhatsThis->addTo( tb ); + + QPopupMenu *menu = new QPopupMenu( this, "Help" ); + menubar->insertSeparator(); + menubar->insertItem( tr( "&Help" ), menu ); + actionHelpContents->addTo( menu ); + actionHelpManual->addTo( menu ); + menu->insertSeparator(); + actionHelpAbout->addTo( menu ); + actionHelpAboutQt->addTo( menu ); +#if 0 //defined(QT_NON_COMMERCIAL) + // ### not used anymore -- should be deleted? + actionHelpRegister->addTo( menu ); +#endif + + menu->insertSeparator(); + actionHelpWhatsThis->addTo( menu ); +} + +void MainWindow::fileNew() +{ + statusBar()->message( tr( "Create a new project, form or source file...") ); + NewForm dlg( this, projectNames(), currentProject->projectName(), templatePath() ); + dlg.exec(); + statusBar()->clear(); +} + +void MainWindow::fileNewDialog() +{ + static int forms = 0; + QString n = "Dialog" + QString::number( ++forms ); + while ( currentProject->findFormFile( n + ".ui" ) ) + n = "Dialog" + QString::number( ++forms ); + FormWindow *fw = 0; + FormFile *ff = new FormFile( n + ".ui", FALSE, currentProject ); + fw = new FormWindow( ff, MainWindow::self, MainWindow::self->qWorkspace(), n ); + ff->setModified( TRUE ); + currentProject->setModified( TRUE ); + workspace()->update(); + fw->setProject( currentProject ); + MetaDataBase::addEntry( fw ); + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QDialog" ), fw, n.latin1() ); + fw->setMainContainer( w ); + fw->setCaption( n ); + fw->resize( 600, 480 ); + insertFormWindow( fw ); + fw->killAccels( fw ); + fw->project()->setModified( TRUE ); + fw->setFocus(); + fw->setSavePixmapInProject( TRUE ); + fw->setSavePixmapInline( FALSE ); +} + +void MainWindow::fileNewFile() +{ + QString name = QInputDialog::getText( tr( "Name of File" ), tr( "Enter the name of the new source file:" ) ); + if ( name.isEmpty() ) + return; + if ( name.right( 3 ) != ".qs" ) + name += ".qs"; + SourceFile *f = new SourceFile( name, FALSE, currentProject ); + MainWindow::self->editSource( f ); + f->setModified( TRUE ); + currentProject->setModified( TRUE ); + workspace()->update(); +} + +void MainWindow::fileQuit() +{ + close(); + if ( !singleProjectMode() ) + qApp->closeAllWindows(); +} + +void MainWindow::fileClose() +{ + if ( !currentProject->isDummy() ) { + fileCloseProject(); + } else { + QWidget *w = qworkspace->activeWindow(); + if ( w ) { + if ( ::qt_cast(w) ) + ( (FormWindow*)w )->formFile()->close(); + else if ( ::qt_cast(w) ) + ( (SourceEditor*)w )->close(); + } + } +} + + +void MainWindow::fileCloseProject() +{ + if ( currentProject->isDummy() ) + return; + Project *pro = currentProject; + QAction* a = 0; + QAction* lastValid = 0; + for ( QMap::Iterator it = projects.begin(); it != projects.end(); ++it ) { + if ( it.data() == pro ) { + a = it.key(); + if ( lastValid ) + break; + } + lastValid = it.key(); + } + if ( a ) { + if ( pro->isModified() ) { + switch ( QMessageBox::warning( this, tr( "Save Project Settings" ), + tr( "Save changes to '%1'?" ).arg( pro->fileName() ), + tr( "&Yes" ), tr( "&No" ), tr( "&Cancel" ), 0, 2 ) ) { + case 0: // save + pro->save(); + break; + case 1: // don't save + break; + case 2: // cancel + return; + default: + break; + } + } + + QWidgetList windows = qWorkspace()->windowList(); + qWorkspace()->blockSignals( TRUE ); + QWidgetListIt wit( windows ); + while ( wit.current() ) { + QWidget *w = wit.current(); + ++wit; + if ( ::qt_cast(w) ) { + if ( ( (FormWindow*)w )->project() == pro ) { + if ( ( (FormWindow*)w )->formFile()->editor() ) + windows.removeRef( ( (FormWindow*)w )->formFile()->editor() ); + if ( !( (FormWindow*)w )->formFile()->close() ) + return; + } + } else if ( ::qt_cast(w) ) { + if ( !( (SourceEditor*)w )->close() ) + return; + } + } + hierarchyView->clear(); + windows = qWorkspace()->windowList(); + qWorkspace()->blockSignals( FALSE ); + actionGroupProjects->removeChild( a ); + projects.remove( a ); + delete a; + currentProject = 0; + if ( lastValid ) { + projectSelected( lastValid ); + statusBar()->message( "Selected project '" + tr( currentProject->projectName() + "'") ); + } + if ( !windows.isEmpty() ) { + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + if (!::qt_cast(w) || w->isHidden()) + continue; + w->setFocus(); + activeWindowChanged( w ); + break; + } + } else { + emit hasActiveWindow( FALSE ); + emit hasActiveForm( FALSE ); + updateUndoRedo( FALSE, FALSE, QString::null, QString::null ); + } + } +} + +void MainWindow::fileOpen() // as called by the menu +{ + fileOpen( "", "", "", FALSE ); +} + +void MainWindow::projectInsertFile() +{ + fileOpen( "", "" ); +} + +void MainWindow::fileOpen( const QString &filter, const QString &extension, const QString &fn, bool inProject ) +{ + statusBar()->message( tr( "Open a file...") ); + + QPluginManager manager( IID_ImportFilter, QApplication::libraryPaths(), pluginDirectory() ); + + Project* project = inProject ? currentProject : eProject; + + QStringList additionalSources; + + { + QStringList filterlist; + if ( filter.isEmpty() ) { + if ( !inProject ) + filterlist << tr( "Designer Files (*.ui *.pro)" ); + filterlist << tr( "Qt User-Interface Files (*.ui)" ); + if ( !inProject ) + filterlist << tr( "QMAKE Project Files (*.pro)" ); + QStringList list = manager.featureList(); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) + filterlist << *it; + LanguageInterface *iface = MetaDataBase::languageInterface( project->language() ); + if ( iface ) { + filterlist += iface->fileFilterList(); + additionalSources += iface->fileExtensionList(); + } + filterlist << tr( "All Files (*)" ); + } else { + filterlist << filter; + } + + QString filters = filterlist.join( ";;" ); + + QStringList filenames; + if ( fn.isEmpty() ) { + if ( !inProject ) { + QString f = QFileDialog::getOpenFileName( QString::null, filters, this, 0, + tr("Open" ), &lastOpenFilter ); + filenames << f; + } else { + filenames = QFileDialog::getOpenFileNames( filters, QString::null, this, 0, + tr("Add"), &lastOpenFilter ); + } + } else { + filenames << fn; + } + + for ( QStringList::Iterator fit = filenames.begin(); fit != filenames.end(); ++fit ) { + QString filename = *fit; + if ( !filename.isEmpty() ) { + QFileInfo fi( filename ); + + if ( fi.extension( FALSE ) == "pro" && ( extension.isEmpty() || extension.find( ";pro" ) != -1 ) ) { + addRecentlyOpened( filename, recentlyProjects ); + openProject( filename ); + } else if ( fi.extension( FALSE ) == "ui" && ( extension.isEmpty() || extension.find( ";ui" ) != -1 ) ) { + if ( !inProject ) + setCurrentProject( eProject ); + openFormWindow( filename ); + addRecentlyOpened( filename, recentlyFiles ); + } else if ( !extension.isEmpty() && extension.find( ";" + fi.extension( FALSE ) ) != -1 || + additionalSources.find( fi.extension( FALSE ) ) != additionalSources.end() ) { + SourceFile *sf = project->findSourceFile( project->makeRelative( filename ) ); + if ( !sf ) + sf = new SourceFile( project->makeRelative( filename ), FALSE, project ); + editSource( sf ); + } else if ( extension.isEmpty() ) { + QString filter; + for ( QStringList::Iterator it2 = filterlist.begin(); it2 != filterlist.end(); ++it2 ) { + if ( (*it2).contains( "." + fi.extension( FALSE ), FALSE ) ) { + filter = *it2; + break; + } + } + + ImportFilterInterface* iface = 0; + manager.queryInterface( filter, &iface ); + if ( !iface ) { + statusBar()->message( tr( "No import filter is available to import '%1'"). + arg( filename ), 3000 ); + return; + } + statusBar()->message( tr( "Importing '%1' using import filter ...").arg( filename ) ); + QStringList list = iface->import( filter, filename ); + iface->release(); + if ( list.isEmpty() ) { + statusBar()->message( tr( "Nothing to load in '%1'").arg( filename ), 3000 ); + return; + } + if ( !inProject ) + setCurrentProject( eProject ); + addRecentlyOpened( filename, recentlyFiles ); + for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { + openFormWindow( *it, FALSE ); + QFile::remove( *it ); + } + statusBar()->clear(); + } + } + } + } +} + +FormWindow *MainWindow::openFormWindow( const QString &filename, bool validFileName, FormFile *ff ) +{ + if ( filename.isEmpty() ) + return 0; + + bool makeNew = FALSE; + + if ( !QFile::exists( filename ) ) { + makeNew = TRUE; + } else { + QFile f( filename ); + f.open( IO_ReadOnly ); + QTextStream ts( &f ); + makeNew = ts.read().length() < 2; + } + if ( makeNew ) { + fileNew(); + if ( formWindow() ) + formWindow()->setFileName( filename ); + return formWindow(); + } + + statusBar()->message( tr( "Reading file '%1'...").arg( filename ) ); + FormFile *ff2 = currentProject->findFormFile( currentProject->makeRelative(filename) ); + if ( ff2 && ff2->formWindow() ) { + ff2->formWindow()->setFocus(); + return ff2->formWindow(); + } + + if ( ff2 ) + ff = ff2; + QApplication::setOverrideCursor( WaitCursor ); + Resource resource( this ); + if ( !ff ) + ff = new FormFile( currentProject->makeRelative( filename ), FALSE, currentProject ); + bool b = resource.load( ff ) && (FormWindow*)resource.widget(); + if ( !validFileName && resource.widget() ) + ( (FormWindow*)resource.widget() )->setFileName( QString::null ); + QApplication::restoreOverrideCursor(); + if ( b ) { + rebuildCustomWidgetGUI(); + statusBar()->message( tr( "Loaded file '%1'").arg( filename ), 3000 ); + } else { + statusBar()->message( tr( "Failed to load file '%1'").arg( filename ), 5000 ); + QMessageBox::information( this, tr("Load File"), tr("Couldn't load file '%1'").arg( filename ) ); + delete ff; + } + return (FormWindow*)resource.widget(); +} + +bool MainWindow::fileSave() +{ + + if ( !currentProject->isDummy() ) + return fileSaveProject(); + return fileSaveForm(); +} + +bool MainWindow::fileSaveForm() +{ + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->object() == formWindow() || e == qWorkspace()->activeWindow() ) { + e->save(); + } + } + + FormWindow *fw = 0; + + QWidget *w = qWorkspace()->activeWindow(); + if ( w ) { + if ( ::qt_cast(w) ) { + SourceEditor *se = (SourceEditor*)w; + if ( se->formWindow() ) + fw = se->formWindow(); + else if ( se->sourceFile() ) { + se->sourceFile()->save(); + return TRUE; + } + } + } + + if ( !fw ) + fw = formWindow(); + if ( !fw || !fw->formFile()->save() ) + return FALSE; + QApplication::restoreOverrideCursor(); + return TRUE; +} + +bool MainWindow::fileSaveProject() +{ + currentProject->save(); + statusBar()->message( tr( "Project '%1' saved.").arg( currentProject->projectName() ), 3000 ); + return TRUE; +} + +bool MainWindow::fileSaveAs() +{ + statusBar()->message( tr( "Enter a filename..." ) ); + + QWidget *w = qworkspace->activeWindow(); + if ( !w ) + return TRUE; + if ( ::qt_cast(w) ) + return ( (FormWindow*)w )->formFile()->saveAs(); + else if ( ::qt_cast(w) ) + return ( (SourceEditor*)w )->saveAs(); + return FALSE; +} + +void MainWindow::fileSaveAll() +{ + for ( QMap::Iterator it = projects.begin(); it != projects.end(); ++it ) + (*it)->save(); +} + +void MainWindow::fileCreateTemplate() +{ + CreateTemplate dia( this, 0, TRUE ); + + int i = 0; + for ( i = 0; i < WidgetDatabase::count(); ++i ) { + if ( WidgetDatabase::isForm( i ) && WidgetDatabase::group( i ) != "Temp") { + dia.listClass->insertItem( WidgetDatabase::className( i ) ); + } + } + for ( i = 0; i < WidgetDatabase::count(); ++i ) { + if ( WidgetDatabase::isContainer( i ) && !WidgetDatabase::isForm(i) && + WidgetDatabase::className( i ) != "QTabWidget" && WidgetDatabase::group( i ) != "Temp" ) { + dia.listClass->insertItem( WidgetDatabase::className( i ) ); + } + } + + QPtrList *lst = MetaDataBase::customWidgets(); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + if ( w->isContainer ) + dia.listClass->insertItem( w->className ); + } + + dia.editName->setText( tr( "NewTemplate" ) ); + connect( dia.buttonCreate, SIGNAL( clicked() ), + this, SLOT( createNewTemplate() ) ); + dia.exec(); +} + +void MainWindow::createNewTemplate() +{ + CreateTemplate *dia = (CreateTemplate*)sender()->parent(); + QString fn = dia->editName->text(); + QString cn = dia->listClass->currentText(); + if ( fn.isEmpty() || cn.isEmpty() ) { + QMessageBox::information( this, tr( "Create Template" ), tr( "Couldn't create the template" ) ); + return; + } + + QStringList templRoots; + const char *qtdir = getenv( "QTDIR" ); + if(qtdir) + templRoots << qtdir; + templRoots << qInstallPathData(); + if(qtdir) //try the tools/designer directory last! + templRoots << (QString(qtdir) + "/tools/designer"); + QFile f; + for ( QStringList::Iterator it = templRoots.begin(); it != templRoots.end(); ++it ) { + if ( QFile::exists( (*it) + "/templates/" )) { + QString tmpfn = (*it) + "/templates/" + fn + ".ui"; + f.setName(tmpfn); + if(f.open(IO_WriteOnly)) + break; + } + } + if ( !f.isOpen() ) { + QMessageBox::information( this, tr( "Create Template" ), tr( "Couldn't create the template" ) ); + return; + } + QTextStream ts( &f ); + + ts << "" << endl; + ts << "" << endl; + ts << "" << cn << "" << endl; + ts << "" << endl; + ts << " name" << endl; + ts << " " << cn << "Form" << endl; + ts << "" << endl; + ts << "" << endl; + ts << " geometry" << endl; + ts << " " << endl; + ts << " 300" << endl; + ts << " 400" << endl; + ts << " " << endl; + ts << "" << endl; + ts << "" << endl; + ts << "" << endl; + + dia->editName->setText( tr( "NewTemplate" ) ); + + f.close(); +} + +void MainWindow::editUndo() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editUndo(); + return; + } + if ( formWindow() ) + formWindow()->undo(); +} + +void MainWindow::editRedo() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editRedo(); + return; + } + if ( formWindow() ) + formWindow()->redo(); +} + +void MainWindow::editCut() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editCut(); + return; + } + editCopy(); + editDelete(); +} + +void MainWindow::editCopy() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editCopy(); + return; + } + if ( formWindow() ) + qApp->clipboard()->setText( formWindow()->copy() ); +} + +void MainWindow::editPaste() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editPaste(); + return; + } + if ( !formWindow() ) + return; + + QWidget *w = formWindow()->mainContainer(); + QWidgetList l( formWindow()->selectedWidgets() ); + if ( l.count() == 1 ) { + w = l.first(); + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout || + ( !WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ) && + w != formWindow()->mainContainer() ) ) + w = formWindow()->mainContainer(); + } + + if ( w && WidgetFactory::layoutType( w ) == WidgetFactory::NoLayout ) { + formWindow()->paste( qApp->clipboard()->text(), WidgetFactory::containerOfWidget( w ) ); + hierarchyView->widgetInserted( 0 ); + formWindow()->commandHistory()->setModified( TRUE ); + } else { + QMessageBox::information( this, tr( "Paste error" ), + tr( "Can't paste widgets. Designer couldn't find a container\n" + "to paste into which does not contain a layout. Break the layout\n" + "of the container you want to paste into and select this container\n" + "and then paste again." ) ); + } +} + +void MainWindow::editDelete() +{ + if ( formWindow() ) + formWindow()->deleteWidgets(); +} + +void MainWindow::editSelectAll() +{ + if ( qWorkspace()->activeWindow() && + ::qt_cast(qWorkspace()->activeWindow()) ) { + ( (SourceEditor*)qWorkspace()->activeWindow() )->editSelectAll(); + return; + } + if ( formWindow() ) + formWindow()->selectAll(); +} + + +void MainWindow::editLower() +{ + if ( formWindow() ) + formWindow()->lowerWidgets(); +} + +void MainWindow::editRaise() +{ + if ( formWindow() ) + formWindow()->raiseWidgets(); +} + +void MainWindow::editAdjustSize() +{ + if ( formWindow() ) + formWindow()->editAdjustSize(); +} + +void MainWindow::editLayoutHorizontal() +{ + if ( layoutChilds ) + editLayoutContainerHorizontal(); + else if ( layoutSelected && formWindow() ) + formWindow()->layoutHorizontal(); +} + +void MainWindow::editLayoutVertical() +{ + if ( layoutChilds ) + editLayoutContainerVertical(); + else if ( layoutSelected && formWindow() ) + formWindow()->layoutVertical(); +} + +void MainWindow::editLayoutHorizontalSplit() +{ + if ( layoutChilds ) + ; // no way to do that + else if ( layoutSelected && formWindow() ) + formWindow()->layoutHorizontalSplit(); +} + +void MainWindow::editLayoutVerticalSplit() +{ + if ( layoutChilds ) + ; // no way to do that + else if ( layoutSelected && formWindow() ) + formWindow()->layoutVerticalSplit(); +} + +void MainWindow::editLayoutGrid() +{ + if ( layoutChilds ) + editLayoutContainerGrid(); + else if ( layoutSelected && formWindow() ) + formWindow()->layoutGrid(); +} + +void MainWindow::editLayoutContainerVertical() +{ + if ( !formWindow() ) + return; + QWidget *w = formWindow()->mainContainer(); + QWidgetList l( formWindow()->selectedWidgets() ); + if ( l.count() == 1 ) + w = l.first(); + if ( w ) + formWindow()->layoutVerticalContainer( w ); +} + +void MainWindow::editLayoutContainerHorizontal() +{ + if ( !formWindow() ) + return; + QWidget *w = formWindow()->mainContainer(); + QWidgetList l( formWindow()->selectedWidgets() ); + if ( l.count() == 1 ) + w = l.first(); + if ( w ) + formWindow()->layoutHorizontalContainer( w ); +} + +void MainWindow::editLayoutContainerGrid() +{ + if ( !formWindow() ) + return; + QWidget *w = formWindow()->mainContainer(); + QWidgetList l( formWindow()->selectedWidgets() ); + if ( l.count() == 1 ) + w = l.first(); + if ( w ) + formWindow()->layoutGridContainer( w ); +} + +void MainWindow::editBreakLayout() +{ + if ( !formWindow() || !breakLayout ) + return; + QWidget *w = formWindow()->mainContainer(); + if ( formWindow()->currentWidget() ) + w = formWindow()->currentWidget(); + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout || + w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) { + formWindow()->breakLayout( w ); + return; + } else { + QWidgetList widgets = formWindow()->selectedWidgets(); + for ( w = widgets.first(); w; w = widgets.next() ) { + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout || + w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + break; + } + if ( w ) { + formWindow()->breakLayout( w ); + return; + } + } + + w = formWindow()->mainContainer(); + if ( WidgetFactory::layoutType( w ) != WidgetFactory::NoLayout || + w->parentWidget() && WidgetFactory::layoutType( w->parentWidget() ) != WidgetFactory::NoLayout ) + formWindow()->breakLayout( w ); +} + +void MainWindow::editAccels() +{ + if ( !formWindow() ) + return; + formWindow()->checkAccels(); +} + +void MainWindow::editFunctions() +{ + if ( !formWindow() ) + return; + + statusBar()->message( tr( "Edit the current form's slots..." ) ); + EditFunctions dlg( this, formWindow(), TRUE ); + dlg.exec(); + statusBar()->clear(); +} + +void MainWindow::editConnections() +{ + if ( !formWindow() ) + return; + + statusBar()->message( tr( "Edit the current form's connections..." ) ); + ConnectionDialog dlg( this ); + dlg.exec(); + + statusBar()->clear(); +} + +SourceEditor *MainWindow::editSource() +{ + if ( !formWindow() ) + return 0; + return formWindow()->formFile()->showEditor(); +} + +SourceEditor *MainWindow::openSourceEditor() +{ + if ( !formWindow() ) + return 0; + + QString lang = currentProject->language(); + if ( !MetaDataBase::hasEditor( lang ) ) { + QMessageBox::information( this, tr( "Edit Source" ), + tr( "There is no plugin for editing " + lang + " code installed!\n" + "Note: Plugins are not available in static Qt configurations." ) ); + return 0; + } + + SourceEditor *editor = 0; + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) { + if ( e->language() == lang && e->formWindow() == formWindow() ) { + editor = e; + break; + } + } + + if ( !editor ) + editor = createSourceEditor( formWindow(), formWindow()->project(), lang ); + return editor; +} + +SourceEditor *MainWindow::editSource( SourceFile *f ) +{ + QString lang = currentProject->language(); + if ( !MetaDataBase::hasEditor( lang ) ) { + QMessageBox::information( this, tr( "Edit Source" ), + tr( "There is no plugin for editing " + lang + " code installed!\n" + "Note: Plugins are not available in static Qt configurations." ) ); + return 0; + } + + SourceEditor *editor = 0; + if ( f ) + editor = f->editor(); + if ( !editor ) + editor = createSourceEditor( f, currentProject, lang ); + editor->setActiveWindow(); + editor->setFocus(); + return editor; +} + +SourceEditor *MainWindow::createSourceEditor( QObject *object, Project *project, + const QString &lang, const QString &func, + bool rereadSource ) +{ + SourceEditor *editor = 0; + EditorInterface *eIface = 0; + editorPluginManager->queryInterface( lang, &eIface ); + if ( !eIface ) + return 0; + LanguageInterface *lIface = MetaDataBase::languageInterface( lang ); + if ( !lIface ) + return 0; + QApplication::setOverrideCursor( WaitCursor ); + editor = new SourceEditor( qWorkspace(), eIface, lIface ); + eIface->release(); + lIface->release(); + + editor->setLanguage( lang ); + sourceEditors.append( editor ); + QApplication::restoreOverrideCursor(); + + if ( editor->object() != object ) + editor->setObject( object, project ); + else if ( rereadSource ) + editor->refresh( FALSE ); + + editor->show(); + editor->setFocus(); + if ( !func.isEmpty() ) + editor->setFunction( func ); + emit editorChanged(); + + return editor; +} + +void MainWindow::editFormSettings() +{ + if ( !formWindow() ) + return; + + statusBar()->message( tr( "Edit the current form's settings..." ) ); + FormSettings dlg( this, formWindow() ); + dlg.exec(); + statusBar()->clear(); +} + +void MainWindow::editProjectSettings() +{ + openProjectSettings( currentProject ); + wspace->setCurrentProject( currentProject ); +} + +void MainWindow::editPixmapCollection() +{ + PixmapCollectionEditor dia( this, 0, TRUE ); + dia.setProject( currentProject ); + dia.exec(); +} + +void MainWindow::editDatabaseConnections() +{ +#ifndef QT_NO_SQL + DatabaseConnectionsEditor dia( currentProject, this, 0, TRUE ); + dia.exec(); +#endif +} + +void MainWindow::editPreferences() +{ + statusBar()->message( tr( "Edit preferences..." ) ); + Preferences *dia = new Preferences( this, 0, TRUE ); + prefDia = dia; + connect( dia->helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + dia->buttonColor->setEditor( StyledButton::ColorEditor ); + dia->buttonPixmap->setEditor( StyledButton::PixmapEditor ); + dia->groupBoxGrid->setChecked( sGrid ); + dia->checkBoxSnapGrid->setChecked( snGrid ); + dia->spinGridX->setValue( grid().x() ); + dia->spinGridY->setValue( grid().y() ); + dia->checkBoxWorkspace->setChecked( restoreConfig ); + dia->checkBoxTextLabels->setChecked( usesTextLabel() ); + dia->buttonColor->setColor( qworkspace->backgroundColor() ); + QString pluginPaths = QApplication::libraryPaths().join("\n"); + dia->textEditPluginPaths->setText(pluginPaths); + if ( qworkspace->backgroundPixmap() ) + dia->buttonPixmap->setPixmap( *qworkspace->backgroundPixmap() ); + if ( backPix ) + dia->radioPixmap->setChecked( TRUE ); + else + dia->radioColor->setChecked( TRUE ); + dia->checkBoxSplash->setChecked( splashScreen ); + dia->checkAutoEdit->setChecked( !databaseAutoEdit ); + dia->checkBoxStartDialog->setChecked( shStartDialog ); + dia->checkBoxAutoSave->setChecked( autoSaveEnabled ); + int h = autoSaveInterval / 3600; + int m = ( autoSaveInterval - h * 3600 ) / 60; + int s = autoSaveInterval - ( h * 3600 + m * 60 ); + QTime t( h, m, s ); + dia->timeEditAutoSave->setTime( t ); + + SenderObject *senderObject = new SenderObject( designerInterface() ); + QValueList::Iterator it; + for ( it = preferenceTabs.begin(); it != preferenceTabs.end(); ++it ) { + Tab t = *it; + dia->tabWidget->addTab( t.w, t.title ); + if ( t.receiver ) { + connect( dia->buttonOk, SIGNAL( clicked() ), senderObject, SLOT( emitAcceptSignal() ) ); + connect( senderObject, SIGNAL( acceptSignal( QUnknownInterface * ) ), t.receiver, t.accept_slot ); + connect( senderObject, SIGNAL( initSignal( QUnknownInterface * ) ), t.receiver, t.init_slot ); + senderObject->emitInitSignal(); + disconnect( senderObject, SIGNAL( initSignal( QUnknownInterface * ) ), t.receiver, t.init_slot ); + } + } + + if ( dia->exec() == QDialog::Accepted ) { + setSnapGrid( dia->checkBoxSnapGrid->isChecked() ); + setShowGrid( dia->groupBoxGrid->isChecked() ); + setGrid( QPoint( dia->spinGridX->value(), + dia->spinGridY->value() ) ); + restoreConfig = dia->checkBoxWorkspace->isChecked(); + setUsesTextLabel( dia->checkBoxTextLabels->isChecked() ); + if (dia->textEditPluginPaths->isModified()) { + pluginPaths = dia->textEditPluginPaths->text(); + QApplication::setLibraryPaths(QStringList::split("\n", pluginPaths)); + savePluginPaths = TRUE; + } + + if ( dia->radioPixmap->isChecked() && dia->buttonPixmap->pixmap() ) { + qworkspace->setBackgroundPixmap( *dia->buttonPixmap->pixmap() ); + backPix = TRUE; + } else { + qworkspace->setBackgroundColor( dia->buttonColor->color() ); + backPix = FALSE; + } + splashScreen = dia->checkBoxSplash->isChecked(); + databaseAutoEdit = !dia->checkAutoEdit->isChecked(); + shStartDialog = dia->checkBoxStartDialog->isChecked(); + autoSaveEnabled = dia->checkBoxAutoSave->isChecked(); + QTime time = dia->timeEditAutoSave->time(); + autoSaveInterval = time.hour() * 3600 + time.minute() * 60 + time.second(); + if ( autoSaveEnabled ) + autoSaveTimer->start( autoSaveInterval * 1000 ); + else + autoSaveTimer->stop(); + } + delete senderObject; + for ( it = preferenceTabs.begin(); it != preferenceTabs.end(); ++it ) { + Tab t = *it; + dia->tabWidget->removePage( t.w ); + t.w->reparent( 0, QPoint(0,0), FALSE ); + } + + for ( SourceEditor *e = sourceEditors.first(); e; e = sourceEditors.next() ) + e->configChanged(); + + delete dia; + prefDia = 0; + statusBar()->clear(); +} + +void MainWindow::searchFind() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast(qWorkspace()->activeWindow()) ) + return; + + if ( !findDialog ) + findDialog = new FindDialog( this, 0, FALSE ); + findDialog->show(); + findDialog->raise(); + findDialog->setEditor( ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface(), + ( (SourceEditor*)qWorkspace()->activeWindow() )->object() ); + findDialog->comboFind->setFocus(); + findDialog->comboFind->lineEdit()->selectAll(); +} + +void MainWindow::searchIncremetalFindMenu() +{ + incrementalSearch->selectAll(); + incrementalSearch->setFocus(); +} + +void MainWindow::searchIncremetalFind() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast(qWorkspace()->activeWindow()) ) + return; + + ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface()->find( incrementalSearch->text(), + FALSE, FALSE, TRUE, FALSE ); +} + +void MainWindow::searchIncremetalFindNext() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast(qWorkspace()->activeWindow()) ) + return; + + ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface()->find( incrementalSearch->text(), + FALSE, FALSE, TRUE, TRUE ); +} + +void MainWindow::searchReplace() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast(qWorkspace()->activeWindow()) ) + return; + + if ( !replaceDialog ) + replaceDialog = new ReplaceDialog( this, 0, FALSE ); + replaceDialog->show(); + replaceDialog->raise(); + replaceDialog->setEditor( ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface(), + ( (SourceEditor*)qWorkspace()->activeWindow() )->object() ); + replaceDialog->comboFind->setFocus(); + replaceDialog->comboFind->lineEdit()->selectAll(); +} + +void MainWindow::searchGotoLine() +{ + if ( !qWorkspace()->activeWindow() || + !::qt_cast(qWorkspace()->activeWindow()) ) + return; + + if ( !gotoLineDialog ) + gotoLineDialog = new GotoLineDialog( this, 0, FALSE ); + gotoLineDialog->show(); + gotoLineDialog->raise(); + gotoLineDialog->setEditor( ( (SourceEditor*)qWorkspace()->activeWindow() )->editorInterface() ); + gotoLineDialog->spinLine->setFocus(); + gotoLineDialog->spinLine->setMinValue( 1 ); + gotoLineDialog->spinLine->setMaxValue( ( (SourceEditor*)qWorkspace()->activeWindow() )->numLines() ); + gotoLineDialog->spinLine->selectAll(); +} + +void MainWindow::toolsCustomWidget() +{ + statusBar()->message( tr( "Edit custom widgets..." ) ); + CustomWidgetEditor edit( this, this ); + edit.exec(); + rebuildCustomWidgetGUI(); + statusBar()->clear(); +} + +void MainWindow::toolsConfigure() +{ + ConfigToolboxDialog dlg( this ); + if ( dlg.exec() != QDialog::Accepted ) + return; + rebuildCommonWidgetsToolBoxPage(); +} + +void MainWindow::showStartDialog() +{ + if ( singleProjectMode() ) + return; + for ( int i = 1; i < qApp->argc(); ++i ) { + QString arg = qApp->argv()[i]; + if ( arg[0] != '-' ) + return; + } + StartDialog *sd = new StartDialog( this, templatePath() ); + sd->setRecentlyFiles( recentlyFiles ); + sd->setRecentlyProjects( recentlyProjects ); + sd->exec(); + shStartDialog = sd->showDialogInFuture(); +} diff --git a/tools/designer/designer/menubareditor.cpp b/tools/designer/designer/menubareditor.cpp new file mode 100644 index 0000000..d26d5d3 --- /dev/null +++ b/tools/designer/designer/menubareditor.cpp @@ -0,0 +1,1134 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "command.h" +#include "formwindow.h" +#include "menubareditor.h" +#include "popupmenueditor.h" + +extern void find_accel( const QString &txt, QMap &accels, QWidget *w ); + +// Drag Object Declaration ------------------------------------------- + +class MenuBarEditorItemPtrDrag : public QStoredDrag +{ +public: + MenuBarEditorItemPtrDrag( MenuBarEditorItem * item, + QWidget * parent = 0, + const char * name = 0 ); + ~MenuBarEditorItemPtrDrag() {}; + static bool canDecode( QDragMoveEvent * e ); + static bool decode( QDropEvent * e, MenuBarEditorItem ** i ); +}; + +// Drag Object Implementation --------------------------------------- + +MenuBarEditorItemPtrDrag::MenuBarEditorItemPtrDrag( MenuBarEditorItem * item, + QWidget * parent, + const char * name ) + : QStoredDrag( "qt/menubareditoritemptr", parent, name ) +{ + QByteArray data( sizeof( Q_LONG ) ); + QDataStream stream( data, IO_WriteOnly ); + stream << ( Q_LONG ) item; + setEncodedData( data ); +} + +bool MenuBarEditorItemPtrDrag::canDecode( QDragMoveEvent * e ) +{ + return e->provides( "qt/menubareditoritemptr" ); +} + +bool MenuBarEditorItemPtrDrag::decode( QDropEvent * e, MenuBarEditorItem ** i ) +{ + QByteArray data = e->encodedData( "qt/menubareditoritemptr" ); + QDataStream stream( data, IO_ReadOnly ); + + if ( !data.size() ) + return FALSE; + + Q_LONG p = 0; + stream >> p; + *i = ( MenuBarEditorItem *) p; + + return TRUE; +} + +// MenuBarEditorItem --------------------------------------------------- + +MenuBarEditorItem::MenuBarEditorItem( MenuBarEditor * bar, QObject * parent, const char * name ) + : QObject( parent, name ), + menuBar( bar ), + popupMenu( 0 ), + visible( TRUE ), + separator( FALSE ), + removable( FALSE ) +{ } + +MenuBarEditorItem::MenuBarEditorItem( PopupMenuEditor * menu, MenuBarEditor * bar, + QObject * parent, const char * name ) + : QObject( parent, name ), + menuBar( bar ), + popupMenu( menu ), + visible( TRUE ), + separator( FALSE ), + removable( TRUE ) +{ + text = menu->name(); +} + +MenuBarEditorItem::MenuBarEditorItem( QActionGroup * actionGroup, MenuBarEditor * bar, + QObject * parent, const char * name ) + : QObject( parent, name ), + menuBar( bar ), + popupMenu( 0 ), + visible( TRUE ), + separator( FALSE ), + removable( TRUE ) +{ + text = actionGroup->menuText(); + popupMenu = new PopupMenuEditor( menuBar->formWindow(), menuBar ); + popupMenu->insert( actionGroup ); +} + +MenuBarEditorItem::MenuBarEditorItem( MenuBarEditorItem * item, QObject * parent, const char * name ) + : QObject( parent, name ), + menuBar( item->menuBar ), + popupMenu( 0 ), + text( item->text ), + visible( item->visible ), + separator( item->separator ), + removable( item->removable ) +{ + popupMenu = new PopupMenuEditor( menuBar->formWindow(), item->popupMenu, menuBar ); +} + +// MenuBarEditor -------------------------------------------------------- + +int MenuBarEditor::clipboardOperation = 0; +MenuBarEditorItem * MenuBarEditor::clipboardItem = 0; + +MenuBarEditor::MenuBarEditor( FormWindow * fw, QWidget * parent, const char * name ) + : QMenuBar( parent, name ), + formWnd( fw ), + draggedItem( 0 ), + currentIndex( 0 ), + itemHeight( 0 ), + separatorWidth( 32 ), + hideWhenEmpty( TRUE ), + hasSeparator( FALSE ) +{ + setAcceptDrops( TRUE ); + setFocusPolicy( StrongFocus ); + + addItem.setMenuText( tr("new menu") ); + addSeparator.setMenuText( tr("new separator") ); + + lineEdit = new QLineEdit( this, "menubar lineedit" ); + lineEdit->hide(); + lineEdit->setFrameStyle(QFrame::Plain | QFrame::NoFrame); + lineEdit->polish(); + lineEdit->setBackgroundMode(PaletteButton); + lineEdit->setBackgroundOrigin(ParentOrigin); + lineEdit->installEventFilter( this ); + + dropLine = new QWidget( this, "menubar dropline", Qt::WStyle_NoBorder | WStyle_StaysOnTop ); + dropLine->setBackgroundColor( Qt::red ); + dropLine->hide(); + + setMinimumHeight( fontMetrics().height() + 2 * borderSize() ); +} + +MenuBarEditor::~MenuBarEditor() +{ + itemList.setAutoDelete( TRUE ); +} + +FormWindow * MenuBarEditor::formWindow() +{ + return formWnd; +} + +MenuBarEditorItem * MenuBarEditor::createItem( int index, bool addToCmdStack ) +{ + MenuBarEditorItem * i = + new MenuBarEditorItem( new PopupMenuEditor( formWnd, ( QWidget * ) parent() ), this ); + if ( addToCmdStack ) { + AddMenuCommand * cmd = new AddMenuCommand( "Add Menu", formWnd, this, i, index ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else { + AddMenuCommand cmd( "Add Menu", formWnd, this, i, index ); + cmd.execute(); + } + return i; +} + +void MenuBarEditor::insertItem( MenuBarEditorItem * item, int index ) +{ + item->menu()->parentMenu = this; + + if ( index != -1 ) + itemList.insert( index, item ); + else + itemList.append( item ); + + if ( hideWhenEmpty && itemList.count() == 1 ) + show(); // calls resizeInternals(); + else + resizeInternals(); + + if ( isVisible() ) + update(); +} + +void MenuBarEditor::insertItem( QString text, PopupMenuEditor * menu, int index ) +{ + MenuBarEditorItem * item = new MenuBarEditorItem( menu, this ); + if ( !text.isNull() ) + item->setMenuText( text ); + insertItem( item, index ); +} + +void MenuBarEditor::insertItem( QString text, QActionGroup * group, int index ) +{ + MenuBarEditorItem * item = new MenuBarEditorItem( group, this ); + if ( !text.isNull() ) + item->setMenuText( text ); + insertItem( item, index ); +} + + +void MenuBarEditor::insertSeparator( int index ) +{ + if ( hasSeparator ) + return; + + MenuBarEditorItem * i = createItem( index ); + i->setSeparator( TRUE ); + i->setMenuText( "separator" ); + hasSeparator = TRUE; +} + +void MenuBarEditor::removeItemAt( int index ) +{ + removeItem( item( index ) ); +} + +void MenuBarEditor::removeItem( MenuBarEditorItem * item ) +{ + if ( item && + item->isRemovable() && + itemList.removeRef( item ) ) { + + if ( item->isSeparator() ) + hasSeparator = FALSE; + + if ( hideWhenEmpty && itemList.count() == 0 ) + hide(); + else + resizeInternals(); + + int n = count() + 1; + if ( currentIndex >= n ) + currentIndex = n; + + if ( isVisible() ) + update(); + } +} + +int MenuBarEditor::findItem( MenuBarEditorItem * item ) +{ + return itemList.findRef( item ); +} + +int MenuBarEditor::findItem( PopupMenuEditor * menu ) +{ + MenuBarEditorItem * i = itemList.first(); + + while ( i ) { + if ( i->menu() == menu ) + return itemList.at(); + i = itemList.next(); + } + + return -1; +} + +int MenuBarEditor::findItem( QPoint & pos ) +{ + int x = borderSize(); + int dx = 0; + int y = 0; + int w = width(); + QSize s; + QRect r; + + MenuBarEditorItem * i = itemList.first(); + + while ( i ) { + + if ( i->isVisible() ) { + + s = itemSize( i ); + dx = s.width(); + + if ( x + dx > w && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + + r = QRect( x, y, s.width(), s.height() ); + + if ( r.contains( pos ) ) + return itemList.at(); + + addItemSizeToCoords( i, x, y, w ); + } + + i = itemList.next(); + } + + // check add item + s = itemSize( &addItem ); + dx = s.width(); + + if ( x + dx > w && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + + r = QRect( x, y, s.width(), s.height() ); + + if ( r.contains( pos ) ) + return itemList.count(); + + return itemList.count() + 1; +} + +MenuBarEditorItem * MenuBarEditor::item( int index ) +{ + if ( index == -1 ) + return itemList.at( currentIndex ); + + int c = itemList.count(); + if ( index == c ) + return &addItem; + else if ( index > c ) + return &addSeparator; + + return itemList.at( index ); +} + +int MenuBarEditor::count() +{ + return itemList.count(); +} + +int MenuBarEditor::current() +{ + return currentIndex; +} + +void MenuBarEditor::cut( int index ) +{ + if ( clipboardItem && clipboardOperation == Cut ) + delete clipboardItem; + + clipboardOperation = Cut; + clipboardItem = itemList.at( index ); + + if ( clipboardItem == &addItem || clipboardItem == &addSeparator ) { + clipboardOperation = None; + clipboardItem = 0; + return; // do nothing + } + + RemoveMenuCommand * cmd = new RemoveMenuCommand( "Cut Menu", formWnd, this, index ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void MenuBarEditor::copy( int index ) +{ + if ( clipboardItem && clipboardOperation == Cut ) + delete clipboardItem; + + clipboardOperation = Copy; + clipboardItem = itemList.at( index ); + + if ( clipboardItem == &addItem || clipboardItem == &addSeparator ) { + clipboardOperation = None; + clipboardItem = 0; + } +} + +void MenuBarEditor::paste( int index ) +{ + if ( clipboardItem && clipboardOperation ) { + MenuBarEditorItem * i = new MenuBarEditorItem( clipboardItem ); + AddMenuCommand * cmd = new AddMenuCommand( "Paste Menu", formWnd, this, i, index ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void MenuBarEditor::exchange( int a, int b ) +{ + MenuBarEditorItem * ia = itemList.at( a ); + MenuBarEditorItem * ib = itemList.at( b ); + if ( !ia || !ib || + ia == &addItem || ia == &addSeparator || + ib == &addItem || ib == &addSeparator ) + return; // do nothing + itemList.replace( b, ia ); + itemList.replace( a, ib ); +} + +void MenuBarEditor::showLineEdit( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + MenuBarEditorItem * i = 0; + + if ( (uint) index >= itemList.count() ) + i = &addItem; + else + i = itemList.at( index ); + + if ( i && i->isSeparator() ) + return; + + // open edit field for item name + lineEdit->setText( i->menuText() ); + lineEdit->selectAll(); + QPoint pos = itemPos( index ); + lineEdit->move( pos.x() + borderSize(), pos.y() - ( borderSize() / 2 ) ); + lineEdit->resize( itemSize( i ) ); + lineEdit->show(); + lineEdit->setFocus(); +} + +void MenuBarEditor::showItem( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + if ( (uint)index < itemList.count() ) { + MenuBarEditorItem * i = itemList.at( index ); + if ( i->isSeparator() || draggedItem ) + return; + PopupMenuEditor * m = i->menu(); + QPoint pos = itemPos( index ); + m->move( pos.x(), pos.y() + itemHeight - 1 ); + m->raise(); + m->show(); + setFocus(); + } +} + +void MenuBarEditor::hideItem( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + if ( (uint)index < itemList.count() ) { + PopupMenuEditor * m = itemList.at( index )->menu(); + m->hideSubMenu(); + m->hide(); + } +} + +void MenuBarEditor::focusItem( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + if ( (uint)index < itemList.count() ) { + PopupMenuEditor * m = itemList.at( index )->menu(); + m->setFocus(); + m->update(); + update(); + } +} + +void MenuBarEditor::deleteItem( int index ) +{ + if ( index == -1 ) + index = currentIndex; + + if ( (uint)index < itemList.count() ) { + RemoveMenuCommand * cmd = new RemoveMenuCommand( "Delete Menu", + formWnd, + this, + currentIndex ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +QSize MenuBarEditor::sizeHint() const +{ + return QSize( parentWidget()->width(), heightForWidth( parentWidget()->width() ) ); +} + +int MenuBarEditor::heightForWidth( int max_width ) const +{ + MenuBarEditor * that = ( MenuBarEditor * ) this; + int x = borderSize(); + int y = 0; + + QPainter p( this ); + that->itemHeight = that->itemSize( &(that->addItem) ).height(); + + MenuBarEditorItem * i = that->itemList.first(); + while ( i ) { + if ( i->isVisible() ) + that->addItemSizeToCoords( i, x, y, max_width ); + i = that->itemList.next(); + } + + that->addItemSizeToCoords( &(that->addItem), x, y, max_width ); + that->addItemSizeToCoords( &(that->addSeparator), x, y, max_width ); + + return y + itemHeight; +} + +void MenuBarEditor::show() +{ + QWidget::show(); + resizeInternals(); + + QResizeEvent e( parentWidget()->size(), parentWidget()->size() ); + QApplication::sendEvent( parentWidget(), &e ); +} + +void MenuBarEditor::checkAccels( QMap &accels ) +{ + QString t; + MenuBarEditorItem * i = itemList.first(); + while ( i ) { + t = i->menuText(); + find_accel( t, accels, this ); + // do not check the accelerators in the popup menus + i = itemList.next(); + } +} + +// public slots + +void MenuBarEditor::cut() +{ + cut( currentIndex ); +} + +void MenuBarEditor::copy() +{ + copy( currentIndex ); +} + +void MenuBarEditor::paste() +{ + paste( currentIndex ); +} + +// protected + +bool MenuBarEditor::eventFilter( QObject * o, QEvent * e ) +{ + if ( o == lineEdit && e->type() == QEvent::FocusOut ) { + leaveEditMode(); + lineEdit->hide(); + update(); + } else if ( e->type() == QEvent::LayoutHint ) { + resize( sizeHint() ); + } + return QMenuBar::eventFilter( o, e ); +} + +void MenuBarEditor::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + QRect r = rect(); + style().drawPrimitive( QStyle::PE_PanelMenuBar, &p, + r, colorGroup() ); + drawItems( p ); +} + +void MenuBarEditor::mousePressEvent( QMouseEvent * e ) +{ + mousePressPos = e->pos(); + hideItem(); + lineEdit->hide(); + currentIndex = findItem( mousePressPos ); + showItem(); + update(); + e->accept(); +} + +void MenuBarEditor::mouseDoubleClickEvent( QMouseEvent * e ) +{ + mousePressPos = e->pos(); + currentIndex = findItem( mousePressPos ); + lineEdit->hide(); + if ( currentIndex > (int)itemList.count() ) { + insertSeparator(); + update(); + } else { + showLineEdit(); + } +} + +void MenuBarEditor::mouseMoveEvent( QMouseEvent * e ) +{ + if ( e->state() & Qt::LeftButton ) { + if ( ( e->pos() - mousePressPos ).manhattanLength() > 3 ) { + bool itemCreated = FALSE; + bool isSeparator = FALSE; + draggedItem = item( findItem( mousePressPos ) ); + if ( draggedItem == &addItem ) { + draggedItem = createItem(); + itemCreated = TRUE; + } else if ( draggedItem == &addSeparator ) { + if (hasSeparator) // we can only have one separator + return; + draggedItem = createItem(); + draggedItem->setSeparator( TRUE ); + draggedItem->setMenuText( "separator" ); + isSeparator = TRUE; + itemCreated = TRUE; + } else { + isSeparator = draggedItem->isSeparator(); + } + + MenuBarEditorItemPtrDrag * d = + new MenuBarEditorItemPtrDrag( draggedItem, this ); + d->setPixmap( createTextPixmap( draggedItem->menuText() ) ); + hideItem(); + draggedItem->setVisible( FALSE ); + update(); + + // If the item is dropped in the same list, + // we will have two instances of the same pointer + // in the list. + itemList.find( draggedItem ); + QLNode * node = itemList.currentNode(); + dropConfirmed = FALSE; + d->dragCopy(); // dragevents and stuff happens + if ( draggedItem ) { // item was not dropped + if ( itemCreated ) { + removeItem( draggedItem ); + } else { + hideItem(); + draggedItem->setVisible( TRUE ); + draggedItem = 0; + showItem(); + } + } else if ( dropConfirmed ) { // item was dropped + dropConfirmed = FALSE; + hideItem(); + itemList.takeNode( node )->setVisible( TRUE ); + hasSeparator = isSeparator || hasSeparator; + showItem(); + } else { + hasSeparator = isSeparator || hasSeparator; + } + update(); + } + } +} + +void MenuBarEditor::dragEnterEvent( QDragEnterEvent * e ) +{ + if ( MenuBarEditorItemPtrDrag::canDecode( e ) ) { + e->accept(); + dropLine->show(); + } +} + +void MenuBarEditor::dragLeaveEvent( QDragLeaveEvent * ) +{ + dropLine->hide(); +} + +void MenuBarEditor::dragMoveEvent( QDragMoveEvent * e ) +{ + + QPoint pos = e->pos(); + dropLine->move( snapToItem( pos ) ); + + int idx = findItem( pos ); + if ( currentIndex != idx ) { + hideItem(); + currentIndex = idx; + showItem(); + } +} + +void MenuBarEditor::dropEvent( QDropEvent * e ) +{ + MenuBarEditorItem * i = 0; + + if ( MenuBarEditorItemPtrDrag::decode( e, &i ) ) { + draggedItem = 0; + hideItem(); + dropInPlace( i, e->pos() ); + e->accept(); + } + + dropLine->hide(); +} + +void MenuBarEditor::keyPressEvent( QKeyEvent * e ) +{ + if ( lineEdit->isHidden() ) { // In navigation mode + switch ( e->key() ) { + + case Qt::Key_Delete: + hideItem(); + deleteItem(); + showItem(); + break; + + case Qt::Key_Left: + e->accept(); + navigateLeft( e->state() & Qt::ControlButton ); + return; + + case Qt::Key_Right: + e->accept(); + navigateRight( e->state() & Qt::ControlButton ); + return; // no update + + case Qt::Key_Down: + e->accept(); + focusItem(); + return; // no update + + case Qt::Key_PageUp: + currentIndex = 0; + break; + + case Qt::Key_PageDown: + currentIndex = itemList.count(); + break; + + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_F2: + e->accept(); + enterEditMode(); + return; // no update + + case Qt::Key_Up: + case Qt::Key_Alt: + case Qt::Key_Shift: + case Qt::Key_Control: + case Qt::Key_Escape: + e->ignore(); + setFocus(); // FIXME: this is because some other widget get the focus when CTRL is pressed + return; // no update + + case Qt::Key_C: + if ( e->state() & Qt::ControlButton && currentIndex < (int)itemList.count() ) { + copy( currentIndex ); + break; + } + + case Qt::Key_X: + if ( e->state() & Qt::ControlButton && currentIndex < (int)itemList.count() ) { + hideItem(); + cut( currentIndex ); + showItem(); + break; + } + + case Qt::Key_V: + if ( e->state() & Qt::ControlButton ) { + hideItem(); + paste( currentIndex < (int)itemList.count() ? currentIndex + 1: itemList.count() ); + showItem(); + break; + } + + default: + if ( e->ascii() >= 32 || e->ascii() == 0 ) { + showLineEdit(); + QApplication::sendEvent( lineEdit, e ); + e->accept(); + } else { + e->ignore(); + } + return; + } + } else { // In edit mode + + switch ( e->key() ) { + case Qt::Key_Control: + e->ignore(); + return; + case Qt::Key_Enter: + case Qt::Key_Return: + leaveEditMode(); + case Qt::Key_Escape: + lineEdit->hide(); + setFocus(); + break; + } + } + e->accept(); + update(); +} + +void MenuBarEditor::focusOutEvent( QFocusEvent * e ) +{ + QWidget * fw = qApp->focusWidget(); + if ( e->lostFocus() && !::qt_cast(fw) ) + hideItem(); + update(); +} + +void MenuBarEditor::resizeInternals() +{ + dropLine->resize( 2, itemHeight ); + updateGeometry(); +} + +void MenuBarEditor::drawItems( QPainter & p ) +{ + QPoint pos( borderSize(), 0 ); + uint c = 0; + + p.setPen( colorGroup().buttonText() ); + + MenuBarEditorItem * i = itemList.first(); + while ( i ) { + if ( i->isVisible() ) + drawItem( p, i, c++, pos ); // updates x y + i = itemList.next(); + } + + p.setPen( darkBlue ); + drawItem( p, &addItem, c++, pos ); + if ( !hasSeparator ) + drawItem( p, &addSeparator, c, pos ); +} + +void MenuBarEditor::drawItem( QPainter & p, + MenuBarEditorItem * i, + int idx, + QPoint & pos ) +{ + int w = itemSize( i ).width(); + + // If the item passes the right border, and it is not the first item on the line + if ( pos.x() + w > width() && pos.x() > borderSize() ) { // wrap + pos.ry() += itemHeight; + pos.setX( borderSize() ); + } + + if ( i->isSeparator() ) { + drawSeparator( p, pos ); + } else { + int flags = QPainter::AlignLeft | QPainter::AlignVCenter | + Qt::ShowPrefix | Qt::SingleLine; + p.drawText( pos.x() + borderSize(), pos.y(), w - borderSize(), itemHeight, + flags, i->menuText() ); + } + + if ( hasFocus() && idx == currentIndex && !draggedItem ) + p.drawWinFocusRect( pos.x(), pos.y() + 1, w, itemHeight - 2 ); + + pos.rx() += w; +} + +void MenuBarEditor::drawSeparator( QPainter & p, QPoint & pos ) +{ + p.save(); + p.setPen( darkBlue ); + + int left = pos.x(); + int top = pos.y() + 2; + int right = left + separatorWidth - 1; + int bottom = pos.y() + itemHeight - 4; + + p.drawLine( left, top, left, bottom ); + p.drawLine( right, top, right, bottom ); + + p.fillRect( left, pos.y() + borderSize() * 2, + separatorWidth - 1, itemHeight - borderSize() * 4, + QBrush( darkBlue, Qt::Dense5Pattern ) ); + + p.restore(); +} + +QSize MenuBarEditor::itemSize( MenuBarEditorItem * i ) +{ + if ( i->isSeparator() ) + return QSize( separatorWidth, itemHeight ); + QRect r = fontMetrics().boundingRect( i->menuText().remove( "&") ); + return QSize( r.width() + borderSize() * 2, r.height() + borderSize() * 4 ); +} + +void MenuBarEditor::addItemSizeToCoords( MenuBarEditorItem * i, int & x, int & y, int w ) +{ + int dx = itemSize( i ).width(); + if ( x + dx > w && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + x += dx; +} + +QPoint MenuBarEditor::itemPos( int index ) +{ + int x = borderSize(); + int y = 0; + int w = width(); + int dx = 0; + int c = 0; + + MenuBarEditorItem * i = itemList.first(); + + while ( i ) { + if ( i->isVisible() ) { + dx = itemSize( i ).width(); + if ( x + dx > w && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + if ( c == index ) + return QPoint( x, y ); + x += dx; + c++; + } + i = itemList.next(); + } + dx = itemSize( &addItem ).width(); + if ( x + dx > width() && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + + return QPoint( x, y ); +} + +QPoint MenuBarEditor::snapToItem( const QPoint & pos ) +{ + int x = borderSize(); + int y = 0; + int dx = 0; + + MenuBarEditorItem * n = itemList.first(); + + while ( n ) { + if ( n->isVisible() ) { + dx = itemSize( n ).width(); + if ( x + dx > width() && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + if ( pos.y() > y && + pos.y() < y + itemHeight && + pos.x() < x + dx / 2 ) { + return QPoint( x, y ); + } + x += dx; + } + n = itemList.next(); + } + + return QPoint( x, y ); +} + +void MenuBarEditor::dropInPlace( MenuBarEditorItem * i, const QPoint & pos ) +{ + int x = borderSize(); + int y = 0; + int dx = 0; + int idx = 0; + + MenuBarEditorItem * n = itemList.first(); + + while ( n ) { + if ( n->isVisible() ) { + dx = itemSize( n ).width(); + if ( x + dx > width() && x > borderSize() ) { + y += itemHeight; + x = borderSize(); + } + if ( pos.y() > y && + pos.y() < y + itemHeight && + pos.x() < x + dx / 2 ) + break; + x += dx; + } + n = itemList.next(); + idx++; + } + + hideItem(); + Command * cmd = 0; + int iidx = itemList.findRef( i ); + if ( iidx != -1 ) { // internal dnd + cmd = new MoveMenuCommand( "Item Dragged", formWnd, this, iidx, idx ); + item( iidx )->setVisible( TRUE ); + } else { + cmd = new AddMenuCommand( "Add Menu", formWnd, this, i, idx ); + dropConfirmed = TRUE; // let mouseMoveEvent set the item visible + } + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + currentIndex = ( iidx >= 0 && iidx < idx ) ? idx - 1 : idx; + showItem(); +} + + +void MenuBarEditor::safeDec() +{ + do { + currentIndex--; + } while ( currentIndex > 0 && !( item( currentIndex )->isVisible() ) ); +} + +void MenuBarEditor::safeInc() +{ + int max = (int)itemList.count(); + if ( !hasSeparator ) + max += 1; + if ( currentIndex < max ) { + do { + currentIndex++; + // skip invisible items + } while ( currentIndex < max && !( item( currentIndex )->isVisible() ) ); + } +} + +void MenuBarEditor::navigateLeft( bool ctrl ) +{ + // FIXME: handle invisible items + if ( currentIndex > 0 ) { + hideItem(); + if ( ctrl ) { + ExchangeMenuCommand * cmd = new ExchangeMenuCommand( "Move Menu Left", + formWnd, + this, + currentIndex, + currentIndex - 1 ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + safeDec(); + } else { + safeDec(); + } + showItem(); + } + update(); +} + +void MenuBarEditor::navigateRight( bool ctrl ) +{ +// FIXME: handle invisible items + hideItem(); + if ( ctrl ) { + if ( currentIndex < ( (int)itemList.count() - 1 ) ) { + ExchangeMenuCommand * cmd = new ExchangeMenuCommand( "Move Menu Right", + formWnd, + this, + currentIndex, + currentIndex + 1 ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + safeInc(); + } + } else { + safeInc(); + } + showItem(); + update(); +} + +void MenuBarEditor::enterEditMode() +{ + if ( currentIndex > (int)itemList.count() ) { + insertSeparator(); + } else { + showLineEdit(); + } +} + +void MenuBarEditor::leaveEditMode() +{ + MenuBarEditorItem * i = 0; + if ( currentIndex >= (int)itemList.count() ) { + i = createItem(); + // do not put rename on cmd stack + RenameMenuCommand rename( "Rename Menu", formWnd, this, lineEdit->text(), i ); + rename.execute(); + } else { + i = itemList.at( currentIndex ); + RenameMenuCommand * cmd = + new RenameMenuCommand( "Rename Menu", formWnd, this, lineEdit->text(), i ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + showItem(); +} + +QPixmap MenuBarEditor::createTextPixmap( const QString &text ) +{ + QSize sz( fontMetrics().boundingRect( text ).size() ); + QPixmap pix( sz.width() + 20, sz.height() * 2 ); + pix.fill( white ); + QPainter p( &pix, this ); + p.drawText( 2, 0, pix.width(), pix.height(), 0, text ); + p.end(); + QBitmap bm( pix.size() ); + bm.fill( color0 ); + p.begin( &bm ); + p.setPen( color1 ); + p.drawText( 2, 0, pix.width(), pix.height(), 0, text ); + p.end(); + pix.setMask( bm ); + return pix; +} diff --git a/tools/designer/designer/menubareditor.h b/tools/designer/designer/menubareditor.h new file mode 100644 index 0000000..59af1b4 --- /dev/null +++ b/tools/designer/designer/menubareditor.h @@ -0,0 +1,205 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef MENUBAREDITOR_H +#define MENUBAREDITOR_H + +#include +#include + +class PopupMenuEditor; +class MenuBarEditor; +class QActionGroup; + +class MenuBarEditorItem : public QObject +{ + Q_OBJECT + + friend class MenuBarEditor; + + MenuBarEditorItem( MenuBarEditor * bar = 0, QObject * parent = 0, const char * name = 0 ); + +public: + MenuBarEditorItem( PopupMenuEditor * menu, MenuBarEditor * bar, + QObject * parent = 0, const char * name = 0); + MenuBarEditorItem( QActionGroup * actionGroup, MenuBarEditor * bar, + QObject * parent = 0, const char * name = 0); + MenuBarEditorItem( MenuBarEditorItem * item, + QObject * parent = 0, const char * name = 0); + ~MenuBarEditorItem() { }; + + PopupMenuEditor * menu() { return popupMenu; } + + void setMenuText( const QString t ) { text = t; }; + QString menuText() { return text; } + + void setVisible( bool enable ) { visible = enable; } + bool isVisible() { return visible; } + + void setRemovable( bool enable ) { removable = enable; } + bool isRemovable() { return removable; } + + bool isSeparator() { return separator; } +protected: + void setSeparator( bool enable ) { separator = enable; } + +private: + MenuBarEditor * menuBar; + PopupMenuEditor * popupMenu; + QString text; + uint visible : 1; + uint separator : 1; + uint removable : 1; +}; + +class QLineEdit; +class FormWindow; + +class MenuBarEditor : public QMenuBar +{ + Q_OBJECT + +public: + MenuBarEditor( FormWindow * fw, QWidget * parent = 0, const char * name = 0 ); + ~MenuBarEditor(); + + FormWindow * formWindow(); + + MenuBarEditorItem * createItem( int index = -1, bool addToCmdStack = TRUE ); + void insertItem( MenuBarEditorItem * item, int index = -1 ); + void insertItem( QString text, PopupMenuEditor * menu, int index = -1 ); + void insertItem( QString text, QActionGroup * group, int index = -1 ); + + void insertSeparator( int index = -1 ); + + void removeItemAt( int index ); + void removeItem( MenuBarEditorItem * item ); + + int findItem( MenuBarEditorItem * item ); + int findItem( PopupMenuEditor * menu ); + int findItem( QPoint & pos ); + + MenuBarEditorItem * item( int index = -1 ); + + int count(); + int current(); + + void cut( int index ); + void copy( int index ); + void paste( int index ); + void exchange( int a, int b ); + + void showLineEdit( int index = -1); + void showItem( int index = -1 ); + void hideItem( int index = -1 ); + void focusItem( int index = -1 ); + void deleteItem( int index = -1 ); + + QSize sizeHint() const; + QSize minimumSize() const { return sizeHint(); } + QSize minimumSizeHint() const { return sizeHint(); } + int heightForWidth( int max_width ) const; + + void show(); + + void checkAccels( QMap &accels ); + +public slots: + void cut(); + void copy(); + void paste(); + +protected: + bool eventFilter( QObject * o, QEvent * e ); + void paintEvent( QPaintEvent * e ); + void mousePressEvent( QMouseEvent * e ); + void mouseDoubleClickEvent( QMouseEvent * e ); + void mouseMoveEvent( QMouseEvent * e ); + void dragEnterEvent( QDragEnterEvent * e ); + void dragLeaveEvent( QDragLeaveEvent * e ); + void dragMoveEvent( QDragMoveEvent * e ); + void dropEvent( QDropEvent * e ); + void keyPressEvent( QKeyEvent * e ); + void focusOutEvent( QFocusEvent * e ); + void resizeEvent( QResizeEvent * e ) { QFrame::resizeEvent( e ); } + + void resizeInternals(); + + void drawItems( QPainter & p ); + void drawItem( QPainter & p, MenuBarEditorItem * i, int idx, QPoint & pos ); + void drawSeparator( QPainter & p, QPoint & pos ); + + QSize itemSize( MenuBarEditorItem * i ); + void addItemSizeToCoords( MenuBarEditorItem * i, int & x, int & y, int w ); + + QPoint itemPos( int index ); + QPoint snapToItem( const QPoint & pos ); + void dropInPlace( MenuBarEditorItem * i, const QPoint & pos ); + + void safeDec(); + void safeInc(); + + void navigateLeft( bool ctrl ); + void navigateRight( bool ctrl ); + void enterEditMode(); + void leaveEditMode(); + + QPixmap createTextPixmap( const QString &text ); + int borderSize() const { return margin() + 4; } // add 4 pixels to the margin + +private: + FormWindow * formWnd; + QLineEdit * lineEdit; + QWidget * dropLine; + QPtrList itemList; + MenuBarEditorItem addItem; + MenuBarEditorItem addSeparator; + MenuBarEditorItem * draggedItem; + QPoint mousePressPos; + int currentIndex; + int itemHeight; + int separatorWidth; + bool hideWhenEmpty; + bool hasSeparator; + bool dropConfirmed; + + enum ClipboardOperation { + None = 0, + Cut = 1, + Copy = 2 + }; + static int clipboardOperation; + static MenuBarEditorItem * clipboardItem; +}; + +#endif //MENUBAREDITOR_H diff --git a/tools/designer/designer/metadatabase.cpp b/tools/designer/designer/metadatabase.cpp new file mode 100644 index 0000000..cd36cc0 --- /dev/null +++ b/tools/designer/designer/metadatabase.cpp @@ -0,0 +1,1693 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "metadatabase.h" +#include "widgetfactory.h" +#include "formwindow.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "formfile.h" +#include "propertyobject.h" +#include "project.h" +#include "mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class MetaDataBaseRecord +{ +public: + QObject *object; + QStringList changedProperties; + QMap fakeProperties; + QMap propertyComments; + int spacing, margin; + QString resizeMode; + QValueList connections; + QValueList functionList; + QValueList includes; + QValueList variables; + QStringList forwards, sigs; + QWidgetList tabOrder; + MetaDataBase::MetaInfo metaInfo; + QCursor cursor; + QMap pixmapArguments; + QMap pixmapKeys; + QMap columnFields; + QValueList breakPoints; + QMap breakPointConditions; + QString exportMacro; +}; + +static QPtrDict *db = 0; +static QPtrList *cWidgets = 0; +static bool doUpdate = TRUE; +static QStringList langList; +static QStringList editorLangList; +static QPluginManager *languageInterfaceManager = 0; + +/*! + \class MetaDataBase metadatabase.h + \brief Database which stores meta data of widgets + + The MetaDataBase stores meta information of widgets, which are not + stored directly in widgets (properties). This is e.g. the + information which properties have been modified. +*/ + +MetaDataBase::MetaDataBase() +{ +} + +inline void setupDataBase() +{ + if ( !db || !cWidgets ) { + db = new QPtrDict( 1481 ); + db->setAutoDelete( TRUE ); + cWidgets = new QPtrList; + cWidgets->setAutoDelete( TRUE ); + } +} + +void MetaDataBase::clearDataBase() +{ + delete db; + db = 0; + delete cWidgets; + cWidgets = 0; +} + +void MetaDataBase::addEntry( QObject *o ) +{ + if ( !o ) + return; + setupDataBase(); + if ( db->find( o ) ) + return; + MetaDataBaseRecord *r = new MetaDataBaseRecord; + r->object = o; + r->spacing = r->margin = -1; + db->insert( (void*)o, r ); + + WidgetFactory::initChangedProperties( o ); +} + +void MetaDataBase::removeEntry( QObject *o ) +{ + setupDataBase(); + db->remove( o ); +} + +void MetaDataBase::setPropertyChanged( QObject *o, const QString &property, bool changed ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdPropertyChanged( property, changed ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + if ( changed ) { + if ( r->changedProperties.findIndex( property ) == -1 ) + r->changedProperties.append( property ); + } else { + if ( r->changedProperties.findIndex( property ) != -1 ) + r->changedProperties.remove( property ); + } + + if ( doUpdate && + ( property == "hAlign" || property == "vAlign" || property == "wordwrap" ) ) { + doUpdate = FALSE; + setPropertyChanged( o, "alignment", changed || + isPropertyChanged( o, "hAlign" ) || + isPropertyChanged( o, "vAlign" ) || + isPropertyChanged( o, "wordwrap" ) ); + doUpdate = TRUE; + } + + if ( doUpdate && property == "alignment" ) { + doUpdate = FALSE; + setPropertyChanged( o, "hAlign", changed ); + setPropertyChanged( o, "vAlign", changed ); + setPropertyChanged( o, "wordwrap", changed ); + doUpdate = TRUE; + } +} + +bool MetaDataBase::isPropertyChanged( QObject *o, const QString &property ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdIsPropertyChanged( property ); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + return r->changedProperties.findIndex( property ) != -1; +} + +QStringList MetaDataBase::changedProperties( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QStringList(); + } + + QStringList lst( r->changedProperties ); + return lst; +} + +void MetaDataBase::setPropertyComment( QObject *o, const QString &property, const QString &comment ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdSetPropertyComment( property, comment ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->propertyComments.insert( property, comment ); +} + +QString MetaDataBase::propertyComment( QObject *o, const QString &property ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdPropertyComment( property ); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + + return *r->propertyComments.find( property ); +} + +void MetaDataBase::setFakeProperty( QObject *o, const QString &property, const QVariant& value ) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdSetFakeProperty( property, value ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + r->fakeProperties[property] = value; +} + +QVariant MetaDataBase::fakeProperty( QObject * o, const QString &property) +{ + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdFakeProperty( property ); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QVariant(); + } + QMap::Iterator it = r->fakeProperties.find( property ); + if ( it != r->fakeProperties.end() ) + return r->fakeProperties[property]; + return WidgetFactory::defaultValue( o, property ); + +} + +QMap* MetaDataBase::fakeProperties( QObject* o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return 0; + } + return &r->fakeProperties; +} + +void MetaDataBase::setSpacing( QObject *o, int spacing ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->spacing = spacing; + QLayout * layout = 0; + WidgetFactory::layoutType( (QWidget*)o, layout ); + if ( layout ) { + int spadef = 6; + if ( MainWindow::self->formWindow() ) + spadef = MainWindow::self->formWindow()->layoutDefaultSpacing(); + if ( spacing == -1 ) + layout->setSpacing( spadef ); + else + layout->setSpacing( spacing ); + } +} + +int MetaDataBase::spacing( QObject *o ) +{ + if ( !o ) + return -1; + setupDataBase(); + if ( ::qt_cast(o) ) + o = ( (QMainWindow*)o )->centralWidget(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return -1; + } + + return r->spacing; +} + +void MetaDataBase::setMargin( QObject *o, int margin ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->margin = margin; + QLayout * layout = 0; + WidgetFactory::layoutType( (QWidget*)o, layout ); + + bool isInnerLayout = TRUE; + + QWidget *widget = (QWidget*)o; + if ( widget && !::qt_cast(widget) && + ( WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( widget ) ) ) || + widget && widget->parentWidget() && ::qt_cast(widget->parentWidget()) ) ) + isInnerLayout = FALSE; + + + if ( layout ) { + int mardef = 11; + if ( MainWindow::self->formWindow() ) + mardef = MainWindow::self->formWindow()->layoutDefaultMargin(); + if ( margin == -1 ) { + if ( isInnerLayout ) + layout->setMargin( 1 ); + else + layout->setMargin( QMAX( 1, mardef ) ); + } + else + layout->setMargin( QMAX( 1, margin ) ); + } +} + +int MetaDataBase::margin( QObject *o ) +{ + if ( !o ) + return -1; + setupDataBase(); + if ( ::qt_cast(o) ) + o = ( (QMainWindow*)o )->centralWidget(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return -1; + } + return r->margin; +} + +void MetaDataBase::setResizeMode( QObject *o, const QString &mode ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->resizeMode = mode; +} + +QString MetaDataBase::resizeMode( QObject *o ) +{ + if ( !o ) + return QString::null; + setupDataBase(); + if ( ::qt_cast(o) ) + o = ( (QMainWindow*)o )->centralWidget(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r || !o->isWidgetType() ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + return r->resizeMode; +} + +void MetaDataBase::addConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot, bool addCode ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + if ( !(sender && receiver) ) + return; + Connection conn; + conn.sender = sender; + conn.signal = signal; + conn.receiver = receiver; + conn.slot = slot; + r->connections.append( conn ); + if ( addCode ) { + QString rec = receiver->name(); + if ( ::qt_cast(o) && receiver == ( (FormWindow*)o )->mainContainer() ) + rec = "this"; + QString sen = sender->name(); + if ( ::qt_cast(o) && sender == ( (FormWindow*)o )->mainContainer() ) + sen = "this"; + FormFile *ff = 0; + if ( ::qt_cast(o) ) + ff = (FormFile*)o; + else if ( ::qt_cast(o) ) + ff = ( (FormWindow*)o )->formFile(); + ff->addConnection( sen, signal, rec, slot ); + } +} + +void MetaDataBase::removeConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + if ( !(sender && receiver) ) + return; + for ( QValueList::Iterator it = r->connections.begin(); it != r->connections.end(); ++it ) { + Connection conn = *it; + if ( conn.sender == sender && + conn.signal == signal && + conn.receiver == receiver && + conn.slot == slot ) { + r->connections.remove( it ); + break; + } + } + if ( ::qt_cast(o) ) { + QString rec = receiver->name(); + if ( receiver == ( (FormWindow*)o )->mainContainer() ) + rec = "this"; + ( (FormWindow*)o )->formFile()->removeConnection( sender->name(), signal, rec, slot ); + } +} + +void MetaDataBase::setupConnections( QObject *o, const QValueList &conns ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + if ( !::qt_cast(o) ) + return; + + FormFile *formfile = (FormFile*)o; + + r->connections.clear(); + + for ( QValueList::ConstIterator cit = conns.begin(); + cit != conns.end(); ++cit ) { + // #### get the correct sender object out of Bla.Blub.sender + QString senderName = (*cit).sender; + if ( senderName.find( '.' ) != -1 ) + senderName = senderName.mid( senderName.findRev( '.' ) + 1 ); + QObject *sender = 0; + if ( formfile->formWindow() ) + sender = formfile->formWindow()->child( senderName ); + if ( !sender && formfile->isFake() ) + sender = formfile->project()->objectForFakeFormFile( formfile ); + if ( !sender && senderName == "this" ) + sender = formfile->formWindow() ? + formfile->formWindow()->mainContainer() : + formfile->project()->objectForFakeFormFile( formfile ); + if ( !sender ) + continue; + MetaDataBase::addConnection( formfile->formWindow() ? + (QObject*)formfile->formWindow() : + (QObject*)formfile, + sender, + (*cit).signal.latin1(), + formfile->formWindow() ? + formfile->formWindow()->mainContainer() : + formfile->project()->objectForFakeFormFile( formfile ), + (*cit).slot.latin1(), + FALSE ); + } +} + +bool MetaDataBase::hasConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + for ( QValueList::Iterator it = r->connections.begin(); it != r->connections.end(); ++it ) { + Connection conn = *it; + if ( conn.sender == sender && + conn.signal == signal && + conn.receiver == receiver && + conn.slot == slot ) + return TRUE; + } + return FALSE; +} + + +QValueList MetaDataBase::connections( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList(); + } + return r->connections; +} + +QValueList MetaDataBase::connections( QObject *o, QObject *sender, + QObject *receiver ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList(); + } + QValueList::Iterator it = r->connections.begin(); + QValueList ret; + QValueList::Iterator conn; + while ( ( conn = it ) != r->connections.end() ) { + ++it; + if ( (*conn).sender == sender && + (*conn).receiver == receiver ) + ret << *conn; + } + + return ret; +} + +QValueList MetaDataBase::connections( QObject *o, QObject *object ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList(); + } + QValueList::Iterator it = r->connections.begin(); + QValueList ret; + QValueList::Iterator conn; + while ( ( conn = it ) != r->connections.end() ) { + ++it; + if ( (*conn).sender == object || + (*conn).receiver == object ) + ret << *conn; + } + return ret; +} + +void MetaDataBase::doConnections( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + QObject *sender = 0, *receiver = 0; + QObjectList *l = 0; + QValueList::Iterator it = r->connections.begin(); + for ( ; it != r->connections.end(); ++it ) { + Connection conn = *it; + if ( qstrcmp( conn.sender->name(), o->name() ) == 0 ) { + sender = o; + } else { + l = o->queryList( 0, conn.sender->name(), FALSE ); + if ( !l || !l->first() ) { + delete l; + continue; + } + sender = l->first(); + delete l; + } + if ( qstrcmp( conn.receiver->name(), o->name() ) == 0 ) { + receiver = o; + } else { + l = o->queryList( 0, conn.receiver->name(), FALSE ); + if ( !l || !l->first() ) { + delete l; + continue; + } + receiver = l->first(); + delete l; + } + QString s = "2""%1"; + s = s.arg( conn.signal ); + QString s2 = "1""%1"; + s2 = s2.arg( conn.slot ); + + QStrList signalList = sender->metaObject()->signalNames( TRUE ); + QStrList slotList = receiver->metaObject()->slotNames( TRUE ); + + // avoid warnings + if ( signalList.find( conn.signal ) == -1 || + slotList.find( conn.slot ) == -1 ) + continue; + + QObject::connect( sender, s, receiver, s2 ); + } +} + +bool MetaDataBase::hasSlot( QObject *o, const QCString &slot, bool onlyCustom ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + if ( !onlyCustom ) { + QStrList slotList = o->metaObject()->slotNames( TRUE ); + if ( slotList.find( slot ) != -1 ) + return TRUE; + + if ( ::qt_cast(o) ) { + o = ( (FormWindow*)o )->mainContainer(); + slotList = o->metaObject()->slotNames( TRUE ); + if ( slotList.find( slot ) != -1 ) + return TRUE; + } + + //if ( ::qt_cast(o) ) { + if ( o->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *w = ( (::CustomWidget*)o )->customWidget(); + for ( QValueList::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) { + QCString s = (*it).function; + if ( !s.data() ) + continue; + if ( s == slot ) + return TRUE; + } + } + } + + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + Function f = *it; + if ( normalizeFunction( f.function ) == normalizeFunction( slot ) && f.type == "slot" ) + return TRUE; + } + + return FALSE; +} + +bool MetaDataBase::isSlotUsed( QObject *o, const QCString &slot ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + QValueList conns = connections( o ); + for ( QValueList::Iterator it = conns.begin(); it != conns.end(); ++it ) { + if ( (*it).slot == slot ) + return TRUE; + } + return FALSE; +} + + +void MetaDataBase::addFunction( QObject *o, const QCString &function, const QString &specifier, + const QString &access, const QString &type, const QString &language, + const QString &returnType ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + Function f; + f.function = function; + f.specifier = specifier; + f.access = access; + f.type = type; + f.language = language; + f.returnType = returnType; + QValueList::Iterator it = r->functionList.find( f ); + if ( it != r->functionList.end() ) + r->functionList.remove( it ); + r->functionList.append( f ); + ( (FormWindow*)o )->formFile()->addFunctionCode( f ); +} + +void MetaDataBase::setFunctionList( QObject *o, const QValueList &functionList ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + r->functionList = functionList; +} + +void MetaDataBase::removeFunction( QObject *o, const QCString &function, const QString &specifier, + const QString &access, const QString &type, const QString &language, + const QString &returnType ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( MetaDataBase::normalizeFunction( (*it).function ) == + MetaDataBase::normalizeFunction( function ) && + (*it).specifier == specifier && + (*it).access == access && + (*it).type == type && + ( language.isEmpty() || (*it).language == language ) && + ( returnType.isEmpty() || (*it).returnType == returnType ) ) { + ( (FormWindow*)o )->formFile()->removeFunctionCode( *it ); + r->functionList.remove( it ); + break; + } + } +} + +void MetaDataBase::removeFunction( QObject *o, const QString &function ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( normalizeFunction( (*it).function ) == normalizeFunction( function ) ) { + ( (FormWindow*)o )->formFile()->removeFunctionCode( *it ); + r->functionList.remove( it ); + break; + } + } +} + +QValueList MetaDataBase::functionList( QObject *o, bool onlyFunctions ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList(); + } + if ( !onlyFunctions ) + return r->functionList; + QValueList fList; + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( (*it).type == "function" ) + fList.append( *it ); + } + return fList; +} + +QValueList MetaDataBase::slotList( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList(); + } + QValueList slotList; + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( (*it).type == "slot" ) + slotList.append( *it ); + } + return slotList; +} + +void MetaDataBase::changeFunction( QObject *o, const QString &function, const QString &newName, + const QString &returnType ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + Function f = *it; + if ( normalizeFunction( f.function ) == normalizeFunction( function ) ) { + (*it).function = newName; + if ( !returnType.isNull() ) + (*it).returnType = returnType; + return; + } + } +} + +void MetaDataBase::changeFunctionAttributes( QObject *o, const QString &oldName, const QString &newName, + const QString &specifier, const QString &access, + const QString &type, const QString &language, + const QString &returnType ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + Function f = *it; + if ( normalizeFunction( f.function ) == normalizeFunction( oldName ) ) { + (*it).function = newName; + (*it).specifier = specifier; + (*it).access = access; + (*it).type = type; + (*it).language = language; + (*it).returnType = returnType; + return; + } + } +} + +bool MetaDataBase::hasFunction( QObject *o, const QCString &function, bool onlyCustom ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + if ( !onlyCustom ) { + QStrList functionList = o->metaObject()->slotNames( TRUE ); + if ( functionList.find( function ) != -1 ) + return TRUE; + + if ( ::qt_cast(o) ) { + o = ( (FormWindow*)o )->mainContainer(); + functionList = o->metaObject()->slotNames( TRUE ); + if ( functionList.find( function ) != -1 ) + return TRUE; + } + + //if ( ::qt_cast(o) ) { + if ( o->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *w = ( (::CustomWidget*)o )->customWidget(); + for ( QValueList::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) { + QCString s = (*it).function; + if ( !s.data() ) + continue; + if ( s == function ) + return TRUE; + } + } + } + + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + Function f = *it; + if ( normalizeFunction( f.function ) == normalizeFunction( function ) ) + return TRUE; + } + + return FALSE; +} + +QString MetaDataBase::languageOfFunction( QObject *o, const QCString &function ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + + QString fu = normalizeFunction( function ); + for ( QValueList::Iterator it = r->functionList.begin(); it != r->functionList.end(); ++it ) { + if ( fu == normalizeFunction( (*it).function ) ) + return (*it).language; + } + return QString::null; +} + +bool MetaDataBase::addCustomWidget( CustomWidget *wid ) +{ + setupDataBase(); + + for ( CustomWidget *w = cWidgets->first(); w; w = cWidgets->next() ) { + if ( *wid == *w ) { + for ( QValueList::ConstIterator it = wid->lstSignals.begin(); it != wid->lstSignals.end(); ++it ) { + if ( !w->hasSignal( *it ) ) + w->lstSignals.append( *it ); + } + for ( QValueList::ConstIterator it2 = wid->lstSlots.begin(); it2 != wid->lstSlots.end(); ++it2 ) { + if ( !w->hasSlot( MetaDataBase::normalizeFunction( (*it2).function ).latin1() ) ) + w->lstSlots.append( *it2 ); + } + for ( QValueList::ConstIterator it3 = wid->lstProperties.begin(); it3 != wid->lstProperties.end(); ++it3 ) { + if ( !w->hasProperty( (*it3).property ) ) + w->lstProperties.append( *it3 ); + } + delete wid; + return FALSE; + } + } + + + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + r->name = wid->className; + r->includeFile = wid->includeFile; + r->group = WidgetDatabase::widgetGroup( "Custom" ); + r->toolTip = wid->className; + r->icon = new QIconSet( *wid->pixmap, *wid->pixmap ); + r->isContainer = wid->isContainer; + wid->id = WidgetDatabase::addCustomWidget( r ); + cWidgets->append( wid ); + return TRUE; +} + +void MetaDataBase::removeCustomWidget( CustomWidget *w ) +{ + cWidgets->removeRef( w ); +} + +QPtrList *MetaDataBase::customWidgets() +{ + setupDataBase(); + return cWidgets; +} + +MetaDataBase::CustomWidget *MetaDataBase::customWidget( int id ) +{ + for ( CustomWidget *w = cWidgets->first(); w; w = cWidgets->next() ) { + if ( id == w->id ) + return w; + } + return 0; +} + +bool MetaDataBase::isWidgetNameUsed( CustomWidget *wid ) +{ + for ( CustomWidget *w = cWidgets->first(); w; w = cWidgets->next() ) { + if ( w == wid ) + continue; + if ( wid->className == w->className ) + return TRUE; + } + return FALSE; +} + +bool MetaDataBase::hasCustomWidget( const QString &className ) +{ + for ( CustomWidget *w = cWidgets->first(); w; w = cWidgets->next() ) { + if ( w->className == className ) + return TRUE; + } + return FALSE; +} + +void MetaDataBase::setTabOrder( QWidget *w, const QWidgetList &order ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*) w ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + w, w->name(), w->className() ); + return; + } + + r->tabOrder = order; +} + +QWidgetList MetaDataBase::tabOrder( QWidget *w ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*) w ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + w, w->name(), w->className() ); + return QWidgetList(); + } + + return r->tabOrder; +} + +void MetaDataBase::setIncludes( QObject *o, const QValueList &incs ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->includes = incs; +} + +QValueList MetaDataBase::includes( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList(); + } + + return r->includes; +} + +void MetaDataBase::setForwards( QObject *o, const QStringList &fwds ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->forwards = fwds; +} + +QStringList MetaDataBase::forwards( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QStringList(); + } + + return r->forwards; +} + +void MetaDataBase::setVariables( QObject *o, const QValueList &vars ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->variables = vars; +} + +void MetaDataBase::addVariable( QObject *o, const QString &name, const QString &access ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + Variable v; + v.varName = name; + v.varAccess = access; + r->variables << v; +} + +void MetaDataBase::removeVariable( QObject *o, const QString &name ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + QValueList::Iterator it = r->variables.begin(); + for ( ; it != r->variables.end(); ++it ) { + if ( (*it).varName == name ) { + r->variables.remove( it ); + break; + } + } +} + +QValueList MetaDataBase::variables( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList(); + } + + return r->variables; +} + +bool MetaDataBase::hasVariable( QObject *o, const QString &name ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return FALSE; + } + + QValueList::Iterator it = r->variables.begin(); + for ( ; it != r->variables.end(); ++it ) { + if ( extractVariableName( name ) == extractVariableName( (*it).varName ) ) + return TRUE; + } + return FALSE; +} + +QString MetaDataBase::extractVariableName( const QString &name ) +{ + QString n = name.right( name.length() - name.findRev( ' ' ) - 1 ); + if ( n[ 0 ] == '*' || n[ 0 ] == '&' ) + n[ 0 ] = ' '; + if ( n[ (int)n.length() - 1 ] == ';' ) + n[ (int)n.length() - 1 ] = ' '; + return n.simplifyWhiteSpace(); +} + +void MetaDataBase::setSignalList( QObject *o, const QStringList &sigs ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->sigs.clear(); + + for ( QStringList::ConstIterator it = sigs.begin(); it != sigs.end(); ++it ) { + QString s = (*it).simplifyWhiteSpace(); + bool hasSemicolon = s.endsWith( ";" ); + if ( hasSemicolon ) + s = s.left( s.length() - 1 ); + int p = s.find( '(' ); + if ( p < 0 ) + p = s.length(); + int sp = s.find( ' ' ); + if ( sp >= 0 && sp < p ) { + s = s.mid( sp+1 ); + p -= sp + 1; + } + if ( p == (int) s.length() ) + s += "()"; + if ( hasSemicolon ) + s += ";"; + r->sigs << s; + } +} + +QStringList MetaDataBase::signalList( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QStringList(); + } + + return r->sigs; +} + +void MetaDataBase::setMetaInfo( QObject *o, MetaInfo mi ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->metaInfo = mi; +} + +MetaDataBase::MetaInfo MetaDataBase::metaInfo( QObject *o ) +{ + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return MetaInfo(); + } + + return r->metaInfo; +} + + + + +MetaDataBase::CustomWidget::CustomWidget() +{ + className = "MyCustomWidget"; + includeFile = "mywidget.h"; + includePolicy = Local; + sizeHint = QSize( -1, -1 ); + pixmap = new QPixmap( QPixmap::fromMimeSource( "designer_customwidget.png" ) ); + id = -1; + sizePolicy = QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + isContainer = FALSE; +} + +MetaDataBase::CustomWidget::CustomWidget( const CustomWidget &w ) +{ + className = w.className; + includeFile = w.includeFile; + includePolicy = w.includePolicy; + sizeHint = w.sizeHint; + if ( w.pixmap ) + pixmap = new QPixmap( *w.pixmap ); + else + pixmap = 0; + id = w.id; + isContainer = w.isContainer; +} + +void MetaDataBase::setCursor( QWidget *w, const QCursor &c ) +{ + setupDataBase(); + if ( w->isA( "PropertyObject" ) ) { + ( (PropertyObject*)w )->mdSetCursor( c ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)w ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + w, w->name(), w->className() ); + return; + } + + r->cursor = c; +} + +QCursor MetaDataBase::cursor( QWidget *w ) +{ + setupDataBase(); + if ( w->isA( "PropertyObject" ) ) + return ( (PropertyObject*)w )->mdCursor(); + MetaDataBaseRecord *r = db->find( (void*)w ); + if ( !r ) { + w->unsetCursor(); + return w->cursor(); + } + + return r->cursor; +} + +bool MetaDataBase::CustomWidget::operator==( const CustomWidget &w ) const +{ + return className == w.className; +} + +MetaDataBase::CustomWidget &MetaDataBase::CustomWidget::operator=( const CustomWidget &w ) +{ + delete pixmap; + className = w.className; + includeFile = w.includeFile; + includePolicy = w.includePolicy; + sizeHint = w.sizeHint; + if ( w.pixmap ) + pixmap = new QPixmap( *w.pixmap ); + else + pixmap = 0; + lstSignals = w.lstSignals; + lstSlots = w.lstSlots; + lstProperties = w.lstProperties; + id = w.id; + isContainer = w.isContainer; + return *this; +} + +bool MetaDataBase::CustomWidget::hasSignal( const QCString &signal ) const +{ + QStrList sigList = QWidget::staticMetaObject()->signalNames( TRUE ); + if ( sigList.find( signal ) != -1 ) + return TRUE; + for ( QValueList::ConstIterator it = lstSignals.begin(); it != lstSignals.end(); ++it ) { + if ( normalizeFunction( *it ) == normalizeFunction( signal ) ) + return TRUE; + } + return FALSE; +} + +bool MetaDataBase::CustomWidget::hasSlot( const QCString &slot ) const +{ + QStrList slotList = QWidget::staticMetaObject()->slotNames( TRUE ); + if ( slotList.find( normalizeFunction( slot ) ) != -1 ) + return TRUE; + + for ( QValueList::ConstIterator it = lstSlots.begin(); it != lstSlots.end(); ++it ) { + if ( normalizeFunction( (*it).function ) == normalizeFunction( slot ) ) + return TRUE; + } + return FALSE; +} + +bool MetaDataBase::CustomWidget::hasProperty( const QCString &prop ) const +{ + QStrList propList = QWidget::staticMetaObject()->propertyNames( TRUE ); + if ( propList.find( prop ) != -1 ) + return TRUE; + + for ( QValueList::ConstIterator it = lstProperties.begin(); it != lstProperties.end(); ++it ) { + if ( (*it).property == prop ) + return TRUE; + } + return FALSE; +} + +void MetaDataBase::setPixmapArgument( QObject *o, int pixmap, const QString &arg ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->pixmapArguments.remove( pixmap ); + r->pixmapArguments.insert( pixmap, arg ); +} + +QString MetaDataBase::pixmapArgument( QObject *o, int pixmap ) +{ + if ( !o ) + return QString::null; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + + return *r->pixmapArguments.find( pixmap ); +} + +void MetaDataBase::clearPixmapArguments( QObject *o ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->pixmapArguments.clear(); +} + + +void MetaDataBase::setPixmapKey( QObject *o, int pixmap, const QString &arg ) +{ + if ( !o ) + return; + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdSetPixmapKey( pixmap, arg ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->pixmapKeys.remove( pixmap ); + r->pixmapKeys.insert( pixmap, arg ); +} + +QString MetaDataBase::pixmapKey( QObject *o, int pixmap ) +{ + if ( !o ) + return QString::null; + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdPixmapKey( pixmap ); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + + QString s = *r->pixmapKeys.find( pixmap ); + if ( !s.isNull() ) + return s; + if ( !o->isWidgetType() ) + return s; + QWidget *w = (QWidget*)o; + if ( w->icon() ) + return *r->pixmapKeys.find( w->icon()->serialNumber() ); + return s; +} + +void MetaDataBase::clearPixmapKeys( QObject *o ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->pixmapKeys.clear(); +} + + + +void MetaDataBase::setColumnFields( QObject *o, const QMap &columnFields ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->columnFields = columnFields; +} + +QMap MetaDataBase::columnFields( QObject *o ) +{ + if ( !o ) + return QMap(); + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QMap(); + } + + return r->columnFields; +} + +void MetaDataBase::setEditor( const QStringList &langs ) +{ + editorLangList = langs; +} + +bool MetaDataBase::hasEditor( const QString &lang ) +{ + return editorLangList.find( lang ) != editorLangList.end(); +} + +void MetaDataBase::setupInterfaceManagers( const QString &plugDir ) +{ + if ( !languageInterfaceManager ) { + languageInterfaceManager = + new QPluginManager( IID_Language, + QApplication::libraryPaths(), + plugDir ); + + langList = languageInterfaceManager->featureList(); + langList.remove( "C++" ); + langList << "C++"; + } +} + +QStringList MetaDataBase::languages() +{ + return langList; +} + +QString MetaDataBase::normalizeFunction( const QString &f ) +{ + return Parser::cleanArgs( f ); +} + +LanguageInterface *MetaDataBase::languageInterface( const QString &lang ) +{ + LanguageInterface* iface = 0; + languageInterfaceManager->queryInterface( lang, &iface ); + return iface; +} + +void MetaDataBase::clear( QObject *o ) +{ + if ( !o ) + return; + setupDataBase(); + db->remove( (void*)o ); + for ( QPtrDictIterator it( *( (FormWindow*)o )->widgets() ); it.current(); ++it ) + db->remove( (void*)it.current() ); +} + +void MetaDataBase::setBreakPoints( QObject *o, const QValueList &l ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->breakPoints = l; + + QMap::Iterator it = r->breakPointConditions.begin(); + while ( it != r->breakPointConditions.end() ) { + int line = it.key(); + ++it; + if ( r->breakPoints.find( line ) == r->breakPoints.end() ) + r->breakPointConditions.remove( r->breakPointConditions.find( line ) ); + } +} + +QValueList MetaDataBase::breakPoints( QObject *o ) +{ + if ( !o ) + return QValueList(); + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QValueList(); + } + + return r->breakPoints; +} + +void MetaDataBase::setBreakPointCondition( QObject *o, int line, const QString &condition ) +{ + if ( !o ) + return; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + r->breakPointConditions.replace( line, condition ); +} + +QString MetaDataBase::breakPointCondition( QObject *o, int line ) +{ + if ( !o ) + return QString::null; + setupDataBase(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return QString::null; + } + QMap::Iterator it = r->breakPointConditions.find( line ); + if ( it == r->breakPointConditions.end() ) + return QString::null; + return *it; +} + +void MetaDataBase::setExportMacro( QObject *o, const QString ¯o ) +{ + if ( !o ) + return; + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) { + ( (PropertyObject*)o )->mdSetExportMacro( macro ); + return; + } + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return; + } + + r->exportMacro = macro; +} + +QString MetaDataBase::exportMacro( QObject *o ) +{ + if ( !o ) + return ""; + setupDataBase(); + if ( o->isA( "PropertyObject" ) ) + return ( (PropertyObject*)o )->mdExportMacro(); + MetaDataBaseRecord *r = db->find( (void*)o ); + if ( !r ) { + qWarning( "No entry for %p (%s, %s) found in MetaDataBase", + o, o->name(), o->className() ); + return ""; + } + + return r->exportMacro; +} + +bool MetaDataBase::hasObject( QObject *o ) +{ + return !!db->find( o ); +} diff --git a/tools/designer/designer/metadatabase.h b/tools/designer/designer/metadatabase.h new file mode 100644 index 0000000..707cc69 --- /dev/null +++ b/tools/designer/designer/metadatabase.h @@ -0,0 +1,276 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef METADATABASE_H +#define METADATABASE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pixmapchooser.h" +#include "../interfaces/languageinterface.h" + +class QObject; +class QPixmap; +struct LanguageInterface; + +class MetaDataBase +{ +public: + struct Connection + { + QObject *sender, *receiver; + QCString signal, slot; + bool operator==( const Connection &c ) const { + return sender == c.sender && receiver == c.receiver && + signal == c.signal && slot == c.slot ; + } + }; + + struct Function + { + QString returnType; + QCString function; + QString specifier; + QString access; + QString type; + QString language; + bool operator==( const Function &f ) const { + return ( returnType == f.returnType && + function == f.function && + specifier == f.specifier && + access == f.access && + type == f.type && + language == f.language + ); + } + }; + + struct Property + { + QCString property; + QString type; + bool operator==( const Property &p ) const { + return property == p.property && + type == p.type; + } + }; + + struct CustomWidget + { + CustomWidget(); + CustomWidget( const CustomWidget &w ); + ~CustomWidget() { delete pixmap; } // inlined to work around 2.7.2.3 bug + bool operator==( const CustomWidget &w ) const; + CustomWidget &operator=( const CustomWidget &w ); + + bool hasSignal( const QCString &signal ) const; + bool hasSlot( const QCString &slot ) const; + bool hasProperty( const QCString &prop ) const; + + enum IncludePolicy { Global, Local }; + QString className; + QString includeFile; + IncludePolicy includePolicy; + QSize sizeHint; + QSizePolicy sizePolicy; + QPixmap *pixmap; + QValueList lstSignals; + QValueList lstSlots; + QValueList lstProperties; + int id; + bool isContainer; + }; + + struct Include + { + Include() : header(), location(), implDecl( "in implementation" ) {} + QString header; + QString location; + bool operator==( const Include &i ) const { + return header == i.header && location == i.location; + } + QString implDecl; + }; + + struct Variable + { + QString varName; + QString varAccess; + bool operator==( const Variable &v ) const { + return varName == v.varName && + varAccess == v.varAccess; + } + }; + + struct MetaInfo + { + MetaInfo() : classNameChanged( FALSE ) { } + QString className; + bool classNameChanged; + QString comment; + QString author; + }; + + MetaDataBase(); + static void clearDataBase(); + + static void addEntry( QObject *o ); + static void removeEntry( QObject *o ); + static void setPropertyChanged( QObject *o, const QString &property, bool changed ); + static bool isPropertyChanged( QObject *o, const QString &property ); + static void setPropertyComment( QObject *o, const QString &property, const QString &comment ); + static QString propertyComment( QObject *o, const QString &property ); + static QStringList changedProperties( QObject *o ); + + static void setFakeProperty( QObject *o, const QString &property, const QVariant& value ); + static QVariant fakeProperty( QObject * o, const QString &property ); + static QMap* fakeProperties( QObject* o ); + + static void setSpacing( QObject *o, int spacing ); + static int spacing( QObject *o ); + static void setMargin( QObject *o, int margin ); + static int margin( QObject *o ); + + static void setResizeMode( QObject *o, const QString &mode ); + static QString resizeMode( QObject *o ); + + static void addConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot, bool addCode = TRUE ); + static void removeConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot ); + static bool hasConnection( QObject *o, QObject *sender, const QCString &signal, + QObject *receiver, const QCString &slot ); + static void setupConnections( QObject *o, const QValueList &conns ); + static QValueList connections( QObject *o ); + static QValueList connections( QObject *o, QObject *sender, QObject *receiver ); + static QValueList connections( QObject *o, QObject *object ); + static void doConnections( QObject *o ); + + static void addFunction( QObject *o, const QCString &function, const QString &specifier, + const QString &access, const QString &type, const QString &language, + const QString &returnType ); + static void removeFunction( QObject *o, const QCString &function, const QString &specifier, + const QString &access, const QString &type, const QString &language, + const QString &returnType ); + static void removeFunction( QObject *o, const QString &function ); + static QValueList functionList( QObject *o, bool onlyFunctions = FALSE ); + static QValueList slotList( QObject *o ); + static bool isSlotUsed( QObject *o, const QCString &slot ); + static bool hasFunction( QObject *o, const QCString &function, bool onlyCustom = FALSE ); + static bool hasSlot( QObject *o, const QCString &slot, bool onlyCustom = FALSE ); + static void changeFunction( QObject *o, const QString &function, const QString &newName, + const QString &returnType ); + static void changeFunctionAttributes( QObject *o, const QString &oldName, const QString &newName, + const QString &specifier, const QString &access, + const QString &type, const QString &language, + const QString &returnType ); + static QString languageOfFunction( QObject *o, const QCString &function ); + static void setFunctionList( QObject *o, const QValueList &functionList ); + + + static bool addCustomWidget( CustomWidget *w ); + static void removeCustomWidget( CustomWidget *w ); + static QPtrList *customWidgets(); + static CustomWidget *customWidget( int id ); + static bool isWidgetNameUsed( CustomWidget *w ); + static bool hasCustomWidget( const QString &className ); + + static void setTabOrder( QWidget *w, const QWidgetList &order ); + static QWidgetList tabOrder( QWidget *w ); + + static void setIncludes( QObject *o, const QValueList &incs ); + static QValueList includes( QObject *o ); + + static void setForwards( QObject *o, const QStringList &fwds ); + static QStringList forwards( QObject *o ); + + static void setVariables( QObject *o, const QValueList &vars ); + static void addVariable( QObject *o, const QString &name, const QString &access ); + static void removeVariable( QObject *o, const QString &name ); + static QValueList variables( QObject *o ); + static bool hasVariable( QObject *o, const QString &name ); + static QString extractVariableName( const QString &name ); + + static void setSignalList( QObject *o, const QStringList &sigs ); + static QStringList signalList( QObject *o ); + + static void setMetaInfo( QObject *o, MetaInfo mi ); + static MetaInfo metaInfo( QObject *o ); + + static void setCursor( QWidget *w, const QCursor &c ); + static QCursor cursor( QWidget *w ); + + static void setPixmapArgument( QObject *o, int pixmap, const QString &arg ); + static QString pixmapArgument( QObject *o, int pixmap ); + static void clearPixmapArguments( QObject *o ); + + static void setPixmapKey( QObject *o, int pixmap, const QString &arg ); + static QString pixmapKey( QObject *o, int pixmap ); + static void clearPixmapKeys( QObject *o ); + + static void setColumnFields( QObject *o, const QMap &columnFields ); + static QMap columnFields( QObject *o ); + + static void setEditor( const QStringList &langs ); + static bool hasEditor( const QString &lang ); + + static void setupInterfaceManagers( const QString &plugDir ); + static QStringList languages(); + + static LanguageInterface *languageInterface( const QString &lang ); + + static QString normalizeFunction( const QString &f ); + + static void clear( QObject *o ); + + static void setBreakPoints( QObject *o, const QValueList &l ); + static void setBreakPointCondition( QObject *o, int line, const QString &condition ); + static QValueList breakPoints( QObject *o ); + static QString breakPointCondition( QObject *o, int line ); + + static void setExportMacro( QObject *o, const QString ¯o ); + static QString exportMacro( QObject *o ); + + static bool hasObject( QObject *o ); + +}; + +#endif diff --git a/tools/designer/designer/multilineeditor.ui b/tools/designer/designer/multilineeditor.ui new file mode 100644 index 0000000..85923e2 --- /dev/null +++ b/tools/designer/designer/multilineeditor.ui @@ -0,0 +1,188 @@ + +MultiLineEditorBase +********************************************************************* +** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + MultiLineEditorBase + + + + 0 + 0 + 598 + 307 + + + + Edit Text + + + <b>Multiline Edit</b><p>This is a simple richtext editor. For an easier working, it provides the most common html tags in form of toolbar items respectively shortcuts. By clicking on such an icon, the regarding tag will be written to the editor and you can insert your text. If you have already written a text and want to format it, just mark it and click on the wished tag button. For a better visualization this editor supports also a simple html syntax highlighting. + + + + unnamed + + + 11 + + + 6 + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + OkButton + + + &OK + + + false + + + true + + + true + + + + + applyButton + + + &Apply + + + + + cancelButton + + + &Cancel + + + + + Spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + helpButton + + + &Help + + + + + + + + + + + menuBar + + + + + + + OkButton + clicked() + MultiLineEditorBase + okClicked() + + + applyButton + clicked() + MultiLineEditorBase + applyClicked() + + + cancelButton + clicked() + MultiLineEditorBase + cancelClicked() + + + + applyClicked() + okClicked() + cancelClicked() + + + diff --git a/tools/designer/designer/multilineeditorimpl.cpp b/tools/designer/designer/multilineeditorimpl.cpp new file mode 100644 index 0000000..a1dd51b --- /dev/null +++ b/tools/designer/designer/multilineeditorimpl.cpp @@ -0,0 +1,417 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "multilineeditorimpl.h" +#include "formwindow.h" +#include "command.h" +#include "mainwindow.h" +#include "richtextfontdialog.h" +#include "syntaxhighlighter_html.h" +#include "widgetfactory.h" + +#include +#include <./private/qrichtext_p.h> +#include +#include +#include +#include +#include +#include + +ToolBarItem::ToolBarItem( QWidget *parent, QWidget *toolBar, + const QString &label, const QString &tagstr, + const QIconSet &icon, const QKeySequence &key ) + : QAction( parent ) +{ + setIconSet( icon ); + setText( label ); + setAccel( key ); + addTo( toolBar ); + tag = tagstr; + connect( this, SIGNAL( activated() ), this, SLOT( wasActivated() ) ); +} + +ToolBarItem::~ToolBarItem() +{ + +} + +void ToolBarItem::wasActivated() +{ + emit clicked( tag ); +} + +TextEdit::TextEdit( QWidget *parent, const char *name ) + : QTextEdit( parent, name ) +{ + setTextFormat( Qt::PlainText ); +} + +QTextParagraph* TextEdit::paragraph() +{ + QTextCursor *tc = new QTextCursor( QTextEdit::document() ); + return tc->paragraph(); +} + + +MultiLineEditor::MultiLineEditor( bool call_static, bool richtextMode, QWidget *parent, QWidget *editWidget, + FormWindow *fw, const QString &text ) + : MultiLineEditorBase( parent, 0, WType_Dialog | WShowModal ), formwindow( fw ), doWrap( FALSE ) +{ + callStatic = call_static; + + if ( callStatic ) + applyButton->hide(); + + textEdit = new TextEdit( centralWidget(), "textedit" ); + Layout4->insertWidget( 0, textEdit ); + + if ( richtextMode ) { + QPopupMenu *stylesMenu = new QPopupMenu( this ); + menuBar->insertItem( tr( "&Styles" ), stylesMenu ); + + basicToolBar = new QToolBar( tr( "Basics" ), this, DockTop ); + + ToolBarItem *it = new ToolBarItem( this, basicToolBar, tr( "Italic" ), + "i", QPixmap::fromMimeSource( "designer_textitalic.png" ), CTRL+Key_I ); + it->addTo( stylesMenu ); + connect( it, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *b = new ToolBarItem( this, basicToolBar, tr( "Bold" ), + "b", QPixmap::fromMimeSource( "designer_textbold.png" ), CTRL+Key_B ); + b->addTo( stylesMenu ); + connect( b, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *ul = new ToolBarItem( this, basicToolBar, tr( "Underline" ), + "u", QPixmap::fromMimeSource( "designer_textunderline.png" ), CTRL+Key_U ); + ul->addTo( stylesMenu ); + connect( ul, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *tt = new ToolBarItem( this, basicToolBar, tr( "Typewriter" ), + "tt", QPixmap::fromMimeSource( "designer_textteletext.png" ) ); + tt->addTo( stylesMenu ); + connect( tt, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + basicToolBar->addSeparator(); + + QPopupMenu *layoutMenu = new QPopupMenu( this ); + menuBar->insertItem( tr( "&Layout" ), layoutMenu ); + + QAction *brAction = new QAction( this ); + brAction->setIconSet( QPixmap::fromMimeSource( "designer_textlinebreak.png" ) ); + brAction->setText( tr("Break" ) ); + brAction->addTo( basicToolBar ); + brAction->addTo( layoutMenu ); + connect( brAction, SIGNAL( activated() ) , this, SLOT( insertBR() ) ); + + ToolBarItem *p = new ToolBarItem( this, basicToolBar, tr( "Paragraph" ), + "p", QPixmap::fromMimeSource( "designer_textparagraph.png" ) ); + p->addTo( layoutMenu ); + connect( p, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + layoutMenu->insertSeparator(); + basicToolBar->addSeparator(); + + ToolBarItem *al = new ToolBarItem( this, basicToolBar, tr( "Align left" ), + "p align=\"left\"", QPixmap::fromMimeSource( "designer_textleft.png" ) ); + al->addTo( layoutMenu ); + connect( al, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *ac = new ToolBarItem( this, basicToolBar, tr( "Align center" ), + "p align=\"center\"", QPixmap::fromMimeSource( "designer_textcenter.png" ) ); + ac->addTo( layoutMenu ); + connect( ac, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *ar = new ToolBarItem( this, basicToolBar, tr( "Align right" ), + "p align=\"right\"", QPixmap::fromMimeSource( "designer_textright.png" ) ); + ar->addTo( layoutMenu ); + connect( ar, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *block = new ToolBarItem( this, basicToolBar, tr( "Blockquote" ), + "blockquote", QPixmap::fromMimeSource( "designer_textjustify.png" ) ); + block->addTo( layoutMenu ); + connect( block, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + + QPopupMenu *fontMenu = new QPopupMenu( this ); + menuBar->insertItem( tr( "&Font" ), fontMenu ); + + fontToolBar = new QToolBar( "Fonts", this, DockTop ); + + QAction *fontAction = new QAction( this ); + fontAction->setIconSet( QPixmap::fromMimeSource( "designer_textfont.png" ) ); + fontAction->setText( tr("Font" ) ); + fontAction->addTo( fontToolBar ); + fontAction->addTo( fontMenu ); + connect( fontAction, SIGNAL( activated() ) , this, SLOT( showFontDialog() ) ); + + + ToolBarItem *fp1 = new ToolBarItem( this, fontToolBar, tr( "Fontsize +1" ), + "font size=\"+1\"", QPixmap::fromMimeSource( "designer_textlarger.png" ) ); + connect( fp1, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *fm1 = new ToolBarItem( this, fontToolBar, tr( "Fontsize -1" ), + "font size=\"-1\"", QPixmap::fromMimeSource( "designer_textsmaller.png" ) ); + connect( fm1, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *h1 = new ToolBarItem( this, fontToolBar, tr( "Headline 1" ), + "h1", QPixmap::fromMimeSource( "designer_texth1.png" ) ); + connect( h1, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *h2 = new ToolBarItem( this, fontToolBar, tr( "Headline 2" ), + "h2", QPixmap::fromMimeSource( "designer_texth2.png" ) ); + connect( h2, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + ToolBarItem *h3 = new ToolBarItem( this, fontToolBar, tr( "Headline 3" ), + "h3", QPixmap::fromMimeSource( "designer_texth3.png" ) ); + connect( h3, SIGNAL( clicked( const QString& ) ), + this, SLOT( insertTags( const QString& ))); + + QPopupMenu *optionsMenu = new QPopupMenu( this ); + menuBar->insertItem( tr( "O&ptions" ), optionsMenu ); + + optionsToolBar = new QToolBar( "Options", this, DockTop ); + wrapAction = new QAction( this ); + wrapAction->setToggleAction( TRUE ); + wrapAction->setIconSet( QPixmap::fromMimeSource( "designer_wordwrap.png" ) ); + wrapAction->setText( tr( "Word Wrapping" ) ); + wrapAction->addTo( optionsToolBar ); + wrapAction->addTo( optionsMenu ); + connect( wrapAction, SIGNAL( toggled( bool ) ), this, SLOT( changeWrapMode( bool ) ) ); + + oldDoWrap = doWrap; + wrapAction->setOn( doWrap ); + + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + textEdit->document()->setFormatter( new QTextFormatterBreakInWords ); + textEdit->document()->setUseFormatCollection( FALSE ); + textEdit->document()->setPreProcessor( new SyntaxHighlighter_HTML ); + + if ( !callStatic && ::qt_cast(editWidget) ) { + mlined = (QTextEdit*)editWidget; + mlined->setReadOnly( TRUE ); + + const QMetaProperty *wordWrap = mlined->metaObject()->property( + mlined->metaObject()->findProperty( "wordWrap", TRUE ), TRUE ); + oldWrapMode = 0; + oldWrapString = "NoWrap"; + if ( wordWrap ) { + oldWrapMode = mlined->property( "wordWrap" ); + oldWrapString = QString( wordWrap->valueToKey( oldWrapMode.toInt() ) ); + if ( oldWrapString != "NoWrap" ) + doWrap = TRUE; + } + textEdit->setAlignment( mlined->alignment() ); + textEdit->setWordWrap( mlined->wordWrap() ); + textEdit->setWrapColumnOrWidth( mlined->wrapColumnOrWidth() ); + textEdit->setWrapPolicy( mlined->wrapPolicy() ); + textEdit->setText( mlined->text() ); + if ( !mlined->text().isEmpty() ) + textEdit->selectAll(); + } else { + textEdit->setText( text ); + textEdit->selectAll(); + } + } else { + textEdit->setText( text ); + textEdit->selectAll(); + } + textEdit->setFocus(); +} + +int MultiLineEditor::exec() +{ + res = 1; + show(); + qApp->enter_loop(); + return res; +} + +void MultiLineEditor::okClicked() +{ + applyClicked(); + close(); +} + +void MultiLineEditor::applyClicked() +{ + if ( !callStatic ) { + PopulateMultiLineEditCommand *cmd = new PopulateMultiLineEditCommand( tr( "Set the text of '%1'" ).arg( mlined->name() ), + formwindow, mlined, textEdit->text() ); + cmd->execute(); + formwindow->commandHistory()->addCommand( cmd ); + + if ( oldDoWrap != doWrap ) { + QString pn( tr( "Set 'wordWrap' of '%2'" ).arg( mlined->name() ) ); + SetPropertyCommand *propcmd; + if ( doWrap ) + propcmd = new SetPropertyCommand( pn, formwindow, + mlined, MainWindow::self->propertyeditor(), + "wordWrap", WidgetFactory::property( mlined, "wordWrap" ), + QVariant( 1 ), "WidgetWidth", oldWrapString ); + else + propcmd = new SetPropertyCommand( pn, formwindow, + mlined, MainWindow::self->propertyeditor(), + "wordWrap", WidgetFactory::property( mlined, "wordWrap" ), + QVariant( 0 ), "NoWrap", oldWrapString ); + + propcmd->execute(); + formwindow->commandHistory()->addCommand( propcmd, TRUE ); + } + textEdit->setFocus(); + } + else { + staticText = textEdit->text(); + } +} + +void MultiLineEditor::cancelClicked() +{ + res = 0; + close(); +} + +void MultiLineEditor::closeEvent( QCloseEvent *e ) +{ + qApp->exit_loop(); + MultiLineEditorBase::closeEvent( e ); +} + +void MultiLineEditor::insertTags( const QString &tag ) +{ + int pfrom, pto, ifrom, ito; + QString tagend( tag.simplifyWhiteSpace() ); + tagend.remove( tagend.find( ' ', 0 ), tagend.length() ); + if ( textEdit->hasSelectedText() ) { + textEdit->getSelection( &pfrom, &ifrom, &pto, &ito ); + QString buf = textEdit->selectedText(); + buf = QString( "<%1>%3" ).arg( tag ).arg( tagend ).arg( buf ); + textEdit->removeSelectedText(); + textEdit->insertAt( buf, pfrom, ifrom ); + textEdit->setCursorPosition( pto, ito + 2 + tag.length() ); + } + else { + int para, index; + textEdit->getCursorPosition( ¶, &index ); + textEdit->insert( QString( "<%1>" ).arg( tag ).arg( tagend ) ); + index += 2 + tag.length(); + textEdit->setCursorPosition( para, index ); + } +} + +void MultiLineEditor::insertBR() +{ + textEdit->insert( "
    " ); +} + +void MultiLineEditor::showFontDialog() +{ + bool selText = FALSE; + int pfrom, pto, ifrom, ito; + if ( textEdit->hasSelectedText() ) { + textEdit->getSelection( &pfrom, &ifrom, &pto, &ito ); + selText = TRUE; + } + RichTextFontDialog *fd = new RichTextFontDialog( this ); + if ( fd->exec() == QDialog::Accepted ) { + QString size, font; + if ( fd->getSize() != "0" ) + size = "size=\"" + fd->getSize() + "\""; + QString color; + if ( !fd->getColor().isEmpty() && fd->getColor() != "#000000" ) + color = "color=\"" + fd->getColor() + "\""; + if ( fd->getFont() != "default" ) + font = "face=\"" + fd->getFont() + "\""; + QString tag( QString( "font %1 %2 %3" ) + .arg( color ).arg( size ).arg( font ) ); + + if ( selText ) + textEdit->setSelection( pfrom, ifrom, pto, ito ); + insertTags( tag.simplifyWhiteSpace() ); + } + else if ( selText ) + textEdit->setSelection( pfrom, ifrom, pto, ito ); +} + +QString MultiLineEditor::getStaticText() +{ + return staticText.stripWhiteSpace(); +} + +QString MultiLineEditor::getText( QWidget *parent, const QString &text, bool richtextMode, bool *useWrap ) +{ + MultiLineEditor medit( TRUE, richtextMode, parent, 0, 0, text ); + if ( richtextMode ) + medit.setUseWrapping( *useWrap ); + if ( medit.exec() == QDialog::Accepted ) { + *useWrap = medit.useWrapping(); + return medit.getStaticText(); + } + return QString::null; +} + +void MultiLineEditor::changeWrapMode( bool b ) +{ + doWrap = b; + if ( doWrap && !callStatic ) { + if ( oldDoWrap ) + textEdit->setProperty( "wordWrap", oldWrapMode ); + else + textEdit->setWordWrap( QTextEdit::WidgetWidth ); + } else { + textEdit->setWordWrap( QTextEdit::NoWrap ); + } +} + +bool MultiLineEditor::useWrapping() const +{ + return doWrap; +} + +void MultiLineEditor::setUseWrapping( bool b ) +{ + doWrap = b; + wrapAction->setOn( doWrap ); +} diff --git a/tools/designer/designer/multilineeditorimpl.h b/tools/designer/designer/multilineeditorimpl.h new file mode 100644 index 0000000..e147d53 --- /dev/null +++ b/tools/designer/designer/multilineeditorimpl.h @@ -0,0 +1,116 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef MULTILINEEDITORIMPL_H +#define MULTILINEEDITORIMPL_H + +#include +#include +#include +#include "multilineeditor.h" + +class FormWindow; +class QToolBar; +class QTextDocument; + +class TextEdit : public QTextEdit +{ + Q_OBJECT + +public: + TextEdit( QWidget *parent = 0, const char *name = 0 ); + QTextDocument *document() const { return QTextEdit::document(); } + QTextParagraph *paragraph(); + +}; + +class ToolBarItem : public QAction +{ + Q_OBJECT + +public: + ToolBarItem( QWidget *parent, QWidget *toolBar, + const QString &label, const QString &tagstr, + const QIconSet &icon, const QKeySequence &key = 0 ); + ~ToolBarItem(); +signals: + void clicked( const QString &t ); + +protected slots: + void wasActivated(); +private: + QString tag; +}; + + +class MultiLineEditor : public MultiLineEditorBase +{ + Q_OBJECT + +public: + MultiLineEditor( bool call_static, bool richtextMode, QWidget *parent, QWidget *editWidget, + FormWindow *fw, const QString &text = QString::null ); + bool useWrapping() const; + void setUseWrapping( bool ); + static QString getText( QWidget *parent, const QString &text, bool richtextMode, bool *useWrap ); + int exec(); + +protected slots: + void okClicked(); + void applyClicked(); + void cancelClicked(); + void insertTags( const QString& ); + void insertBR(); + void showFontDialog(); + void changeWrapMode( bool ); + + void closeEvent( QCloseEvent *e ); + +private: + QString getStaticText(); + TextEdit *textEdit; + QTextEdit *mlined; + FormWindow *formwindow; + QToolBar *basicToolBar; + QToolBar *fontToolBar; + QToolBar *optionsToolBar; + QAction *wrapAction; + int res; + QString staticText; + bool callStatic; + bool oldDoWrap, doWrap; + QVariant oldWrapMode; + QString oldWrapString; +}; + +#endif diff --git a/tools/designer/designer/newform.ui b/tools/designer/designer/newform.ui new file mode 100644 index 0000000..ecf2eb1 --- /dev/null +++ b/tools/designer/designer/newform.ui @@ -0,0 +1,245 @@ + +NewFormBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + NewFormBase + + + + 0 + 0 + 557 + 436 + + + + New File + + + true + + + <b>New Form</b><p>Select a template for the new form and click the <b>OK</b>-button to create it.</p> + + + + unnamed + + + 11 + + + 6 + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + helpButton + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + true + + + true + + + Create a new form using the selected template. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog without creating a new form. + + + + + + + templateView + + + 120 + + + Adjust + + + false + + + true + + + Displays a list of the available templates. + + + + + labelProject + + + &Insert into: + + + projectCombo + + + + + projectCombo + + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + buttonOk + clicked() + NewFormBase + accept() + + + buttonCancel + clicked() + NewFormBase + reject() + + + projectCombo + activated(const QString&) + NewFormBase + projectChanged(const QString&) + + + templateView + currentChanged(QIconViewItem*) + NewFormBase + itemChanged(QIconViewItem*) + + + templateView + doubleClicked(QIconViewItem*) + NewFormBase + accept() + + + templateView + returnPressed(QIconViewItem*) + NewFormBase + accept() + + + + templateView + helpButton + buttonOk + buttonCancel + + + itemChanged( QIconViewItem * ) + projectChanged( const QString & ) + + + diff --git a/tools/designer/designer/newformimpl.cpp b/tools/designer/designer/newformimpl.cpp new file mode 100644 index 0000000..a4a6ce0 --- /dev/null +++ b/tools/designer/designer/newformimpl.cpp @@ -0,0 +1,418 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "newformimpl.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "project.h" +#include "formwindow.h" +#include "widgetfactory.h" +#include "widgetdatabase.h" +#include "actioneditorimpl.h" +#include "hierarchyview.h" +#include "resource.h" +#include "projectsettingsimpl.h" +#include "sourcefile.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int forms = 0; + +ProjectItem::ProjectItem( QIconView *view, const QString &text ) + : NewItem( view, text ) +{ +} + +void ProjectItem::insert( Project * ) +{ + MainWindow::self->createNewProject( lang ); +} + + + +FormItem::FormItem( QIconView *view, const QString &text ) + : NewItem( view, text ) +{ +} + +void FormItem::insert( Project *pro ) +{ + QString n = "Form" + QString::number( ++forms ); + FormWindow *fw = 0; + FormFile *ff = new FormFile( FormFile::createUnnamedFileName(), TRUE, pro ); + fw = new FormWindow( ff, MainWindow::self, MainWindow::self->qWorkspace(), n ); + fw->setProject( pro ); + MetaDataBase::addEntry( fw ); + if ( fType == Widget ) { + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QWidget" ), + fw, n.latin1() ); + fw->setMainContainer( w ); + } else if ( fType == Dialog ) { + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QDialog" ), fw, n.latin1() ); + fw->setMainContainer( w ); + } else if ( fType == Wizard ) { + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QWizard" ), + fw, n.latin1() ); + fw->setMainContainer( w ); + } else if ( fType == MainWindow ) { + QWidget *w = WidgetFactory::create( WidgetDatabase::idFromClassName( "QMainWindow" ), + fw, n.latin1() ); + fw->setMainContainer( w ); + } + + fw->setCaption( n ); + fw->resize( 600, 480 ); + MainWindow::self->insertFormWindow( fw ); + + TemplateWizardInterface *iface = + MainWindow::self->templateWizardInterface( fw->mainContainer()->className() ); + if ( iface ) { + iface->setup( fw->mainContainer()->className(), fw->mainContainer(), + fw->iFace(), MainWindow::self->designerInterface() ); + iface->release(); + } + + // the wizard might have changed a lot, lets update everything + MainWindow::self->actioneditor()->setFormWindow( fw ); + MainWindow::self->objectHierarchy()->setFormWindow( fw, fw ); + MainWindow::self->objectHierarchy()->formDefinitionView()->refresh(); + MainWindow::self->objectHierarchy()->rebuild(); + fw->killAccels( fw ); + fw->project()->setModified( TRUE ); + fw->setFocus(); + if ( !pro->isDummy() ) { + fw->setSavePixmapInProject( TRUE ); + fw->setSavePixmapInline( FALSE ); + } +} + + + +CustomFormItem::CustomFormItem( QIconView *view, const QString &text ) + : NewItem( view, text ) +{ +} + +static void unifyFormName( FormWindow *fw, QWorkspace *qworkspace ) +{ + QStringList lst; + QWidgetList windows = qworkspace->windowList(); + for ( QWidget *w =windows.first(); w; w = windows.next() ) { + if ( w == fw ) + continue; + lst << w->name(); + } + + if ( lst.findIndex( fw->name() ) == -1 ) + return; + QString origName = fw->name(); + QString n = origName; + int i = 1; + while ( lst.findIndex( n ) != -1 ) { + n = origName + QString::number( i++ ); + } + fw->setName( n ); + fw->setCaption( n ); +} + +void CustomFormItem::insert( Project *pro ) +{ + QString filename = templateFileName(); + if ( !filename.isEmpty() && QFile::exists( filename ) ) { + Resource resource( MainWindow::self ); + FormFile *ff = new FormFile( filename, TRUE, pro ); + if ( !resource.load( ff ) ) { + QMessageBox::information( MainWindow::self, MainWindow::tr("Load Template"), + MainWindow::tr("Couldn't load form description from template '" + + filename + "'" ) ); + delete ff; + return; + } + ff->setFileName( QString::null ); + if ( MainWindow::self->formWindow() ) { + MainWindow::self->formWindow()->setFileName( QString::null ); + unifyFormName( MainWindow::self->formWindow(), MainWindow::self->qWorkspace() ); + if ( !pro->isDummy() ) { + MainWindow::self->formWindow()->setSavePixmapInProject( TRUE ); + MainWindow::self->formWindow()->setSavePixmapInline( FALSE ); + } + } + } +} + + + +SourceFileItem::SourceFileItem( QIconView *view, const QString &text ) + : NewItem( view, text ), visible( TRUE ) +{ +} + +void SourceFileItem::insert( Project *pro ) +{ + SourceFile *f = new SourceFile( SourceFile::createUnnamedFileName( ext ), TRUE, pro ); + MainWindow::self->editSource( f ); +} + +void SourceFileItem::setProject( Project *pro ) +{ + QIconView *iv = iconView(); + bool v = lang == pro->language(); + if ( !iv || v == visible ) + return; + visible = v; + if ( !visible ) + iv->takeItem( this ); + else + iv->insertItem( this ); +} + + + +SourceTemplateItem::SourceTemplateItem( QIconView *view, const QString &text ) + : NewItem( view, text ), visible( TRUE ) +{ +} + +void SourceTemplateItem::insert( Project *pro ) +{ + SourceTemplateInterface *siface = MainWindow::self->sourceTemplateInterface( text() ); + if ( !siface ) + return; + SourceTemplateInterface::Source src = siface->create( text(), MainWindow::self->designerInterface() ); + SourceFile *f = 0; + if ( src.type == SourceTemplateInterface::Source::Invalid ) + return; + if ( src.type == SourceTemplateInterface::Source::FileName ) + f = new SourceFile( src.filename, FALSE, pro ); + else + f = new SourceFile( SourceFile::createUnnamedFileName( src.extension ), TRUE, pro ); + if ( f->isAccepted()) { + f->setText( src.code ); + MainWindow::self->editSource( f ); + f->setModified( TRUE ); + } else { + delete f; + } +} + +void SourceTemplateItem::setProject( Project *pro ) +{ + QIconView *iv = iconView(); + bool v = !pro->isDummy() && lang == pro->language(); + if ( !iv || v == visible ) + return; + visible = v; + if ( !visible ) + iv->takeItem( this ); + else + iv->insertItem( this ); +} + +void NewForm::insertTemplates( QIconView *tView, + const QString &templatePath ) +{ + QStringList::Iterator it; + QStringList languages = MetaDataBase::languages(); + if ( !MainWindow::self->singleProjectMode() ) { + for ( it = languages.begin(); it != languages.end(); ++it ) { + ProjectItem *pi = new ProjectItem( tView, *it + " " + tr( "Project" ) ); + allItems.append( pi ); + pi->setLanguage( *it ); + pi->setPixmap( QPixmap::fromMimeSource( "designer_project.png" ) ); + pi->setDragEnabled( FALSE ); + } + } + QIconViewItem *cur = 0; + FormItem *fi = new FormItem( tView,tr( "Dialog" ) ); + allItems.append( fi ); + fi->setFormType( FormItem::Dialog ); + fi->setPixmap( QPixmap::fromMimeSource( "designer_newform.png" ) ); + fi->setDragEnabled( FALSE ); + cur = fi; + if ( !MainWindow::self->singleProjectMode() ) { + fi = new FormItem( tView,tr( "Wizard" ) ); + allItems.append( fi ); + fi->setFormType( FormItem::Wizard ); + fi->setPixmap( QPixmap::fromMimeSource( "designer_newform.png" ) ); + fi->setDragEnabled( FALSE ); + fi = new FormItem( tView, tr( "Widget" ) ); + allItems.append( fi ); + fi->setFormType( FormItem::Widget ); + fi->setPixmap( QPixmap::fromMimeSource( "designer_newform.png" ) ); + fi->setDragEnabled( FALSE ); + fi = new FormItem( tView, tr( "Main Window" ) ); + allItems.append( fi ); + fi->setFormType( FormItem::MainWindow ); + fi->setPixmap( QPixmap::fromMimeSource( "designer_newform.png" ) ); + fi->setDragEnabled( FALSE ); + + QString templPath = templatePath; + QStringList templRoots; + const char *qtdir = getenv( "QTDIR" ); + if(qtdir) + templRoots << qtdir; + templRoots << qInstallPathData(); + if(qtdir) //try the tools/designer directory last! + templRoots << (QString(qtdir) + "/tools/designer"); + for ( QStringList::Iterator it = templRoots.begin(); it != templRoots.end(); ++it ) { + QString path = (*it) + "/templates"; + if ( QFile::exists( path )) { + templPath = path; + break; + } + } + if ( !templPath.isEmpty() ) { + QDir dir( templPath ); + const QFileInfoList *filist = dir.entryInfoList( QDir::DefaultFilter, QDir::DirsFirst | QDir::Name ); + if ( filist ) { + QFileInfoListIterator it( *filist ); + QFileInfo *fi; + while ( ( fi = it.current() ) != 0 ) { + ++it; + if ( !fi->isFile() || fi->extension() != "ui" ) + continue; + QString name = fi->baseName(); + name = name.replace( '_', ' ' ); + CustomFormItem *ci = new CustomFormItem( tView, name ); + allItems.append( ci ); + ci->setDragEnabled( FALSE ); + ci->setPixmap( QPixmap::fromMimeSource( "designer_newform.png" ) ); + ci->setTemplateFile( fi->absFilePath() ); + } + } + } + } + + for ( it = languages.begin(); it != languages.end(); ++it ) { + LanguageInterface *iface = MetaDataBase::languageInterface( *it ); + if ( iface ) { + QMap extensionMap; + iface->preferedExtensions( extensionMap ); + for ( QMap::Iterator eit = extensionMap.begin(); + eit != extensionMap.end(); ++eit ) { + SourceFileItem * si = new SourceFileItem( tView, *eit ); + allItems.append( si ); + si->setExtension( eit.key() ); + si->setLanguage( *it ); + si->setPixmap( QPixmap::fromMimeSource( "designer_filenew.png" ) ); + si->setDragEnabled( FALSE ); + } + iface->release(); + } + } + + if ( !MainWindow::self->singleProjectMode() ) { + QStringList sourceTemplates = MainWindow::self->sourceTemplates(); + for ( QStringList::Iterator sit = sourceTemplates.begin(); sit != sourceTemplates.end(); ++sit ) { + SourceTemplateInterface *siface = MainWindow::self->sourceTemplateInterface( *sit ); + if ( !siface ) + continue; + SourceTemplateItem * si = new SourceTemplateItem( tView, *sit ); + allItems.append( si ); + si->setTemplate( *sit ); + si->setLanguage( siface->language( *sit ) ); + si->setPixmap( QPixmap::fromMimeSource( "designer_filenew.png" ) ); + si->setDragEnabled( FALSE ); + siface->release(); + } + } + + tView->viewport()->setFocus(); + tView->setCurrentItem( cur ); + + if ( MainWindow::self->singleProjectMode() ) + adjustSize(); +} + +NewForm::NewForm( QIconView *templateView, const QString &templatePath ) +{ + insertTemplates( templateView, templatePath ); + projectChanged( tr( "" ) ); +} + +NewForm::NewForm( QWidget *parent, const QStringList& projects, + const QString& currentProject, const QString &templatePath ) + : NewFormBase( parent, 0, TRUE ) +{ + connect( helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + projectCombo->insertStringList( projects ); + projectCombo->setCurrentText( currentProject ); + + insertTemplates( templateView, templatePath ); + + projectChanged( projectCombo->currentText() ); +} + +void NewForm::accept() +{ + if ( !templateView->currentItem() ) + return; + Project *pro = MainWindow::self->findProject( projectCombo->currentText() ); + if ( !pro ) + return; + MainWindow::self->setCurrentProject( pro ); + NewFormBase::accept(); + ( (NewItem*)templateView->currentItem() )->insert( pro ); +} + +void NewForm::projectChanged( const QString &project ) +{ + Project *pro = MainWindow::self->findProject( project ); + if ( !pro ) + return; + QIconViewItem *i; + for ( i = allItems.first(); i; i = allItems.next() ) + ( (NewItem*)i )->setProject( pro ); + templateView->setCurrentItem( templateView->firstItem() ); + templateView->arrangeItemsInGrid( TRUE ); +} + +void NewForm::itemChanged( QIconViewItem *item ) +{ + labelProject->setEnabled( item->rtti() != NewItem::ProjectType ); + projectCombo->setEnabled( item->rtti() != NewItem::ProjectType ); +} + +QPtrList NewForm::allViewItems() +{ + return allItems; +} diff --git a/tools/designer/designer/newformimpl.h b/tools/designer/designer/newformimpl.h new file mode 100644 index 0000000..b97a4f0 --- /dev/null +++ b/tools/designer/designer/newformimpl.h @@ -0,0 +1,171 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef NEWFORMIMPL_H +#define NEWFORMIMPL_H + +#include "newform.h" +#include + +class Project; + +class NewItem : public QIconViewItem +{ +public: + enum Type { + ProjectType, + Form, + CustomForm, + SourceFileType, + SourceTemplateType + }; + + NewItem( QIconView *view, const QString &text ) + : QIconViewItem( view, text ) {} + virtual void insert( Project *pro ) = 0; + virtual void setProject( Project * ) {} + +}; + +class ProjectItem : public NewItem +{ +public: + ProjectItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)ProjectType; } + + void setLanguage( const QString &l ) { lang = l; } + QString language() const { return lang; } + +private: + QString lang; + +}; + +class FormItem : public NewItem +{ +public: + enum FormType { + Widget, + Dialog, + Wizard, + MainWindow + }; + + FormItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)Form; } + + void setFormType( FormType ft ) { fType = ft; } + FormType formType() const { return fType; } + +private: + FormType fType; + +}; + +class CustomFormItem : public NewItem +{ +public: + CustomFormItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)CustomForm; } + + void setTemplateFile( const QString &tf ) { templFile = tf; } + QString templateFileName() const { return templFile; } + +private: + QString templFile; + +}; + +class SourceFileItem : public NewItem +{ +public: + SourceFileItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)SourceFileType; } + + void setExtension( const QString &e ) { ext = e; } + QString extension() const { return ext; } + void setLanguage( const QString &l ) { lang = l; } + void setProject( Project *pro ); + +private: + QString ext; + QString lang; + bool visible; + +}; + +class SourceTemplateItem : public NewItem +{ +public: + SourceTemplateItem( QIconView *view, const QString &text ); + void insert( Project *pro ); + int rtti() const { return (int)SourceTemplateType; } + + void setTemplate( const QString &t ) { templ = t; } + QString tenplate() const { return templ; } + void setLanguage( const QString &l ) { lang = l; } + void setProject( Project *pro ); + +private: + QString templ; + QString lang; + bool visible; + +}; + +class NewForm : public NewFormBase +{ + Q_OBJECT + +public: + NewForm( QIconView *templateView, const QString &templatePath ); + NewForm( QWidget *parent, const QStringList& projects, + const QString& currentProject, const QString &templatePath ); + void insertTemplates( QIconView*, const QString& ); + void accept(); + QPtrList allViewItems(); + +protected slots: + void projectChanged( const QString &project ); + void itemChanged( QIconViewItem *item ); + +private: + QPtrList allItems; + +}; + +#endif diff --git a/tools/designer/designer/orderindicator.cpp b/tools/designer/designer/orderindicator.cpp new file mode 100644 index 0000000..bfc5ff1 --- /dev/null +++ b/tools/designer/designer/orderindicator.cpp @@ -0,0 +1,119 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include // HP-UX compiler need this here + +#include "orderindicator.h" +#include "formwindow.h" + +#include +#include +#include + +OrderIndicator::OrderIndicator( int i, QWidget* w, FormWindow *fw ) + : QWidget( fw, "order_indicator", WMouseNoMask ), formWindow( fw ) +{ + order = -1; + widget = w; + setBackgroundMode( NoBackground ); + setAutoMask( TRUE ); + setOrder( i, w ); +} + + +OrderIndicator::~OrderIndicator() +{ +} + + +void OrderIndicator::setOrder( int i, QWidget* wid ) +{ + if ( widget != wid ) + return; + if ( !wid->isVisibleTo( formWindow ) ) { + hide(); + return; + } + + if ( order == i ) { + show(); + raise(); + return; + } + order = i; + int w = fontMetrics().width( QString::number( i ) ) + 10; + int h = fontMetrics().lineSpacing() * 3 / 2; + QFont f( font() ); + f.setBold( TRUE ); + setFont( f ); + resize( QMAX( w, h ), h ); + update(); // in case the size didn't change + reposition(); + show(); + raise(); +} + +void OrderIndicator::reposition() +{ + QPoint p =parentWidget()->mapFromGlobal( widget->mapToGlobal( widget->rect().topLeft() ) ); + move( p - QPoint( width()/3, height()/3 ) ); +} + + +void OrderIndicator::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + p.setPen( white ); + p.setBrush( blue ); + p.drawEllipse( rect() ); + p.drawText( rect(), AlignCenter, QString::number( order ) ); +} + + +void OrderIndicator::updateMask() +{ + QBitmap bm( size() ); + bm.fill( color0 ); + { + QPainter p( &bm, this ); + p.setPen( color1 ); + p.setBrush( color1 ); + p.drawEllipse( rect() ); + } + setMask( bm ); +} + +void OrderIndicator::mousePressEvent( QMouseEvent *e ) +{ + QApplication::sendEvent( widget, e ); +} diff --git a/tools/designer/designer/orderindicator.h b/tools/designer/designer/orderindicator.h new file mode 100644 index 0000000..ea2fbc3 --- /dev/null +++ b/tools/designer/designer/orderindicator.h @@ -0,0 +1,64 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef ORDERINDICATOR_H +#define ORDERINDICATOR_H + +#include + +class FormWindow; + +class OrderIndicator : public QWidget +{ + Q_OBJECT + +public: + OrderIndicator( int i, QWidget* w, FormWindow* fw ); + ~OrderIndicator(); + + void setOrder( int i, QWidget* w ); + void reposition(); + +protected: + void paintEvent( QPaintEvent * ); + void mousePressEvent( QMouseEvent *e ); + void updateMask(); + +private: + int order; + QWidget* widget; + FormWindow *formWindow; + +}; + +#endif diff --git a/tools/designer/designer/outputwindow.cpp b/tools/designer/designer/outputwindow.cpp new file mode 100644 index 0000000..bd236a7 --- /dev/null +++ b/tools/designer/designer/outputwindow.cpp @@ -0,0 +1,214 @@ +/********************************************************************** +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "outputwindow.h" +#include "designerappiface.h" +#include "metadatabase.h" +#include "mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include + +static QTextEdit *debugoutput = 0; +bool debugToStderr = FALSE; + +QtMsgHandler OutputWindow::oldMsgHandler = 0; + +OutputWindow::OutputWindow( QWidget *parent ) + : QTabWidget( parent, "output_window" ), debugView( 0 ), errorView( 0 ) +{ + setupDebug(); + setupError(); + iface = new DesignerOutputDockImpl( this ); +} + +OutputWindow::~OutputWindow() +{ + debugoutput = debugView = 0; + errorView = 0; + if ( !debugToStderr ) + qInstallMsgHandler( oldMsgHandler ); + delete iface; +} + +void OutputWindow::shuttingDown() +{ + if ( !debugToStderr ) + qInstallMsgHandler( oldMsgHandler ); +} + +void OutputWindow::setupError() +{ + errorView = new QListView( this, "OutputWindow::errorView" ); + errorView->setSorting( -1 ); + connect( errorView, SIGNAL( currentChanged( QListViewItem* ) ), + this, SLOT( currentErrorChanged( QListViewItem* ) ) ); + connect( errorView, SIGNAL( clicked( QListViewItem* ) ), + this, SLOT( currentErrorChanged( QListViewItem* ) ) ); + + if ( MetaDataBase::languages().count() > 1 ) + addTab( errorView, tr( "Warnings/Errors" ) ); + else + errorView->hide(); + errorView->addColumn( tr( "Type" ) ); + errorView->addColumn( tr( "Message" ) ); + errorView->addColumn( tr( "Line" ) ); + errorView->addColumn( tr( "Location" ) ); + errorView->setResizeMode( QListView::LastColumn ); + errorView->setColumnWidth( 0, errorView->fontMetrics().width( "WARNING1234" ) ); + errorView->setColumnWidth( 1, errorView->fontMetrics().width( "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOP" ) ); + errorView->setColumnWidth( 2, errorView->fontMetrics().width( "9999999" ) ); + errorView->setColumnAlignment( 2, Qt::AlignRight ); + errorView->setAllColumnsShowFocus( TRUE ); +} + +static void debugMessageOutput( QtMsgType type, const char *msg ) +{ + QString s( msg ); + s += "\n"; + + if ( type != QtFatalMsg ) { + if ( debugoutput && debugoutput->isVisible() ) + debugoutput->append( s ); + else if ( OutputWindow::oldMsgHandler ) + (*OutputWindow::oldMsgHandler)( type, msg ); + else + fputs( s.latin1(), stderr ); + } else { + fputs( s.latin1(), stderr ); + abort(); + } + + qApp->flush(); +} + +void OutputWindow::setupDebug() +{ + debugoutput = debugView = new QTextEdit( this, "OutputWindow::debugView" ); + //debugView->setReadOnly( TRUE ); + addTab( debugView, "Debug Output" ); + + if ( !debugToStderr ) + oldMsgHandler = qInstallMsgHandler( debugMessageOutput ); +} + +void OutputWindow::setErrorMessages( const QStringList &errors, const QValueList &lines, + bool clear, const QStringList &locations, + const QObjectList &locationObjects ) +{ + if ( clear ) + errorView->clear(); + QStringList::ConstIterator mit = errors.begin(); + QValueList::ConstIterator lit = lines.begin(); + QStringList::ConstIterator it = locations.begin(); + QObjectList objects = (QObjectList)locationObjects; + QObject *o = objects.first(); + QListViewItem *after = 0; + for ( ; lit != lines.end() && mit != errors.end(); ++lit, ++mit, ++it, o = objects.next() ) + after = new ErrorItem( errorView, after, *mit, *lit, *it, o ); + setCurrentPage( 1 ); +} + +DesignerOutputDock *OutputWindow::iFace() +{ + return iface; +} + +void OutputWindow::appendDebug( const QString &text ) +{ + debugView->append( text + "\n" ); +} + +void OutputWindow::clearErrorMessages() +{ + errorView->clear(); +} + +void OutputWindow::clearDebug() +{ + debugView->clear(); +} + +void OutputWindow::showDebugTab() +{ + showPage( debugView ); +} + +void OutputWindow::currentErrorChanged( QListViewItem *i ) +{ + if ( !i ) + return; + ErrorItem *ei = (ErrorItem*)i; + ei->setRead( TRUE ); + MainWindow::self->showSourceLine( ei->location(), ei->line() - 1, MainWindow::Error ); +} + + + +ErrorItem::ErrorItem( QListView *parent, QListViewItem *after, const QString &message, int line, + const QString &locationString, QObject *locationObject ) + : QListViewItem( parent, after ) +{ + setMultiLinesEnabled( TRUE ); + QString m( message ); + type = m.startsWith( "Warning: " ) ? Warning : Error; + m = m.mid( m.find( ':' ) + 1 ); + setText( 0, type == Error ? "Error" : "Warning" ); + setText( 1, m ); + setText( 2, QString::number( line ) ); + setText( 3, locationString ); + object = locationObject; + read = !after; + if ( !after ) { + parent->setSelected( this, TRUE ); + parent->setCurrentItem( this ); + } +} + +void ErrorItem::paintCell( QPainter *p, const QColorGroup & cg, + int column, int width, int alignment ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Text, type == Error ? Qt::red : Qt::darkYellow ); + if ( !read ) { + QFont f( p->font() ); + f.setBold( TRUE ); + p->setFont( f ); + } + QListViewItem::paintCell( p, g, column, width, alignment ); +} diff --git a/tools/designer/designer/outputwindow.h b/tools/designer/designer/outputwindow.h new file mode 100644 index 0000000..7dc754a --- /dev/null +++ b/tools/designer/designer/outputwindow.h @@ -0,0 +1,105 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef OUTPUTWINDOW_H +#define OUTPUTWINDOW_H + +#include +#include +#include +#include + +struct DesignerOutputDock; +class QTextEdit; +class QListView; + +class ErrorItem : public QListViewItem +{ +public: + enum Type { Error, Warning }; + + ErrorItem( QListView *parent, QListViewItem *after, const QString &message, int line, + const QString &locationString, QObject *locationObject ); + + void paintCell( QPainter *, const QColorGroup & cg, + int column, int width, int alignment ); + + void setRead( bool b ) { read = b; repaint(); } + + QObject *location() const { return object; } + int line() const { return text( 2 ).toInt(); } + +private: + QObject *object; + Type type; + bool read; + +}; + +class OutputWindow : public QTabWidget +{ + Q_OBJECT + +public: + OutputWindow( QWidget *parent ); + ~OutputWindow(); + + void setErrorMessages( const QStringList &errors, const QValueList &lines, + bool clear, const QStringList &locations, + const QObjectList &locationObjects ); + void appendDebug( const QString& ); + void clearErrorMessages(); + void clearDebug(); + void showDebugTab(); + + DesignerOutputDock *iFace(); + + void shuttingDown(); + + static QtMsgHandler oldMsgHandler; + +private slots: + void currentErrorChanged( QListViewItem *i ); + +private: + void setupError(); + void setupDebug(); + + QTextEdit *debugView; + QListView *errorView; + + DesignerOutputDock *iface; + +}; + +#endif diff --git a/tools/designer/designer/paletteeditor.ui b/tools/designer/designer/paletteeditor.ui new file mode 100644 index 0000000..cbb7b92 --- /dev/null +++ b/tools/designer/designer/paletteeditor.ui @@ -0,0 +1,503 @@ + +PaletteEditorBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + PaletteEditorBase + + + + 0 + 0 + 449 + 443 + + + + + 7 + 7 + + + + Edit Palette + + + + unnamed + + + 11 + + + 6 + + + + groupAutoPalette + + + + 5 + 4 + + + + Build Palette + + + AlignAuto + + + + unnamed + + + 11 + + + 6 + + + + labelMainColor + + + + 1 + 1 + + + + + 50 + 0 + + + + 1 + + + 0 + + + 0 + + + &3-D Effects: + + + AlignAuto|AlignVCenter + + + buttonMainColor + + + + + buttonMainColor + + + + 0 + 0 + + + + StrongFocus + + + false + + + Choose a color + + + Choose the effect-color for the generated palette. + + + + + labelMainColor2 + + + + 1 + 1 + + + + + 50 + 0 + + + + 1 + + + 0 + + + 0 + + + Back&ground: + + + AlignAuto|AlignVCenter + + + buttonMainColor2 + + + + + buttonMainColor2 + + + + 0 + 0 + + + + StrongFocus + + + false + + + Choose a color + + + Choose the background color for the generated palette. + + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + btnAdvanced + + + &Tune Palette... + + + + + + + GroupBox126 + + + + 5 + 7 + + + + Preview + + + + unnamed + + + 11 + + + 6 + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + Select &Palette: + + + paletteCombo + + + + + + Active Palette + + + + + Inactive Palette + + + + + Disabled Palette + + + + paletteCombo + + + + + + + previewFrame + + + + 7 + 7 + + + + + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + true + + + + + Horizontal Spacing11 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + + + StyledButton +
    styledbutton.h
    + + 40 + 25 + + 0 + + 5 + 5 + + image0 + clicked() + changed() + color + pixmap + scale +
    + + PreviewFrame +
    previewframe.h
    + + 200 + 200 + + 0 + + 5 + 5 + + image1 +
    +
    + + + 789c9dd2cb8e9b301406e07d9e0225bba89a09601350d505302c5b7559a9eac23e6672b363620c0ca9faeef53949da2e2a55eab123f9e38f2f217e5e475f3e7f8cd6cf8bde0b7f8008f6c2456b3518337ffdf6e1fb62992451e8691ac5cb778be55304d1277b6e71fc12c6ab0d157222e61bd8e4c812196f6216535a13f318624a6764b2495842e99558249014c81e99c6294b69d3376291424ae9806431638cd28628183081f4489e70ce13e4852878c129ad905992f18cd291283295517a466ed32ddfa64847945bb595c80e99a739cf29d54499ab9c528b2c58c10b86344428540148400a26b8a0541241b482d215523299494a0551c9562ae409091c32e0c82351410b942aa4e22a53941e882d36e41ed966d8903b2215f215f99a6143b6442afaafff5aff485658622584a091941256948443d1cabbdd6ebf3f28753c09a9e9cdc1fe703c9e4ea19f689a0430fa4c8908082be093d08d016bbb0bbd5e7ceafade5b30de19d083b3fa9e008cd39b9fafd69495b473af7fcfb15325c1d61eea0afaf005ddf97b5295c658a866338f97591babef7340fa396c6c5ca9e7fe650807d0bf566b4262299986ba335a3b4a2cc84b69ac85b1b673037d8fabf95b023a9c09cc7530e104dd5419ed6e27083fb09a7c752db5a9bd31cde4ec634ed8a39aebbe337618c3f6fdc5dee6d8b0bb0d6b5b8b1fad43d78fe4e14e3f6aace8e29d9d736777fea3c686eee0138c9726d4d00c548df7a315ff750f7ebc5ffc04a0e5308d + + + 789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758 + + + + + buttonMainColor2 + clicked() + PaletteEditorBase + onChoose2ndMainColor() + + + paletteCombo + activated(int) + PaletteEditorBase + paletteSelected(int) + + + btnAdvanced + clicked() + PaletteEditorBase + onTune() + + + buttonOk + clicked() + PaletteEditorBase + accept() + + + buttonCancel + clicked() + PaletteEditorBase + reject() + + + buttonMainColor + changed() + PaletteEditorBase + onChooseMainColor() + + + buttonMainColor + clicked() + PaletteEditorBase + onChooseMainColor() + + + buttonMainColor2 + changed() + PaletteEditorBase + onChoose2ndMainColor() + + init() + destroy() + onTune() + onChoose2ndMainColor() + onChooseMainColor() + paletteSelected(int) + + + buttonOk + buttonCancel + buttonMainColor + buttonMainColor2 + btnAdvanced + paletteCombo + buttonHelp + +
    diff --git a/tools/designer/designer/paletteeditoradvanced.ui b/tools/designer/designer/paletteeditoradvanced.ui new file mode 100644 index 0000000..4c5a6a0 --- /dev/null +++ b/tools/designer/designer/paletteeditoradvanced.ui @@ -0,0 +1,755 @@ + +PaletteEditorAdvancedBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + PaletteEditorAdvancedBase + + + true + + + + 0 + 0 + 327 + 341 + + + + Tune Palette + + + true + + + <b>Edit Palette</b><p>Change the current widget or form's palette.</p><p>Use a generated palette or select colors for each color group and each color role.</p><p>The palette can be tested with different widget layouts in the preview section.</p> + + + + unnamed + + + 11 + + + 6 + + + + Layout14 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + MShape + + + MShadow + + + Select &Palette: + + + paletteCombo + + + + + + Active Palette + + + + + Inactive Palette + + + + + Disabled Palette + + + + paletteCombo + + + + + + + ButtonGroup1 + + + + 5 + 4 + + + + Auto + + + + unnamed + + + 11 + + + 6 + + + + checkBuildInactive + + + Build the &inactive palette from the active palette. + + + true + + + + + checkBuildDisabled + + + Build the &disabled palette from the active palette. + + + true + + + + + + + groupCentral + + + Central color roles + + + + unnamed + + + 11 + + + 6 + + + + + Background + + + + + Foreground + + + + + Button + + + + + Base + + + + + Text + + + + + BrightText + + + + + ButtonText + + + + + Highlight + + + + + HighlightText + + + + + Link + + + + + LinkVisited + + + + comboCentral + + + Choose the central color role + + + <b>Select a color role.</b><p>Available central color roles are: <ul> <li>Background - general background color.</li> <li>Foreground - general foreground color. </li> <li>Base - used as the background color for example, for text entry widgets; it is usually white or another light color. </li> <li>Text - the forground color used with Base. Usually this is the same as the Foreground, in which case it must provide good contrast both with the Background and with the Base. </li> <li>Button - general button background color; useful where buttons need a background different from Background, as in the Macintosh style. </li> <li>ButtonText - a foreground color used with the Button color. </li> <li>Highlight - a color used to indicate a selected or highlighted item. </li> <li>HighlightedText - a text color that contrasts to Highlight. </li> <li>BrightText - a text color that is very different from Foreground and contrasts well with, for example, black. </li> </ul> </p> + + + + + Layout32_2 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal_Spacing1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + labelPixmap + + + + 1 + 1 + + + + Choose Pi&xmap: + + + buttonPixmap + + + + + buttonPixmap + + + + 0 + 0 + + + + TabFocus + + + true + + + Select a pixmap + + + Choose a pixmap file for the selected central color role. + + + + + labelCentral + + + + 1 + 1 + + + + + 0 + 0 + + + + &Select Color: + + + buttonCentral + + + + + buttonCentral + + + + 0 + 0 + + + + TabFocus + + + false + + + Choose a color + + + Choose a color for the selected central color role. + + + + + + + + + groupEffect + + + 3-D shadow effects + + + + unnamed + + + 11 + + + 6 + + + + Layout32_3 + + + + unnamed + + + 0 + + + 6 + + + + checkBuildEffect + + + Build &from button color + + + true + + + Generate shadings + + + Check to let 3D-effect colors be calculated from the button-color. + + + + + + Light + + + + + Midlight + + + + + Mid + + + + + Dark + + + + + Shadow + + + + comboEffect + + + Choose 3D-effect color role + + + <b>Select a color effect role.</b><p>Available effect roles are: <ul> <li>Light - lighter than Button color. </li> <li>Midlight - between Button and Light. </li> <li>Mid - between Button and Dark. </li> <li>Dark - darker than Button. </li> <li>Shadow - a very dark color. </li> </ul> + + + + + + + Layout31_2 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal_Spacing3 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + labelEffect + + + + 1 + 1 + + + + + 0 + 0 + + + + Select Co&lor: + + + buttonEffect + + + + + buttonEffect + + + + 0 + 0 + + + + TabFocus + + + false + + + Choose a color + + + Choose a color for the selected effect color role. + + + + + + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + true + + + + + Horizontal_Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + + + StyledButton +
    styledbutton.h
    + + 40 + 25 + + 0 + + 5 + 5 + + image0 + clicked() + changed() + color + pixmap + scale +
    +
    + + + 789c9dd2cb8e9b301406e07d9e0225bba89a09601350d505302c5b7559a9eac23e6672b363620c0ca9faeef53949da2e2a55eab123f9e38f2f217e5e475f3e7f8cd6cf8bde0b7f8008f6c2456b3518337ffdf6e1fb62992451e8691ac5cb778be55304d1277b6e71fc12c6ab0d157222e61bd8e4c812196f6216535a13f318624a6764b2495842e99558249014c81e99c6294b69d3376291424ae9806431638cd28628183081f4489e70ce13e4852878c129ad905992f18cd291283295517a466ed32ddfa64847945bb595c80e99a739cf29d54499ab9c528b2c58c10b86344428540148400a26b8a0541241b482d215523299494a0551c9562ae409091c32e0c82351410b942aa4e22a53941e882d36e41ed966d8903b2215f215f99a6143b6442afaafff5aff485658622584a091941256948443d1cabbdd6ebf3f28753c09a9e9cdc1fe703c9e4ea19f689a0430fa4c8908082be093d08d016bbb0bbd5e7ceafade5b30de19d083b3fa9e008cd39b9fafd69495b473af7fcfb15325c1d61eea0afaf005ddf97b5295c658a866338f97591babef7340fa396c6c5ca9e7fe650807d0bf566b4262299986ba335a3b4a2cc84b69ac85b1b673037d8fabf95b023a9c09cc7530e104dd5419ed6e27083fb09a7c752db5a9bd31cde4ec634ed8a39aebbe337618c3f6fdc5dee6d8b0bb0d6b5b8b1fad43d78fe4e14e3f6aace8e29d9d736777fea3c686eee0138c9726d4d00c548df7a315ff750f7ebc5ffc04a0e5308d + + + + + buttonOk + clicked() + PaletteEditorAdvancedBase + accept() + + + buttonCancel + clicked() + PaletteEditorAdvancedBase + reject() + + + paletteCombo + activated(int) + PaletteEditorAdvancedBase + paletteSelected(int) + + + comboCentral + activated(int) + PaletteEditorAdvancedBase + onCentral(int) + + + buttonPixmap + clicked() + PaletteEditorAdvancedBase + onChoosePixmap() + + + buttonCentral + clicked() + PaletteEditorAdvancedBase + onChooseCentralColor() + + + buttonEffect + clicked() + PaletteEditorAdvancedBase + onChooseEffectColor() + + + comboEffect + activated(int) + PaletteEditorAdvancedBase + onEffect(int) + + + checkBuildEffect + toggled(bool) + PaletteEditorAdvancedBase + onToggleBuildEffects(bool) + + + buttonHelp + clicked() + PaletteEditorAdvancedBase + showHelp() + + + checkBuildEffect + toggled(bool) + comboEffect + setDisabled(bool) + + + checkBuildEffect + toggled(bool) + buttonEffect + setDisabled(bool) + + + checkBuildInactive + toggled(bool) + PaletteEditorAdvancedBase + onToggleBuildInactive(bool) + + + checkBuildDisabled + toggled(bool) + PaletteEditorAdvancedBase + onToggleBuildDisabled(bool) + + init() + destroy() + onToggleBuildDisabled(bool) + onCentral(int) + onChooseCentralColor() + onChooseEffectColor() + onChoosePixmap() + onEffect(int) + onToggleBuildEffects(bool) + onToggleBuildInactive(bool) + paletteSelected(int) + showHelp() + + + buttonOk + buttonCancel + paletteCombo + checkBuildInactive + checkBuildDisabled + comboCentral + buttonPixmap + buttonCentral + checkBuildEffect + comboEffect + buttonEffect + buttonHelp + +
    diff --git a/tools/designer/designer/paletteeditoradvancedimpl.cpp b/tools/designer/designer/paletteeditoradvancedimpl.cpp new file mode 100644 index 0000000..43d63de --- /dev/null +++ b/tools/designer/designer/paletteeditoradvancedimpl.cpp @@ -0,0 +1,650 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "paletteeditoradvancedimpl.h" +#include "styledbutton.h" +#include "mainwindow.h" +#include "formwindow.h" + +#include +#include +#include +#include +#include +#include +#include + +/*! + Class used by PaletteEditor for bold combobox items +*/ + +class BoldListBoxText : public QListBoxText +{ +public: + BoldListBoxText( QString text, QListBox* lb = 0 ); + +protected: + virtual void paint( QPainter* ); +}; + +BoldListBoxText::BoldListBoxText( QString text, QListBox* lb ) + : QListBoxText( lb ) +{ + setText( text ); +} + +void BoldListBoxText::paint( QPainter* painter ) +{ + QFont f = painter->font(); + f.setBold( TRUE ); + painter->setFont( f ); + + QListBoxText::paint( painter ); +} + +PaletteEditorAdvanced::PaletteEditorAdvanced( FormWindow *fw, QWidget * parent, + const char * name, bool modal, WFlags f ) + : PaletteEditorAdvancedBase( parent, name, modal, f ), formWindow( fw ), selectedPalette(0) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + buttonPixmap->setEditor( StyledButton::PixmapEditor ); + + editPalette = QApplication::palette(); + setPreviewPalette( editPalette ); + + buttonPixmap->setFormWindow( formWindow ); + + // force toggle event + checkBuildEffect->setChecked(FALSE); + checkBuildEffect->setChecked(TRUE); +} + +PaletteEditorAdvanced::~PaletteEditorAdvanced() +{ +} + +void PaletteEditorAdvanced::onToggleBuildInactive( bool v ) +{ + if (selectedPalette == 1) { + groupCentral->setDisabled(v); + groupEffect->setDisabled(v); + } + + if (v) { + buildInactive(); + updateStyledButtons(); + } +} + +void PaletteEditorAdvanced::onToggleBuildDisabled( bool v ) +{ + if (selectedPalette == 2) { + groupCentral->setDisabled(v); + groupEffect->setDisabled(v); + } + + if (v) { + buildDisabled(); + updateStyledButtons(); + } +} + +void PaletteEditorAdvanced::paletteSelected(int p) +{ + selectedPalette = p; + + if(p == 1) { // inactive + groupCentral->setDisabled(checkBuildInactive->isChecked()); + groupEffect->setDisabled(checkBuildInactive->isChecked()); + } + else if (p == 2) { // disabled + groupCentral->setDisabled(checkBuildDisabled->isChecked()); + groupEffect->setDisabled(checkBuildDisabled->isChecked()); + } + else { + groupCentral->setEnabled(TRUE); + groupEffect->setEnabled(TRUE); + } + updateStyledButtons(); +} + +void PaletteEditorAdvanced::onChooseCentralColor() +{ + switch(selectedPalette) { + case 0: + default: + mapToActiveCentralRole( buttonCentral->color() ); + break; + case 1: + mapToInactiveCentralRole( buttonCentral->color() ); + break; + case 2: + mapToDisabledCentralRole( buttonCentral->color() ); + break; + } + updateStyledButtons(); +} + +void PaletteEditorAdvanced::onChooseEffectColor() +{ + switch(selectedPalette) { + case 0: + default: + mapToActiveEffectRole( buttonEffect->color() ); + break; + case 1: + mapToInactiveEffectRole( buttonEffect->color() ); + break; + case 2: + mapToDisabledEffectRole( buttonEffect->color() ); + break; + } + updateStyledButtons(); +} + +void PaletteEditorAdvanced::onChoosePixmap() +{ + if (buttonPixmap->pixmap()) { + switch(selectedPalette) { + case 0: + default: + mapToActivePixmapRole( *buttonPixmap->pixmap() ); + break; + case 1: + mapToInactivePixmapRole( *buttonPixmap->pixmap() ); + break; + case 2: + mapToDisabledPixmapRole( *buttonPixmap->pixmap() ); + break; + } + } + updateStyledButtons(); +} + +void PaletteEditorAdvanced::onToggleBuildEffects( bool on ) +{ + if (!on) return; + buildActiveEffect(); + buildInactiveEffect(); + buildDisabledEffect(); +} + +QColorGroup::ColorRole PaletteEditorAdvanced::centralFromItem( int item ) +{ + switch( item ) { + case 0: + return QColorGroup::Background; + case 1: + return QColorGroup::Foreground; + case 2: + return QColorGroup::Button; + case 3: + return QColorGroup::Base; + case 4: + return QColorGroup::Text; + case 5: + return QColorGroup::BrightText; + case 6: + return QColorGroup::ButtonText; + case 7: + return QColorGroup::Highlight; + case 8: + return QColorGroup::HighlightedText; + case 9: + return QColorGroup::Link; + case 10: + return QColorGroup::LinkVisited; + default: + return QColorGroup::NColorRoles; + } +} + +QColorGroup::ColorRole PaletteEditorAdvanced::effectFromItem( int item ) +{ + switch( item ) { + case 0: + return QColorGroup::Light; + case 1: + return QColorGroup::Midlight; + case 2: + return QColorGroup::Mid; + case 3: + return QColorGroup::Dark; + case 4: + return QColorGroup::Shadow; + default: + return QColorGroup::NColorRoles; + } +} + +void PaletteEditorAdvanced::onCentral( int item ) +{ + QPixmap* p = 0; + QColor c; + + switch(selectedPalette) { + case 0: + default: + c = editPalette.active().color( centralFromItem(item) ); + p = editPalette.active().brush( centralFromItem(item) ).pixmap(); + break; + case 1: + c = editPalette.inactive().color( centralFromItem(item) ); + p = editPalette.inactive().brush( centralFromItem(item) ).pixmap(); + break; + case 2: + c = editPalette.disabled().color( centralFromItem(item) ); + p = editPalette.disabled().brush( centralFromItem(item) ).pixmap(); + break; + } + + buttonCentral->setColor(c); + + if (p) + buttonPixmap->setPixmap( *p ); + else + buttonPixmap->setPixmap( QPixmap() ); +} + +void PaletteEditorAdvanced::onEffect( int item ) +{ + QColor c; + switch(selectedPalette) { + case 0: + default: + c = editPalette.active().color( effectFromItem(item) ); + break; + case 1: + editPalette.inactive().color( effectFromItem(item) ); + break; + case 2: + editPalette.disabled().color( effectFromItem(item) ); + break; + } + buttonEffect->setColor(c); +} + +void PaletteEditorAdvanced::mapToActiveCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.active(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setActive( cg ); + + buildActiveEffect(); + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToActiveEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.active(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setActive( cg ); + + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToActivePixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.active(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + editPalette.setActive( cg ); + + + buildActiveEffect(); + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactiveCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.inactive(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setInactive( cg ); + + buildInactiveEffect(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactiveEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.inactive(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setInactive( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactivePixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.inactive(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + editPalette.setInactive( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.disabled(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setDisabled( cg ); + + buildDisabledEffect(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.disabled(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setDisabled( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledPixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.disabled(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + + editPalette.setDisabled( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::buildActiveEffect() +{ + QColorGroup cg = editPalette.active(); + QColor btn = cg.color( QColorGroup::Button ); + + QPalette temp( btn, btn ); + + for (int i = 0; i<5; i++) + cg.setColor( effectFromItem(i), temp.active().color( effectFromItem(i) ) ); + + editPalette.setActive( cg ); + setPreviewPalette( editPalette ); + + updateStyledButtons(); +} + +void PaletteEditorAdvanced::buildInactive() +{ + editPalette.setInactive( editPalette.active() ); + buildInactiveEffect(); +} + +void PaletteEditorAdvanced::buildInactiveEffect() +{ + QColorGroup cg = editPalette.inactive(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setInactive( cg ); + setPreviewPalette( editPalette ); + updateStyledButtons(); +} + +void PaletteEditorAdvanced::buildDisabled() +{ + QColorGroup cg = editPalette.active(); + cg.setColor( QColorGroup::ButtonText, darkGray ); + cg.setColor( QColorGroup::Foreground, darkGray ); + editPalette.setDisabled( cg ); + + buildDisabledEffect(); +} + +void PaletteEditorAdvanced::buildDisabledEffect() +{ + QColorGroup cg = editPalette.disabled(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setDisabled( cg ); + setPreviewPalette( editPalette ); + updateStyledButtons(); +} + +void PaletteEditorAdvanced::setPreviewPalette( const QPalette& pal ) +{ + QColorGroup cg; + + switch (selectedPalette) { + case 0: + default: + cg = pal.active(); + break; + case 1: + cg = pal.inactive(); + break; + case 2: + cg = pal.disabled(); + break; + } + previewPalette.setActive( cg ); + previewPalette.setInactive( cg ); + previewPalette.setDisabled( cg ); +} + +void PaletteEditorAdvanced::updateStyledButtons() +{ + QColor central, effect; + QPixmap *pm = 0; + switch (selectedPalette) { + case 0: + default: + central = editPalette.active().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.active().color( effectFromItem( comboEffect->currentItem() ) ); + pm = editPalette.active().brush( centralFromItem( comboCentral->currentItem() ) ).pixmap(); + break; + case 1: + central = editPalette.inactive().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.inactive().color( effectFromItem( comboEffect->currentItem() ) ); + pm = editPalette.inactive().brush( centralFromItem( comboCentral->currentItem() ) ).pixmap(); + break; + case 2: + central = editPalette.disabled().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.disabled().color( effectFromItem( comboEffect->currentItem() ) ); + pm = editPalette.disabled().brush( centralFromItem( comboCentral->currentItem() ) ).pixmap(); + break; + } + + buttonCentral->setColor(central); + buttonEffect->setColor(effect); + if ( pm && !pm->isNull() ) + buttonPixmap->setPixmap( *pm ); + else + buttonPixmap->setPixmap(QPixmap()); +} + +void PaletteEditorAdvanced::setPal( const QPalette& pal ) +{ + editPalette = pal; + setPreviewPalette( pal ); + updateStyledButtons(); +} + +QPalette PaletteEditorAdvanced::pal() const +{ + return editPalette; +} + +void PaletteEditorAdvanced::setupBackgroundMode( BackgroundMode mode ) +{ + int initRole = 0; + + switch( mode ) { + case PaletteBackground: + initRole = 0; + break; + case PaletteForeground: + initRole = 1; + break; + case PaletteButton: + initRole = 2; + break; + case PaletteBase: + initRole = 3; + break; + case PaletteText: + initRole = 4; + break; + case PaletteBrightText: + initRole = 5; + break; + case PaletteButtonText: + initRole = 6; + break; + case PaletteHighlight: + initRole = 7; + break; + case PaletteHighlightedText: + initRole = 8; + break; + case PaletteLight: + initRole = 9; + break; + case PaletteMidlight: + initRole = 10; + break; + case PaletteDark: + initRole = 11; + break; + case PaletteMid: + initRole = 12; + break; + case PaletteShadow: + initRole = 13; + break; + default: + initRole = -1; + break; + } + + if ( initRole <= -1 ) return; + + if (initRole > 8 ) { + comboEffect->setCurrentItem( initRole - 9 ); + if ( comboEffect->listBox() ) { + QString text = comboEffect->currentText(); + comboEffect->listBox()->changeItem( new BoldListBoxText( text ), initRole - 9 ); + } + } + else { + comboCentral->setCurrentItem( initRole ); + if ( comboCentral->listBox() ) { + QString text = comboCentral->currentText(); + comboCentral->listBox()->changeItem( new BoldListBoxText( text ), initRole ); + } + } +} + +QPalette PaletteEditorAdvanced::getPalette( bool *ok, const QPalette &init, + BackgroundMode mode, QWidget* parent, + const char* name, FormWindow *fw ) +{ + PaletteEditorAdvanced* dlg = new PaletteEditorAdvanced( fw, parent, name, TRUE ); + dlg->setupBackgroundMode( mode ); + + if ( init != QPalette() ) + dlg->setPal( init ); + int resultCode = dlg->exec(); + + QPalette result = init; + if ( resultCode == QDialog::Accepted ) { + if ( ok ) + *ok = TRUE; + result = dlg->pal(); + } else { + if ( ok ) + *ok = FALSE; + } + delete dlg; + return result; +} diff --git a/tools/designer/designer/paletteeditoradvancedimpl.h b/tools/designer/designer/paletteeditoradvancedimpl.h new file mode 100644 index 0000000..e16e600 --- /dev/null +++ b/tools/designer/designer/paletteeditoradvancedimpl.h @@ -0,0 +1,103 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PALETTEEDITORADVANCEDIMPL_H +#define PALETTEEDITORADVANCEDIMPL_H + +#include "paletteeditoradvanced.h" + +class FormWindow; + +class PaletteEditorAdvanced : public PaletteEditorAdvancedBase +{ + Q_OBJECT +public: + PaletteEditorAdvanced( FormWindow *fw, QWidget * parent=0, const char * name=0, + bool modal=FALSE, WFlags f=0 ); + ~PaletteEditorAdvanced(); + + static QPalette getPalette( bool *ok, const QPalette &pal, BackgroundMode mode = PaletteBackground, + QWidget* parent = 0, const char* name = 0, FormWindow *fw = 0 ); + +protected slots: + void paletteSelected(int); + + void onCentral( int ); + void onEffect( int ); + + void onChooseCentralColor(); + void onChooseEffectColor(); + void onChoosePixmap(); + + void onToggleBuildEffects( bool ); + void onToggleBuildInactive( bool ); + void onToggleBuildDisabled( bool ); + +protected: + void mapToActiveCentralRole( const QColor& ); + void mapToActiveEffectRole( const QColor& ); + void mapToActivePixmapRole( const QPixmap& ); + void mapToInactiveCentralRole( const QColor& ); + void mapToInactiveEffectRole( const QColor& ); + void mapToInactivePixmapRole( const QPixmap& ); + void mapToDisabledCentralRole( const QColor& ); + void mapToDisabledEffectRole( const QColor& ); + void mapToDisabledPixmapRole( const QPixmap& ); + + + void buildPalette(); + void buildActiveEffect(); + void buildInactive(); + void buildInactiveEffect(); + void buildDisabled(); + void buildDisabledEffect(); + +private: + void setPreviewPalette( const QPalette& ); + void updateStyledButtons(); + void setupBackgroundMode( BackgroundMode ); + + QPalette pal() const; + void setPal( const QPalette& ); + + QColorGroup::ColorRole centralFromItem( int ); + QColorGroup::ColorRole effectFromItem( int ); + QPalette editPalette; + QPalette previewPalette; + + FormWindow *formWindow; + + int selectedPalette; +}; + +#endif diff --git a/tools/designer/designer/paletteeditorimpl.cpp b/tools/designer/designer/paletteeditorimpl.cpp new file mode 100644 index 0000000..1a790dd --- /dev/null +++ b/tools/designer/designer/paletteeditorimpl.cpp @@ -0,0 +1,311 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "paletteeditorimpl.h" +#include "paletteeditoradvancedimpl.h" +#include "previewframe.h" +#include "styledbutton.h" +#include "mainwindow.h" +#include "formwindow.h" + +#include +#include +#include +#include + +PaletteEditor::PaletteEditor( FormWindow *fw, QWidget * parent, const char * name, bool modal, WFlags f ) + : PaletteEditorBase( parent, name, modal, f ), formWindow( fw ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + editPalette = QApplication::palette(); + setPreviewPalette( editPalette ); + + buttonMainColor->setColor( editPalette.active().color( QColorGroup::Button ) ); + buttonMainColor2->setColor( editPalette.active().color( QColorGroup::Background ) ); +} + +PaletteEditor::~PaletteEditor() +{ +} + +void PaletteEditor::onTune() +{ + bool ok; + QPalette pal = PaletteEditorAdvanced::getPalette( &ok, editPalette, backgroundMode, this, "tune_palette", formWindow); + if (!ok) return; + + editPalette = pal; + setPreviewPalette( editPalette ); +} + +void PaletteEditor::onChooseMainColor() +{ + buildPalette(); +} + +void PaletteEditor::onChoose2ndMainColor() +{ + buildPalette(); +} + +void PaletteEditor::paletteSelected(int) +{ + setPreviewPalette(editPalette); +} + +QColorGroup::ColorRole PaletteEditor::centralFromItem( int item ) +{ + switch( item ) + { + case 0: + return QColorGroup::Background; + case 1: + return QColorGroup::Foreground; + case 2: + return QColorGroup::Button; + case 3: + return QColorGroup::Base; + case 4: + return QColorGroup::Text; + case 5: + return QColorGroup::BrightText; + case 6: + return QColorGroup::ButtonText; + case 7: + return QColorGroup::Highlight; + case 8: + return QColorGroup::HighlightedText; + default: + return QColorGroup::NColorRoles; + } +} + +QColorGroup::ColorRole PaletteEditor::effectFromItem( int item ) +{ + switch( item ) + { + case 0: + return QColorGroup::Light; + case 1: + return QColorGroup::Midlight; + case 2: + return QColorGroup::Mid; + case 3: + return QColorGroup::Dark; + case 4: + return QColorGroup::Shadow; + default: + return QColorGroup::NColorRoles; + } +} + +void PaletteEditor::buildPalette() +{ + int i; + QColorGroup cg; + QColor btn = buttonMainColor->color(); + QColor back = buttonMainColor2->color(); + QPalette automake( btn, back ); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), automake.active().color( centralFromItem(i) ) ); + + editPalette.setActive( cg ); + buildActiveEffect(); + + cg = editPalette.inactive(); + + QPalette temp( editPalette.active().color( QColorGroup::Button ), + editPalette.active().color( QColorGroup::Background ) ); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), temp.inactive().color( centralFromItem(i) ) ); + + editPalette.setInactive( cg ); + buildInactiveEffect(); + + cg = editPalette.disabled(); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), temp.disabled().color( centralFromItem(i) ) ); + + editPalette.setDisabled( cg ); + buildDisabledEffect(); + + updateStyledButtons(); +} + +void PaletteEditor::buildActiveEffect() +{ + QColorGroup cg = editPalette.active(); + QColor btn = cg.color( QColorGroup::Button ); + + QPalette temp( btn, btn ); + + for (int i = 0; i<5; i++) + cg.setColor( effectFromItem(i), temp.active().color( effectFromItem(i) ) ); + + editPalette.setActive( cg ); + setPreviewPalette( editPalette ); + + updateStyledButtons(); +} + +void PaletteEditor::buildInactive() +{ + editPalette.setInactive( editPalette.active() ); + buildInactiveEffect(); +} + +void PaletteEditor::buildInactiveEffect() +{ + QColorGroup cg = editPalette.inactive(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setInactive( cg ); + setPreviewPalette( editPalette ); + updateStyledButtons(); +} + +void PaletteEditor::buildDisabled() +{ + QColorGroup cg = editPalette.active(); + cg.setColor( QColorGroup::ButtonText, darkGray ); + cg.setColor( QColorGroup::Foreground, darkGray ); + editPalette.setDisabled( cg ); + + buildDisabledEffect(); +} + +void PaletteEditor::buildDisabledEffect() +{ + QColorGroup cg = editPalette.disabled(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setDisabled( cg ); + setPreviewPalette( editPalette ); + updateStyledButtons(); +} + +void PaletteEditor::setPreviewPalette( const QPalette& pal ) +{ + QColorGroup cg; + + switch (paletteCombo->currentItem()) { + case 0: + default: + cg = pal.active(); + break; + case 1: + cg = pal.inactive(); + break; + case 2: + cg = pal.disabled(); + break; + } + previewPalette.setActive( cg ); + previewPalette.setInactive( cg ); + previewPalette.setDisabled( cg ); + + previewFrame->setPreviewPalette(previewPalette); +} + +void PaletteEditor::updateStyledButtons() +{ + buttonMainColor->setColor( editPalette.active().color( QColorGroup::Button )); + buttonMainColor2->setColor( editPalette.active().color( QColorGroup::Background )); +} + +void PaletteEditor::setPal( const QPalette& pal ) +{ + editPalette = pal; + setPreviewPalette( pal ); + updateStyledButtons(); +} + +QPalette PaletteEditor::pal() const +{ + return editPalette; +} + +QPalette PaletteEditor::getPalette( bool *ok, const QPalette &init, BackgroundMode mode, + QWidget* parent, const char* name, FormWindow *fw ) +{ + PaletteEditor* dlg = new PaletteEditor( fw, parent, name, TRUE ); + dlg->setupBackgroundMode( mode ); + + if ( init != QPalette() ) + dlg->setPal( init ); + int resultCode = dlg->exec(); + + QPalette result = init; + if ( resultCode == QDialog::Accepted ) { + if ( ok ) + *ok = TRUE; + result = dlg->pal(); + } else { + if ( ok ) + *ok = FALSE; + } + delete dlg; + return result; +} diff --git a/tools/designer/designer/paletteeditorimpl.h b/tools/designer/designer/paletteeditorimpl.h new file mode 100644 index 0000000..806651e --- /dev/null +++ b/tools/designer/designer/paletteeditorimpl.h @@ -0,0 +1,83 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PALETTEEDITORIMPL_H +#define PALETTEEDITORIMPL_H + +#include "paletteeditor.h" + +class FormWindow; + +class PaletteEditor : public PaletteEditorBase +{ + Q_OBJECT + +public: + PaletteEditor( FormWindow *fw, QWidget * parent=0, const char * name=0, bool modal=FALSE, WFlags f=0 ); + ~PaletteEditor(); + + static QPalette getPalette( bool *ok, const QPalette &pal, BackgroundMode mode = PaletteBackground, + QWidget* parent = 0, const char* name = 0, FormWindow *fw = 0 ); + +protected slots: + void onChooseMainColor(); + void onChoose2ndMainColor(); + void onTune(); + void paletteSelected(int); + +protected: + void buildPalette(); + void buildActiveEffect(); + void buildInactive(); + void buildInactiveEffect(); + void buildDisabled(); + void buildDisabledEffect(); + +private: + void setPreviewPalette( const QPalette& ); + void updateStyledButtons(); + void setupBackgroundMode( BackgroundMode mode ) { backgroundMode = mode; } + + QPalette pal() const; + void setPal( const QPalette& ); + + QColorGroup::ColorRole centralFromItem( int ); + QColorGroup::ColorRole effectFromItem( int ); + QPalette editPalette; + QPalette previewPalette; + + FormWindow *formWindow; + BackgroundMode backgroundMode; +}; + +#endif diff --git a/tools/designer/designer/pixmapchooser.cpp b/tools/designer/designer/pixmapchooser.cpp new file mode 100644 index 0000000..8c8b0a7 --- /dev/null +++ b/tools/designer/designer/pixmapchooser.cpp @@ -0,0 +1,206 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include // HP-UX compiler needs this here + +#include "pixmapchooser.h" +#include "formwindow.h" +#if defined(DESIGNER) && !defined(RESOURCE) +#include "pixmapfunction.h" +#endif +#include "metadatabase.h" +#include "mainwindow.h" +#include "pixmapcollectioneditor.h" +#include "pixmapcollection.h" +#include "project.h" + +#include +#include +#include +#include +#include +#include +#include + +#if defined(DESIGNER) +static ImageIconProvider *imageIconProvider = 0; +#endif + +PixmapView::PixmapView( QWidget *parent ) + : QScrollView( parent ) +{ + viewport()->setBackgroundMode( PaletteBase ); +} + +void PixmapView::setPixmap( const QPixmap &pix ) +{ + pixmap = pix; + resizeContents( pixmap.size().width(), pixmap.size().height() ); + viewport()->repaint( FALSE ); +} + +void PixmapView::drawContents( QPainter *p, int cx, int cy, int cw, int ch ) +{ + p->fillRect( cx, cy, cw, ch, colorGroup().brush( QColorGroup::Base ) ); + p->drawPixmap( 0, 0, pixmap ); +} + +void PixmapView::previewUrl( const QUrl &u ) +{ + if ( u.isLocalFile() ) { + QString path = u.path(); + QPixmap pix( path ); + if ( !pix.isNull() ) + setPixmap( pix ); + } else { + qWarning( "Previewing remote files not supported." ); + } +} + +static void buildImageFormatList( QString &filter, QString &all ) +{ + all = qApp->translate( "qChoosePixmap", "All Pixmaps (" ); + for ( uint i = 0; i < QImageIO::outputFormats().count(); i++ ) { + QString outputFormat = QImageIO::outputFormats().at( i ); + QString outputExtension; + if ( outputFormat != "JPEG" ) + outputExtension = outputFormat.lower(); + else + outputExtension = "jpg;*.jpeg"; + filter += qApp->translate( "qChoosePixmap", "%1-Pixmaps (%2)\n" ). + arg( outputFormat ).arg( "*." + outputExtension); + all += "*." + outputExtension + ";"; + } + filter.prepend( all + qApp->translate( "qChoosePixmap", ")\n" ) ); + filter += qApp->translate( "qChoosePixmap", "All Files (*)" ); + +} +QStringList qChoosePixmaps( QWidget *parent ) +{ + if ( !imageIconProvider && !QFileDialog::iconProvider() ) + QFileDialog::setIconProvider( ( imageIconProvider = new ImageIconProvider ) ); + + QString filter; + QString all; + buildImageFormatList( filter, all ); + + QFileDialog fd( QString::null, filter, parent, 0, TRUE ); + fd.setMode( QFileDialog::ExistingFiles ); + fd.setContentsPreviewEnabled( TRUE ); + PixmapView *pw = new PixmapView( &fd ); + fd.setContentsPreview( pw, pw ); + fd.setViewMode( QFileDialog::List ); + fd.setPreviewMode( QFileDialog::Contents ); + fd.setCaption( qApp->translate( "qChoosePixmap", "Choose Images..." ) ); + if ( fd.exec() == QDialog::Accepted ) + return fd.selectedFiles(); + return QStringList(); +} + +QPixmap qChoosePixmap( QWidget *parent, FormWindow *fw, const QPixmap &old, QString *fn ) +{ +#if defined(DESIGNER) + if ( !fw || fw->savePixmapInline() ) { + if ( !imageIconProvider && !QFileDialog::iconProvider() ) + QFileDialog::setIconProvider( ( imageIconProvider = new ImageIconProvider ) ); + + QString filter; + QString all; + buildImageFormatList( filter, all ); + + QFileDialog fd( QString::null, filter, parent, 0, TRUE ); + fd.setContentsPreviewEnabled( TRUE ); + PixmapView *pw = new PixmapView( &fd ); + fd.setContentsPreview( pw, pw ); + fd.setViewMode( QFileDialog::List ); + fd.setPreviewMode( QFileDialog::Contents ); + fd.setCaption( qApp->translate( "qChoosePixmap", "Choose a Pixmap..." ) ); + if ( fd.exec() == QDialog::Accepted ) { + QPixmap pix( fd.selectedFile() ); + if ( fn ) + *fn = fd.selectedFile(); + MetaDataBase::setPixmapArgument( fw, pix.serialNumber(), fd.selectedFile() ); + return pix; + } + } else if ( fw && fw->savePixmapInProject() ) { + PixmapCollectionEditor dia( parent, 0, TRUE ); + dia.setProject( fw->project() ); + dia.setChooserMode( TRUE ); + dia.setCurrentItem( MetaDataBase::pixmapKey( fw, old.serialNumber() ) ); + if ( dia.exec() == QDialog::Accepted ) { + QPixmap pix( fw->project()->pixmapCollection()->pixmap( dia.viewPixmaps->currentItem()->text() ) ); + MetaDataBase::setPixmapKey( fw, pix.serialNumber(), dia.viewPixmaps->currentItem()->text() ); + return pix; + } + } else { + PixmapFunction dia( parent, 0, TRUE ); + QObject::connect( dia.helpButton, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + dia.labelFunction->setText( fw->pixmapLoaderFunction() + "(" ); + dia.editArguments->setText( MetaDataBase::pixmapArgument( fw, old.serialNumber() ) ); + dia.editArguments->setFocus(); + if ( dia.exec() == QDialog::Accepted ) { + QPixmap pix; + // we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that + pix.convertFromImage( QPixmap::fromMimeSource( "designer_image.png" ).convertToImage() ); + + MetaDataBase::setPixmapArgument( fw, pix.serialNumber(), dia.editArguments->text() ); + return pix; + } + } +#else + Q_UNUSED( parent ); + Q_UNUSED( fw ); + Q_UNUSED( old ); +#endif + return QPixmap(); +} + +ImageIconProvider::ImageIconProvider( QWidget *parent, const char *name ) + : QFileIconProvider( parent, name ), imagepm( QPixmap::fromMimeSource( "designer_image.png" ) ) +{ + fmts = QImage::inputFormats(); +} + +ImageIconProvider::~ImageIconProvider() +{ +} + +const QPixmap * ImageIconProvider::pixmap( const QFileInfo &fi ) +{ + QString ext = fi.extension().upper(); + if ( fmts.contains( ext ) ) { + return &imagepm; + } else { + return QFileIconProvider::pixmap( fi ); + } +} diff --git a/tools/designer/designer/pixmapchooser.h b/tools/designer/designer/pixmapchooser.h new file mode 100644 index 0000000..3ed4ae4 --- /dev/null +++ b/tools/designer/designer/pixmapchooser.h @@ -0,0 +1,79 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PIXMAPCHOOSER_H +#define PIXMAPCHOOSER_H + +#include +#include +#include +#include + +class FormWindow; + +class PixmapView : public QScrollView, + public QFilePreview +{ + Q_OBJECT + +public: + PixmapView( QWidget *parent ); + void setPixmap( const QPixmap &pix ); + void drawContents( QPainter *p, int, int, int, int ); + void previewUrl( const QUrl &u ); + +private: + QPixmap pixmap; + +}; + +class ImageIconProvider : public QFileIconProvider +{ + Q_OBJECT + +public: + ImageIconProvider( QWidget *parent = 0, const char *name = 0 ); + ~ImageIconProvider(); + + const QPixmap *pixmap( const QFileInfo &fi ); + +private: + QStrList fmts; + QPixmap imagepm; + +}; + +QPixmap qChoosePixmap( QWidget *parent, FormWindow *fw = 0, const QPixmap &old = QPixmap(), QString *fn = 0 ); +QStringList qChoosePixmaps( QWidget *parent ); + +#endif diff --git a/tools/designer/designer/pixmapcollection.cpp b/tools/designer/designer/pixmapcollection.cpp new file mode 100644 index 0000000..e70ae00 --- /dev/null +++ b/tools/designer/designer/pixmapcollection.cpp @@ -0,0 +1,187 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "pixmapcollection.h" +#include "project.h" +#include "mainwindow.h" +#include +#include +#include +#include +#include + +PixmapCollection::PixmapCollection( Project *pro ) + : project( pro ) +{ + iface = new DesignerPixmapCollectionImpl( this ); + mimeSourceFactory = new QMimeSourceFactory(); +} + +PixmapCollection::~PixmapCollection() +{ + delete mimeSourceFactory; + delete iface; +} + +bool PixmapCollection::addPixmap( const Pixmap &pix, bool force ) +{ + Pixmap pixmap = pix; + savePixmap( pixmap ); + + if ( !force ) { + for ( QValueList::Iterator it = pixList.begin(); it != pixList.end(); ++it ) { + if ( (*it).name == pixmap.name ) + return FALSE; + } + } + + pixList.append( pixmap ); + mimeSourceFactory->setPixmap( pixmap.name, pixmap.pix ); + project->setModified( TRUE ); + return TRUE; +} + +void PixmapCollection::removePixmap( const QString &name ) +{ + for ( QValueList::Iterator it = pixList.begin(); it != pixList.end(); ++it ) { + if ( (*it).name == name ) { + pixList.remove( it ); + break; + } + } + project->setModified( TRUE ); +} + +QValueList PixmapCollection::pixmaps() const +{ + return pixList; +} + +QString PixmapCollection::unifyName( const QString &n ) +{ + QString name = n; + bool restart = FALSE; + int added = 1; + + for ( QValueList::Iterator it = pixList.begin(); it != pixList.end(); ++it ) { + if ( restart ) + it = pixList.begin(); + restart = FALSE; + if ( name == (*it).name ) { + name = n; + name += "_" + QString::number( added ); + ++added; + restart = TRUE; + } + } + + return name; +} + +void PixmapCollection::setActive( bool b ) +{ + if ( b ) + QMimeSourceFactory::defaultFactory()->addFactory( mimeSourceFactory ); + else + QMimeSourceFactory::defaultFactory()->removeFactory( mimeSourceFactory ); +} + +QPixmap PixmapCollection::pixmap( const QString &name ) +{ + for ( QValueList::Iterator it = pixList.begin(); it != pixList.end(); ++it ) { + if ( (*it).name == name ) + return (*it).pix; + } + return QPixmap(); +} + +void PixmapCollection::savePixmap( Pixmap &pix ) +{ + if ( pix.absname == imageDir() + "/" + pix.name ) + return; // no need to save, it is already there + QString rel = project->makeRelative( pix.absname ); + if ( rel[0] == '/' || ( rel[1] == ':' && rel[2] == '/' ) ) { // only save if file is outside the project + mkdir(); + pix.name = unifyName( QFileInfo( pix.absname ).baseName() ) + ".png"; + pix.absname = imageDir() + "/" + pix.name; + pix.pix.save( pix.absname, "PNG" ); + } else if ( rel.isEmpty() ) { + mkdir(); + pix.name = unifyName( pix.name ); + pix.absname = imageDir() + "/" + pix.name; + pix.pix.save( pix.absname, "PNG" ); + } +} + +QString PixmapCollection::imageDir() const +{ + return QFileInfo( project->fileName() ).dirPath( TRUE ) + "/images"; +} + +void PixmapCollection::mkdir() +{ + QString f = project->fileName(); + QDir d( QFileInfo( f ).dirPath( TRUE ) ); + d.mkdir( "images" ); +} + +void PixmapCollection::load( const QString& filename ) +{ + if ( filename.isEmpty() ) + return; + QString absfile; + if ( filename[0] == '/' ) + absfile = filename; + else + absfile = QFileInfo( project->fileName() ).dirPath( TRUE ) + "/" + filename; + + QPixmap pm( absfile ); + if ( pm.isNull() ) + return; + + Pixmap pix; + pix.name = QFileInfo( absfile ).fileName(); + pix.absname = absfile; + pix.pix = pm; + addPixmap( pix, TRUE ); +} + +DesignerPixmapCollection *PixmapCollection::iFace() +{ + return iface; +} + +bool PixmapCollection::isEmpty() const +{ + return pixList.isEmpty(); +} diff --git a/tools/designer/designer/pixmapcollection.h b/tools/designer/designer/pixmapcollection.h new file mode 100644 index 0000000..0900209 --- /dev/null +++ b/tools/designer/designer/pixmapcollection.h @@ -0,0 +1,87 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PIXMAPCOLLECTION_H +#define PIXMAPCOLLECTION_H + +#include +#include +#include +#include "designerappiface.h" + +class QMimeSourceFactory; +class Project; + +class PixmapCollection +{ +public: + struct Pixmap + { + QPixmap pix; + QString name; + QString absname; + Q_DUMMY_COMPARISON_OPERATOR( Pixmap ) + }; + + PixmapCollection( Project *pro ); + ~PixmapCollection(); + + bool addPixmap( const Pixmap &pix, bool force = TRUE ); + void removePixmap( const QString &name ); + QPixmap pixmap( const QString &name ); + + QValueList pixmaps() const; + bool isEmpty() const; + + void setActive( bool b ); + + void load( const QString& filename ); + + DesignerPixmapCollection *iFace(); + +private: + QString unifyName( const QString &n ); + void savePixmap( Pixmap &pix ); + + QString imageDir() const; + void mkdir(); + +private: + QValueList pixList; + QMimeSourceFactory *mimeSourceFactory; + Project *project; + DesignerPixmapCollectionImpl *iface; + +}; + +#endif diff --git a/tools/designer/designer/pixmapcollectioneditor.ui b/tools/designer/designer/pixmapcollectioneditor.ui new file mode 100644 index 0000000..6ea4282 --- /dev/null +++ b/tools/designer/designer/pixmapcollectioneditor.ui @@ -0,0 +1,225 @@ + +PixmapCollectionEditor +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + PixmapCollectionEditor + + + + 0 + 0 + 455 + 260 + + + + Manage Image Collection + + + + unnamed + + + 11 + + + 6 + + + + viewPixmaps + + + Adjust + + + false + + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + PushButton2 + + + &Add... + + + + + PushButton3 + + + &Delete + + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + true + + + + + buttonCancel + + + &Cancel + + + + + buttonClose + + + C&lose + + + true + + + + + + + + + PushButton2 + clicked() + PixmapCollectionEditor + addPixmap() + + + PushButton3 + clicked() + PixmapCollectionEditor + removePixmap() + + + viewPixmaps + currentChanged(QIconViewItem*) + PixmapCollectionEditor + currentChanged(QIconViewItem*) + + + buttonOk + clicked() + PixmapCollectionEditor + accept() + + + buttonCancel + clicked() + PixmapCollectionEditor + reject() + + + buttonClose + clicked() + PixmapCollectionEditor + accept() + + + + PushButton2 + PushButton3 + viewPixmaps + buttonClose + + + pixmapcollection.h + pixmapchooser.h + project.h + qfileinfo.h + qimage.h + qpixmap.h + pixmapcollectioneditor.ui.h + + + class Project; + + + Project *project; + bool chooser; + + + init() + destroy() + addPixmap() + removePixmap() + updateView() + currentChanged(QIconViewItem * i) + setChooserMode(bool c) + setCurrentItem(const QString & name) + setProject(Project * pro) + scaledPixmap(const QPixmap & p) + + + diff --git a/tools/designer/designer/pixmapcollectioneditor.ui.h b/tools/designer/designer/pixmapcollectioneditor.ui.h new file mode 100644 index 0000000..f68e2a6 --- /dev/null +++ b/tools/designer/designer/pixmapcollectioneditor.ui.h @@ -0,0 +1,156 @@ +/********************************************************************** +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +void PixmapCollectionEditor::init() +{ + project = 0; + setChooserMode( FALSE ); +} + +void PixmapCollectionEditor::destroy() +{ +} + +void PixmapCollectionEditor::addPixmap() +{ + if ( !project ) + return; + + QString f; + QStringList pixmaps = qChoosePixmaps( this ); + if ( pixmaps.isEmpty() ) + return; + + QString lastName; + for ( QStringList::ConstIterator it = pixmaps.begin(); it != pixmaps.end(); ++it ) { + QPixmap pm( *it ); + if ( pm.isNull() ) + continue; + PixmapCollection::Pixmap pixmap; + pixmap.pix = pm; + QFileInfo fi ( *it ); + pixmap.name = fi.fileName(); + pixmap.absname = fi.filePath(); + if ( !project->pixmapCollection()->addPixmap( pixmap, FALSE ) ) + continue; + lastName = pixmap.name; + } + + updateView(); + QIconViewItem *item = viewPixmaps->findItem( lastName ); + if ( item ) { + viewPixmaps->setCurrentItem( item ); + viewPixmaps->ensureItemVisible( item ); + } + +} + +void PixmapCollectionEditor::removePixmap() +{ + if ( !project || !viewPixmaps->currentItem() ) + return; + project->pixmapCollection()->removePixmap( viewPixmaps->currentItem()->text() ); + updateView(); +} + +void PixmapCollectionEditor::updateView() +{ + if ( !project ) + return; + + viewPixmaps->clear(); + + QValueList pixmaps = project->pixmapCollection()->pixmaps(); + for ( QValueList::Iterator it = pixmaps.begin(); it != pixmaps.end(); ++it ) { + // #### might need to scale down the pixmap + QIconViewItem *item = new QIconViewItem( viewPixmaps, (*it).name, scaledPixmap( (*it).pix ) ); + //item->setRenameEnabled( TRUE ); // this will be a bit harder to implement + item->setDragEnabled( FALSE ); + item->setDropEnabled( FALSE ); + } + viewPixmaps->setCurrentItem( viewPixmaps->firstItem() ); + currentChanged( viewPixmaps->firstItem() ); +} + +void PixmapCollectionEditor::currentChanged( QIconViewItem * i ) +{ + buttonOk->setEnabled( !!i ); +} + +void PixmapCollectionEditor::setChooserMode( bool c ) +{ + chooser = c; + if ( chooser ) { + buttonClose->hide(); + buttonOk->show(); + buttonCancel->show(); + buttonOk->setEnabled( FALSE ); + buttonOk->setDefault( TRUE ); + connect( viewPixmaps, SIGNAL( doubleClicked( QIconViewItem * ) ), buttonOk, SIGNAL( clicked() ) ); + connect( viewPixmaps, SIGNAL( returnPressed( QIconViewItem * ) ), buttonOk, SIGNAL( clicked() ) ); + setCaption( tr( "Choose an Image" ) ); + } else { + buttonClose->show(); + buttonOk->hide(); + buttonCancel->hide(); + buttonClose->setDefault( TRUE ); + } + updateView(); +} + +void PixmapCollectionEditor::setCurrentItem( const QString & name ) +{ + QIconViewItem *i = viewPixmaps->findItem( name ); + if ( i ) { + viewPixmaps->setCurrentItem( i ); + currentChanged( i ); + } +} + +void PixmapCollectionEditor::setProject( Project * pro ) +{ + project = pro; + updateView(); +} + +QPixmap PixmapCollectionEditor::scaledPixmap( const QPixmap & p ) +{ + QPixmap pix( p ); + if ( pix.width() < 50 && pix.height() < 50 ) + return pix; + QImage img; + img = pix; + img = img.smoothScale( 50, 50 ); + pix.convertFromImage( img ); + return pix; +} diff --git a/tools/designer/designer/pixmapfunction.ui b/tools/designer/designer/pixmapfunction.ui new file mode 100644 index 0000000..a6cec9f --- /dev/null +++ b/tools/designer/designer/pixmapfunction.ui @@ -0,0 +1,937 @@ + +PixmapFunction +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + QDialog + + name + PixmapFunction + + + geometry + + 0 + 0 + 300 + 108 + + + + caption + Choose Pixmap + + + sizeGripEnabled + true + + + + margin + 11 + + + spacing + 6 + + + QLabel + + name + TextLabel3 + + + text + &Enter arguments for loading the pixmap + + + buddy + editArguments + + + + QFrame + + name + Frame9 + + + frameShadow + Sunken + + + frameShape + StyledPanel + + + lineWidth + 2 + + + layoutMargin + + + layoutSpacing + + + + margin + 2 + + + spacing + 0 + + + QLabel + + name + labelFunction + + + text + QPixmap( + + + palette + + + + 0 + 0 + 0 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 233 + 233 + 233 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + 128 + 128 + 128 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 242 + 242 + 242 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 128 + 128 + 128 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + 0 + 0 + 0 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 242 + 242 + 242 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + + + QLineEdit + + name + editArguments + + + frame + false + + + palette + + + + 0 + 0 + 0 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 233 + 233 + 233 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 170 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 211 + 211 + 211 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + 128 + 128 + 128 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 242 + 242 + 242 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 170 + 0 + + + 255 + 255 + 255 + + + 128 + 128 + 128 + + + 255 + 255 + 255 + + + 211 + 211 + 211 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + 0 + 0 + 0 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 242 + 242 + 242 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 170 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 211 + 211 + 211 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + + + QLabel + + name + TextLabel5 + + + text + ) + + + palette + + + + 0 + 0 + 0 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 233 + 233 + 233 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + 128 + 128 + 128 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 242 + 242 + 242 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 128 + 128 + 128 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + 0 + 0 + 0 + + + 211 + 211 + 211 + + + 255 + 255 + 255 + + + 242 + 242 + 242 + + + 105 + 105 + 105 + + + 140 + 140 + 140 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 128 + + + 255 + 255 + 255 + + + + + + + + + + name + Spacer1 + + + orientation + Vertical + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + QLayoutWidget + + name + Layout3 + + + + margin + 0 + + + spacing + 6 + + + QPushButton + + name + helpButton + + + text + &Help + + + autoDefault + true + + + + + name + Horizontal Spacing2 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + QPushButton + + name + buttonOk + + + text + &OK + + + autoDefault + true + + + default + true + + + + QPushButton + + name + buttonCancel + + + text + &Cancel + + + autoDefault + true + + + + + + + + + buttonOk + clicked() + PixmapFunction + accept() + + + buttonCancel + clicked() + PixmapFunction + reject() + + + diff --git a/tools/designer/designer/popupmenueditor.cpp b/tools/designer/designer/popupmenueditor.cpp new file mode 100644 index 0000000..49eca6b --- /dev/null +++ b/tools/designer/designer/popupmenueditor.cpp @@ -0,0 +1,1469 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "actiondnd.h" +#include "actioneditorimpl.h" +#include "command.h" +#include "formfile.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "metadatabase.h" +#include "pixmapchooser.h" +#include "popupmenueditor.h" +#include "menubareditor.h" + +// Drag Object Declaration ------------------------------------------- + +class PopupMenuEditorItemPtrDrag : public QStoredDrag +{ +public: + PopupMenuEditorItemPtrDrag( PopupMenuEditorItem * item, QWidget * parent = 0, + const char * name = 0 ); + ~PopupMenuEditorItemPtrDrag() {}; + static bool canDecode( QDragMoveEvent * e ); + static bool decode( QDropEvent * e, PopupMenuEditorItem ** i ); +}; + +// Drag Object Implementation --------------------------------------- + +PopupMenuEditorItemPtrDrag::PopupMenuEditorItemPtrDrag( PopupMenuEditorItem * item, + QWidget * parent, const char * name ) + : QStoredDrag( "qt/popupmenueditoritemptr", parent, name ) +{ + QByteArray data( sizeof( Q_LONG ) ); + QDataStream stream( data, IO_WriteOnly ); + stream << ( Q_LONG ) item; + setEncodedData( data ); +} + +bool PopupMenuEditorItemPtrDrag::canDecode( QDragMoveEvent * e ) +{ + return e->provides( "qt/popupmenueditoritemptr" ); +} + +bool PopupMenuEditorItemPtrDrag::decode( QDropEvent * e, PopupMenuEditorItem ** i ) +{ + QByteArray data = e->encodedData( "qt/popupmenueditoritemptr" ); + QDataStream stream( data, IO_ReadOnly ); + + if ( !data.size() ) + return FALSE; + + Q_LONG p = 0; + stream >> p; + *i = ( PopupMenuEditorItem *) p; + + return TRUE; +} + +// PopupMenuEditorItem Implementation ----------------------------------- + +PopupMenuEditorItem::PopupMenuEditorItem( PopupMenuEditor * menu, QObject * parent, const char * name ) + : QObject( parent, name ), + a( 0 ), + s( 0 ), + m( menu ), + separator( FALSE ), + removable( FALSE ) +{ + init(); + a = new QAction( this ); + QObject::connect( a, SIGNAL( destroyed() ), this, SLOT( selfDestruct() ) ); +} + + +PopupMenuEditorItem::PopupMenuEditorItem( QAction * action, PopupMenuEditor * menu, + QObject * parent, const char * name ) + : QObject( parent, name ), + a( action ), + s( 0 ), + m( menu ), + separator( FALSE ), + removable( TRUE ) +{ + init(); + if ( /*a->name() == "qt_separator_action" ||*/ ::qt_cast(a) ) + separator = TRUE; + if ( a && a->children() ) + a->installEventFilter( this ); +} + +PopupMenuEditorItem::PopupMenuEditorItem( PopupMenuEditorItem * item, PopupMenuEditor * menu, + QObject * parent, const char * name ) + : QObject( parent, name ), + a( item->a ), + s( 0 ), + m( menu ), + separator( item->separator ), + removable( item->removable ) +{ + init(); + if ( ::qt_cast(a) ) + a->installEventFilter( this ); +} + +PopupMenuEditorItem::~PopupMenuEditorItem() +{ + +} + +void PopupMenuEditorItem::init() +{ + if ( a ) { + QObject::connect( a, SIGNAL( destroyed() ), this, SLOT( selfDestruct() ) ); + if ( m && !isSeparator() ) { + s = new PopupMenuEditor( m->formWindow(), m ); + QString n = "popupMenu"; + m->formWindow()->unify( s, n, TRUE ); + s->setName( n ); + MetaDataBase::addEntry( s ); + } + } +} + +PopupMenuEditorItem::ItemType PopupMenuEditorItem::type() const +{ + if ( separator ) + return Separator; + else if ( a ) + return Action; + return Unknown; +} + +void PopupMenuEditorItem::setVisible( bool enable ) +{ + if ( a ) + a->setVisible( enable ); +} + +bool PopupMenuEditorItem::isVisible() const +{ + QActionGroup *g = ::qt_cast(a); + if ( g ) + return ( g->isVisible() && g->usesDropDown() ); + else if ( a ) + return a->isVisible(); + return FALSE; +} + +void PopupMenuEditorItem::showMenu( int x, int y ) +{ + if ( ( !separator ) && s ) { + s->move( x, y ); + s->show(); + s->raise(); + } +} + +void PopupMenuEditorItem::hideMenu() +{ + if ( s ) { + s->hideSubMenu(); + s->hide(); + } +} + +void PopupMenuEditorItem::focusOnMenu() +{ + if ( s ) { + s->showSubMenu(); + s->setFocus(); + } +} + +int PopupMenuEditorItem::count() const +{ + if ( s ) { + return s->count(); + } else if ( ::qt_cast(a) ) { + const QObjectList * l = a->children(); + if ( l ) + return l->count(); + } + return 0; +} + +bool PopupMenuEditorItem::eventFilter( QObject * o, QEvent * event ) +{ + if ( ! ::qt_cast( o ) ) + return FALSE; + if ( event->type() == QEvent::ChildInserted ) { + QChildEvent * ce = ( QChildEvent * ) event; + QObject * c = ce->child(); + QAction * action = ::qt_cast( c ); + if ( s->find( action ) != -1 ) // avoid duplicates + return FALSE; + QActionGroup * actionGroup = ::qt_cast( c ); + if ( actionGroup ) + s->insert( actionGroup ); + else if ( action ) + s->insert( action ); + } + return FALSE; +} + +void PopupMenuEditorItem::selfDestruct() +{ + hideMenu(); + int i = m->find( s ); + if ( i != -1 && i < m->count() ) + m->remove( i ); // remove this item + a = 0; // the selfDestruct call was caused by the deletion of the action + delete this; +} + +// PopupMenuEditor Implementation ----------------------------------- + +PopupMenuEditorItem * PopupMenuEditor::draggedItem = 0; +int PopupMenuEditor::clipboardOperation = 0; +PopupMenuEditorItem * PopupMenuEditor::clipboardItem = 0; + +PopupMenuEditor::PopupMenuEditor( FormWindow * fw, QWidget * parent, const char * name ) + : QWidget( 0, name, WStyle_Customize | WStyle_NoBorder | WRepaintNoErase | WResizeNoErase ), + formWnd( fw ), + parentMenu( parent ), + iconWidth( 0 ), + textWidth( 0 ), + accelWidth( 0 ), + arrowWidth( 30 ), + borderSize( 2 ), + currentField( 1 ), + currentIndex( 0 ) +{ + init(); +} + +PopupMenuEditor::PopupMenuEditor( FormWindow * fw, PopupMenuEditor * menu, + QWidget * parent, const char * name ) + : QWidget( 0, name, WStyle_Customize | WStyle_NoBorder | WRepaintNoErase ), + formWnd( fw ), + parentMenu( parent ), + iconWidth( menu->iconWidth ), + textWidth( menu->textWidth ), + accelWidth( menu->accelWidth ), + arrowWidth( menu->arrowWidth ), + borderSize( menu->borderSize ), + currentField( menu->currentField ), + currentIndex( menu->currentIndex ) +{ + init(); + PopupMenuEditorItem * i; + for ( i = menu->itemList.first(); i; i = menu->itemList.next() ) { + PopupMenuEditorItem * n = new PopupMenuEditorItem( i, this ); + itemList.append( n ); + } +} + +PopupMenuEditor::~PopupMenuEditor() +{ + itemList.setAutoDelete( TRUE ); +} + +void PopupMenuEditor::init() +{ + reparent( ( QMainWindow * ) formWnd->mainContainer(), pos() ); + + addItem.action()->setMenuText( tr("new item") ); + addSeparator.action()->setMenuText( tr("new separator") ); + + setAcceptDrops( TRUE ); + setFocusPolicy( StrongFocus ); + + lineEdit = new QLineEdit( this ); + lineEdit->hide(); + lineEdit->setFrameStyle(QFrame::Plain | QFrame::NoFrame); + lineEdit->polish(); + lineEdit->setBackgroundOrigin(ParentOrigin); + lineEdit->setBackgroundMode(PaletteButton); + lineEdit->installEventFilter( this ); + + dropLine = new QWidget( this, 0, Qt::WStyle_NoBorder | WStyle_StaysOnTop ); + dropLine->setBackgroundColor( Qt::red ); + dropLine->hide(); + + hide(); +} + +void PopupMenuEditor::insert( PopupMenuEditorItem * item, int index ) +{ + if ( !item ) + return; + if ( index == -1 ) { + itemList.append( item ); + if ( isVisible() ) + currentIndex = itemList.count() - 1; + } else { + itemList.insert( index, item ); + if ( isVisible() ) + currentIndex = index; + } + item->m = this; + if (item->s) + item->s->parentMenu = this; + resizeToContents(); + if ( isVisible() && parentMenu ) + parentMenu->update(); // draw arrow in parent menu + emit inserted( item->action() ); +} + +void PopupMenuEditor::insert( QAction * action, int index ) +{ + if ( !action ) + return; + insert( new PopupMenuEditorItem( action, this, 0, action->name() ), index ); +} + +void PopupMenuEditor::insert( QActionGroup * actionGroup, int index ) +{ + if ( !actionGroup ) + return; + bool dropdown = actionGroup->usesDropDown(); + PopupMenuEditorItem *i = new PopupMenuEditorItem( (QAction *)actionGroup, this, 0, + QString( actionGroup->name() ) + "Menu" ); + QActionGroup *g = 0; + QObjectList *l = actionGroup->queryList( "QAction", 0, FALSE, FALSE ); + QObjectListIterator it( *l ); + insert( i, index ); + for ( ; it.current(); ++it ) { + g = ::qt_cast(it.current()); + if ( g ) { + if ( dropdown ) + i->s->insert( g ); + else + insert( g ); + } else { + i->s->insert( (QAction*)it.current() ); + } + } + delete l; +} + +int PopupMenuEditor::find( const QAction * action ) +{ + PopupMenuEditorItem * i = itemList.first(); + while ( i ) { + if ( i->action() == action ) + return itemList.at(); + i = itemList.next(); + } + return -1; +} + +int PopupMenuEditor::find( PopupMenuEditor * menu ) +{ + PopupMenuEditorItem * i = itemList.first(); + while ( i ) { + if ( i->subMenu() == menu ) + return itemList.at(); + i = itemList.next(); + } + return -1; +} + +int PopupMenuEditor::count() +{ + return itemList.count(); +} + +PopupMenuEditorItem * PopupMenuEditor::at( int index ) +{ + return itemList.at( index ); +} + +void PopupMenuEditor::exchange( int a, int b ) +{ + PopupMenuEditorItem * ia = itemList.at( a ); + PopupMenuEditorItem * ib = itemList.at( b ); + if ( !ia || !ib || + ia == &addItem || ia == &addSeparator || + ib == &addItem || ib == &addSeparator ) + return; // do nothing + itemList.replace( b, ia ); + itemList.replace( a, ib ); +} + +void PopupMenuEditor::cut( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + clipboardOperation = Cut; + clipboardItem = itemList.at( idx ); + + if ( clipboardItem == &addItem || clipboardItem == &addSeparator ) { + clipboardOperation = None; + clipboardItem = 0; + return; // do nothing + } + + RemoveActionFromPopupCommand * cmd = + new RemoveActionFromPopupCommand( "Cut Item", formWnd, this, idx ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); +} + +void PopupMenuEditor::copy( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + clipboardOperation = Copy; + clipboardItem = itemList.at( idx ); + + if ( clipboardItem == &addItem || clipboardItem == &addSeparator ) { + clipboardOperation = None; + clipboardItem = 0; + } +} + +void PopupMenuEditor::paste( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + if ( clipboardItem && clipboardOperation ) { + PopupMenuEditorItem * n = new PopupMenuEditorItem( clipboardItem, this ); + AddActionToPopupCommand * cmd = + new AddActionToPopupCommand( "Paste Item", formWnd, this, n, idx ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } +} + +void PopupMenuEditor::insertedActions( QPtrList & list ) +{ + QAction * a = 0; + PopupMenuEditorItem * i = itemList.first(); + + while ( i ) { + a = i->action(); + if ( a ) + list.append( a ); + i = itemList.next(); + } +} + +void PopupMenuEditor::show() +{ + resizeToContents(); + QWidget::show(); +} + +void PopupMenuEditor::choosePixmap( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + PopupMenuEditorItem * i = 0; + QAction * a = 0; + + if ( idx < (int)itemList.count() ) { + i = itemList.at( idx ); + a = i->action(); + } else { + createItem(); + } + + hide(); // qChoosePixmap hides the menu + QIconSet icons( qChoosePixmap( 0, formWnd, 0, 0 ) ); + SetActionIconsCommand * cmd = + new SetActionIconsCommand( "Set icon", formWnd, a, this, icons ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + show(); + setFocus(); +} + +void PopupMenuEditor::showLineEdit( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + + PopupMenuEditorItem * i = 0; + + if ( idx >= (int)itemList.count() ) + i = &addItem; + else + i = itemList.at( idx ); + + // open edit currentField for item name + lineEdit->setText( i->action()->menuText() ); + lineEdit->selectAll(); + lineEdit->setGeometry( borderSize + iconWidth, borderSize + itemPos( i ), + textWidth, itemHeight( i ) ); + lineEdit->show(); + lineEdit->setFocus(); +} + +void PopupMenuEditor::setAccelerator( int key, Qt::ButtonState state, int index ) +{ + // FIXME: make this a command + + int idx = ( index == -1 ? currentIndex : index ); + + if ( key == Qt::Key_Shift || + key == Qt::Key_Control || + key == Qt::Key_Alt || + key == Qt::Key_Meta || + key == Qt::Key_unknown ) + return; // ignore these keys when they are pressed + + PopupMenuEditorItem * i = 0; + + if ( idx >= (int)itemList.count() ) + i = createItem(); + else + i = itemList.at( idx ); + + int shift = ( state & Qt::ShiftButton ? Qt::SHIFT : 0 ); + int ctrl = ( state & Qt::ControlButton ? Qt::CTRL : 0 ); + int alt = ( state & Qt::AltButton ? Qt::ALT : 0 ); + int meta = ( state & Qt::MetaButton ? Qt::META : 0 ); + + QAction * a = i->action(); + QKeySequence ks = a->accel(); + int keys[4] = { ks[0], ks[1], ks[2], ks[3] }; + int n = 0; + while ( n < 4 && ks[n++] ); + n--; + if ( n < 4 ) + keys[n] = key | shift | ctrl | alt | meta; + a->setAccel( QKeySequence( keys[0], keys[1], keys[2], keys[3] ) ); + MetaDataBase::setPropertyChanged( a, "accel", TRUE ); + resizeToContents(); +} + +void PopupMenuEditor::resizeToContents() +{ + QSize s = contentsSize(); + dropLine->resize( s.width(), 2 ); + s.rwidth() += borderSize * 2; + s.rheight() += borderSize * 2; + resize( s ); +} + +void PopupMenuEditor::showSubMenu() +{ + if ( currentIndex < (int)itemList.count() ) { + itemList.at( currentIndex )->showMenu( pos().x() + width() - borderSize * 3, + pos().y() + itemPos( at( currentIndex ) ) + + borderSize * 2 ); + setFocus(); // Keep focus in this widget + } +} + +void PopupMenuEditor::hideSubMenu() +{ + if ( currentIndex < (int)itemList.count() ) + itemList.at( currentIndex )->hideMenu(); +} + +void PopupMenuEditor::focusOnSubMenu() +{ + if ( currentIndex < (int)itemList.count() ) + itemList.at( currentIndex )->focusOnMenu(); +} + +// This function has no undo. It is only here to remove an item when its action was +// removed from the action editor. +// Use removeItem to put the command on the command stack. +void PopupMenuEditor::remove( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + PopupMenuEditorItem * i = itemList.at( idx ); + if ( i && i->isRemovable() ) { + itemList.remove( idx ); + int n = itemList.count() + 1; + if ( currentIndex >= n ) + currentIndex = itemList.count() + 1; + emit removed( i->action() ); + resizeToContents(); + } +} + +PopupMenuEditorItem * PopupMenuEditor::createItem( QAction * a ) +{ + ActionEditor * ae = (ActionEditor *) formWindow()->mainWindow()->child( 0, "ActionEditor" ); + if ( !a ) + a = ae->newActionEx(); + PopupMenuEditorItem * i = new PopupMenuEditorItem( a, this ); + QString n = QString( a->name() ) + "Item"; + formWindow()->unify( i, n, FALSE ); + i->setName( n ); + AddActionToPopupCommand * cmd = + new AddActionToPopupCommand( "Add Item", formWnd, this, i ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + return i; +} + +void PopupMenuEditor::removeItem( int index ) +{ + int idx = ( index == -1 ? currentIndex : index ); + if ( idx < (int)itemList.count() ) { + RemoveActionFromPopupCommand * cmd = new RemoveActionFromPopupCommand( "Remove Item", + formWnd, + this, + idx ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + if ( itemList.count() == 0 && parentMenu ) + parentMenu->update(); + resizeToContents(); + } +} + +PopupMenuEditorItem * PopupMenuEditor::currentItem() +{ + int count = itemList.count(); + if ( currentIndex < count ) + return itemList.at( currentIndex ); + else if ( currentIndex == count ) + return &addItem; + return &addSeparator; +} + +PopupMenuEditorItem * PopupMenuEditor::itemAt( int y ) +{ + PopupMenuEditorItem * i = itemList.first(); + int iy = 0; + + while ( i ) { + iy += itemHeight( i ); + if ( iy > y ) + return i; + i = itemList.next(); + } + iy += itemHeight( &addItem ); + if ( iy > y ) + return &addItem; + return &addSeparator; +} + +void PopupMenuEditor::setFocusAt( const QPoint & pos ) +{ + hideSubMenu(); + lineEdit->hide(); + + currentIndex = 0; + int iy = 0; + PopupMenuEditorItem * i = itemList.first(); + + while ( i ) { + iy += itemHeight( i ); + if ( iy > pos.y() ) + break; + i = itemList.next(); + currentIndex++; + } + + iy += itemHeight( &addItem ); + if ( iy <= pos.y() ) + currentIndex++; + + if ( currentIndex < (int)itemList.count() ) { + if ( pos.x() < iconWidth ) + currentField = 0; + else if ( pos.x() < iconWidth + textWidth ) + currentField = 1; + else + currentField = 2; + } else { + currentField = 1; + } + + showSubMenu(); +} + +bool PopupMenuEditor::eventFilter( QObject * o, QEvent * e ) +{ + if ( o == lineEdit && e->type() == QEvent::FocusOut ) { + leaveEditMode( 0 ); + update(); + } + return QWidget::eventFilter( o, e ); +} + +void PopupMenuEditor::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + p.save(); + QRegion reg( rect() ); + QRegion mid( borderSize, borderSize, + rect().width() - borderSize * 2, rect().height() - borderSize * 2 ); + reg -= mid; + p.setClipRegion( reg ); + style().drawPrimitive( QStyle::PE_PanelPopup, &p, rect(), colorGroup() ); + p.restore(); + drawItems( &p ); +} + +void PopupMenuEditor::mousePressEvent( QMouseEvent * e ) +{ + mousePressPos = e->pos(); + setFocusAt( mousePressPos ); + e->accept(); + update(); +} + +void PopupMenuEditor::mouseDoubleClickEvent( QMouseEvent * ) +{ + setFocusAt( mousePressPos ); + if ( currentItem() == &addSeparator ) { + PopupMenuEditorItem * i = createItem( new QSeparatorAction( 0 ) ); + i->setSeparator( TRUE ); + return; + } + if ( currentField == 0 ) { + choosePixmap(); + resizeToContents(); + } else if ( currentField == 1 ) { + showLineEdit(); + } +} + +void PopupMenuEditor::mouseMoveEvent( QMouseEvent * e ) +{ + if ( e->state() & Qt::LeftButton ) { + if ( ( e->pos() - mousePressPos ).manhattanLength() > 3 ) { + draggedItem = itemAt( mousePressPos.y() ); + if ( draggedItem == &addItem ) { + draggedItem = createItem(); + RenameActionCommand cmd( "Rename Item", formWnd, draggedItem->action(), + this, "Unnamed" ); + cmd.execute(); + // FIXME: start rename after drop + } else if ( draggedItem == &addSeparator ) { + draggedItem = createItem( new QSeparatorAction( 0 ) ); + draggedItem->setSeparator( TRUE ); + } + + PopupMenuEditorItemPtrDrag * d = + new PopupMenuEditorItemPtrDrag( draggedItem, this ); + + hideSubMenu(); + + draggedItem->setVisible( FALSE ); + resizeToContents(); + + // If the item is dropped in the same list, + // we will have two instances of the same pointer + // in the list. We use node instead. + int idx = itemList.find( draggedItem ); + QLNode * node = itemList.currentNode(); + + d->dragCopy(); // dragevents and stuff happens + + if ( draggedItem ) { // item was not dropped + draggedItem->setVisible( TRUE ); + draggedItem = 0; + if ( hasFocus() ) { + hideSubMenu(); + resizeToContents(); + showSubMenu(); + } + } else { // item was dropped + itemList.takeNode( node )->setVisible( TRUE ); + if ( currentIndex > 0 && currentIndex > idx ) + --currentIndex; + // the drop might happen in another menu, so we'll resize + // and show the submenu there + } + } + } +} + +void PopupMenuEditor::dragEnterEvent( QDragEnterEvent * e ) +{ + if ( e->provides( "qt/popupmenueditoritemptr" ) || + e->provides( "application/x-designer-actions" ) || + e->provides( "application/x-designer-actiongroup" ) ) { + e->accept(); + dropLine->show(); + } +} + +void PopupMenuEditor::dragLeaveEvent( QDragLeaveEvent * ) +{ + dropLine->hide(); +} + +void PopupMenuEditor::dragMoveEvent( QDragMoveEvent * e ) +{ + QPoint pos = e->pos(); + dropLine->move( borderSize, snapToItem( pos.y() ) ); + + if ( currentItem() != itemAt( pos.y() ) ) { + hideSubMenu(); + setFocusAt( pos ); + showSubMenu(); + } +} + +void PopupMenuEditor::dropEvent( QDropEvent * e ) +{ + if ( !( e->provides( "qt/popupmenueditoritemptr" ) || + e->provides( "application/x-designer-actions" ) || + e->provides( "application/x-designer-actiongroup" ) ) ) + return; + + // Hide the sub menu of the current item, but do it later + if ( currentIndex < (int)itemList.count() ) { + PopupMenuEditor *s = itemList.at( currentIndex )->s; + QTimer::singleShot( 0, s, SLOT( hide() ) ); + } + + draggedItem = 0; + PopupMenuEditorItem * i = 0; + + if ( e->provides( "qt/popupmenueditoritemptr" ) ) { + PopupMenuEditorItemPtrDrag::decode( e, &i ); + } else { + if ( e->provides( "application/x-designer-actiongroup" ) ) { + QActionGroup * g = ::qt_cast(ActionDrag::action()); + if ( g->usesDropDown() ) { + i = new PopupMenuEditorItem( g, this ); + QString n = QString( g->name() ) + "Item"; + formWindow()->unify( i, n, FALSE ); + i->setName( n ); + QObjectList *l = g->queryList( "QAction", 0, FALSE, FALSE ); + QObjectListIterator it( *l ); + for ( ; it.current(); ++it ) { + g = ::qt_cast(it.current()); + if ( g ) + i->s->insert( g ); + else + i->s->insert( (QAction*)it.current() ); + } + delete l; + } else { + dropInPlace( g, e->pos().y() ); + } + } else if ( e->provides( "application/x-designer-actions" ) ) { + QAction *a = ::qt_cast(ActionDrag::action()); + i = new PopupMenuEditorItem( a, this ); + } + } + + if ( i ) { + dropInPlace( i, e->pos().y() ); + QTimer::singleShot( 0, this, SLOT( resizeToContents() ) ); + } + + QTimer::singleShot( 0, this, SLOT( showSubMenu() ) ); + QTimer::singleShot( 0, this, SLOT( setFocus() ) ); + dropLine->hide(); + e->accept(); +} + +void PopupMenuEditor::keyPressEvent( QKeyEvent * e ) +{ + if ( lineEdit->isHidden() ) { // In navigation mode + + switch ( e->key() ) { + + case Qt::Key_Delete: + hideSubMenu(); + removeItem(); + showSubMenu(); + break; + + case Qt::Key_Backspace: + clearCurrentField(); + break; + + case Qt::Key_Up: + navigateUp( e->state() & Qt::ControlButton ); + break; + + case Qt::Key_Down: + navigateDown( e->state() & Qt::ControlButton ); + break; + + case Qt::Key_Left: + navigateLeft(); + break; + + case Qt::Key_Right: + navigateRight(); + break; + + case Qt::Key_PageUp: + currentIndex = 0; + break; + + case Qt::Key_PageDown: + currentIndex = itemList.count(); + break; + + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_F2: + enterEditMode( e ); + // move on + case Qt::Key_Alt: + case Qt::Key_Shift: + case Qt::Key_Control: + // do nothing + return; + + case Qt::Key_Escape: + currentField = 0; + navigateLeft(); + break; + + case Qt::Key_C: + if ( e->state() & Qt::ControlButton && + currentIndex < (int)itemList.count() ) { + copy( currentIndex ); + break; + } + + case Qt::Key_X: + if ( e->state() & Qt::ControlButton && + currentIndex < (int)itemList.count() ) { + hideSubMenu(); + cut( currentIndex ); + showSubMenu(); + break; + } + + case Qt::Key_V: + if ( e->state() & Qt::ControlButton ) { + hideSubMenu(); + paste( currentIndex < (int)itemList.count() ? currentIndex + 1: itemList.count() ); + showSubMenu(); + break; + } + + default: + if ( currentItem()->isSeparator() ) + return; + if ( currentField == 1 ) { + showLineEdit(); + QApplication::sendEvent( lineEdit, e ); + e->accept(); + return; + } else if ( currentField == 2 ) { + setAccelerator( e->key(), e->state() ); + showSubMenu(); + } + break; + + } + + } else { // In edit mode + switch ( e->key() ) { + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + leaveEditMode( e ); + e->accept(); + return; + } + } + update(); +} + +void PopupMenuEditor::focusInEvent( QFocusEvent * ) +{ + showSubMenu(); + update(); + parentMenu->update(); +} + +void PopupMenuEditor::focusOutEvent( QFocusEvent * ) +{ + QWidget * fw = qApp->focusWidget(); + if ( !fw || ( !::qt_cast(fw) && fw != lineEdit ) ) { + hideSubMenu(); + if ( fw && ::qt_cast(fw) ) + return; + QWidget * w = this; + while ( w && w != fw && ::qt_cast(w) ) { // hide all popups + w->hide(); + w = ((PopupMenuEditor *)w)->parentEditor(); + } + } +} + +void PopupMenuEditor::drawItem( QPainter * p, PopupMenuEditorItem * i, + const QRect & r, int f ) const +{ + int x = r.x(); + int y = r.y(); + int h = r.height(); + + p->fillRect( r, colorGroup().brush( QColorGroup::Background ) ); + + if ( i->isSeparator() ) { + style().drawPrimitive( QStyle::PE_Separator, p, + QRect( r.x(), r.y() + 2, r.width(), 1 ), + colorGroup(), QStyle::Style_Sunken | f ); + return; + } + + const QAction * a = i->action(); + if ( a->isToggleAction() && a->isOn() ) { + style().drawPrimitive( QStyle::PE_CheckMark, p, + QRect( x , y, iconWidth, h ), + colorGroup(), f ); + } else { + QPixmap icon = a->iconSet().pixmap( QIconSet::Automatic, QIconSet::Normal ); + p->drawPixmap( x + ( iconWidth - icon.width() ) / 2, + y + ( h - icon.height() ) / 2, + icon ); + } + x += iconWidth; + p->drawText( x, y, textWidth, h, + QPainter::AlignLeft | + QPainter::AlignVCenter | + Qt::ShowPrefix | + Qt::SingleLine, + a->menuText() ); + + x += textWidth + borderSize * 3; + p->drawText( x, y, accelWidth, h, + QPainter::AlignLeft | QPainter::AlignVCenter, + a->accel() ); + if ( i->count() ) // Item has submenu + style().drawPrimitive( QStyle::PE_ArrowRight, p, + QRect( r.width() - arrowWidth, r.y(), arrowWidth, r.height() ), + colorGroup(), f ); +} + +void PopupMenuEditor::drawWinFocusRect( QPainter * p, const QRect & r ) const +{ + if ( currentIndex < (int)itemList.count() && + ((PopupMenuEditor*)this)->itemList.at( currentIndex )->isSeparator() ) { + p->drawWinFocusRect( borderSize, r.y(), width() - borderSize * 2, r.height() ); + return; + } + int y = r.y(); + int h = r.height(); + if ( currentField == 0 ) + p->drawWinFocusRect( borderSize + 1, y, iconWidth - 2, h ); + else if ( currentField == 1 ) + p->drawWinFocusRect( borderSize + iconWidth, y, textWidth, h ); + else if ( currentField == 2 ) + p->drawWinFocusRect( borderSize + iconWidth + textWidth + + borderSize * 3, y, accelWidth, h ); +} + +void PopupMenuEditor::drawItems( QPainter * p ) +{ + int flags = 0; + int idx = 0; + + QColorGroup enabled = colorGroup(); + QColorGroup disabled = palette().disabled(); + QRect focus; + QRect rect( borderSize, borderSize, width() - borderSize * 2, 0 ); + + PopupMenuEditorItem * i = itemList.first(); + while ( i ) { + if ( i->isVisible() ) { + rect.setHeight( itemHeight( i ) ); + if ( idx == currentIndex ) + focus = rect; + if ( i->action()->isEnabled() ) { + flags = QStyle::Style_Enabled; + p->setPen( enabled.buttonText() ); + } else { + flags = QStyle::Style_Default; + p->setPen( disabled.buttonText() ); + } + drawItem( p, i, rect, flags ); + rect.moveBy( 0, rect.height() ); + } + i = itemList.next(); + idx++; + } + + // Draw the "add item" and "add separator" items + p->setPen( darkBlue ); + rect.setHeight( itemHeight( &addItem ) ); + if ( idx == currentIndex ) + focus = rect; + drawItem( p, &addItem, rect, QStyle::Style_Default ); + rect.moveBy( 0, rect.height() ); + idx++; + rect.setHeight( itemHeight( &addSeparator ) ); + if ( idx == currentIndex ) + focus = rect; + drawItem( p, &addSeparator, rect, QStyle::Style_Default ); + idx++; + + if ( hasFocus() && !draggedItem ) + drawWinFocusRect( p, focus ); +} + +QSize PopupMenuEditor::contentsSize() +{ + QRect textRect = fontMetrics().boundingRect( addSeparator.action()->menuText() ); + textWidth = textRect.width(); + accelWidth = textRect.height(); // default size + iconWidth = textRect.height(); + + int w = 0; + int h = itemHeight( &addItem ) + itemHeight( &addSeparator ); + PopupMenuEditorItem * i = itemList.first(); + QAction * a = 0; + while ( i ) { + if ( i->isVisible() ) { + if ( !i->isSeparator() ) { + a = i->action(); + w = a->iconSet().pixmap( QIconSet::Automatic, QIconSet::Normal ).rect().width() + + borderSize; // padding + iconWidth = QMAX( iconWidth, w ); + w = fontMetrics().boundingRect( a->menuText() ).width(); + textWidth = QMAX( textWidth, w ); + w = fontMetrics().boundingRect( a->accel() ).width() + 2; // added padding? + accelWidth = QMAX( accelWidth, w ); + } + h += itemHeight( i ); + } + i = itemList.next(); + } + + int width = iconWidth + textWidth + borderSize * 3 + accelWidth + arrowWidth; + return QSize( width, h ); +} + +int PopupMenuEditor::itemHeight( const PopupMenuEditorItem * item ) const +{ + if ( !item || ( item && !item->isVisible() ) ) + return 0; + if ( item->isSeparator() ) + return 4; // FIXME: hardcoded ( get from styles )r + int padding = + borderSize * 6; + QAction * a = item->action(); + int h = a->iconSet().pixmap( QIconSet::Automatic, QIconSet::Normal ).rect().height(); + h = QMAX( h, fontMetrics().boundingRect( a->menuText() ).height() + padding ); + h = QMAX( h, fontMetrics().boundingRect( a->accel() ).height() + padding ); + return h; +} + +int PopupMenuEditor::itemPos( const PopupMenuEditorItem * item ) const +{ + PopupMenuEditor * that = ( PopupMenuEditor * ) this; + int y = 0; + PopupMenuEditorItem * i = that->itemList.first(); + while ( i ) { + if ( i == item ) + return y; + y += itemHeight( i ); + i = that->itemList.next(); + } + return y; +} + +int PopupMenuEditor::snapToItem( int y ) +{ + int iy = 0; + int dy = 0; + + PopupMenuEditorItem * i = itemList.first(); + + while ( i ) { + dy = itemHeight( i ); + if ( iy + dy / 2 > y ) + return iy; + iy += dy; + i = itemList.next(); + } + + return iy; +} + +void PopupMenuEditor::dropInPlace( PopupMenuEditorItem * i, int y ) +{ + int iy = 0; + int dy = 0; + int idx = 0; + + PopupMenuEditorItem * n = itemList.first(); + + while ( n ) { + dy = itemHeight( n ); + if ( iy + dy / 2 > y ) + break; + iy += dy; + idx++; + n = itemList.next(); + } + int same = itemList.findRef( i ); + AddActionToPopupCommand * cmd = new AddActionToPopupCommand( "Drop Item", formWnd, this, i, idx ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + currentIndex = ( same >= 0 && same < idx ) ? idx - 1 : idx; + currentField = 1; +} + +void PopupMenuEditor::dropInPlace( QActionGroup * g, int y ) +{ + if (!g->children()) + return; + QObjectList l = *g->children(); + for ( int i = 0; i < (int)l.count(); ++i ) { + QAction *a = ::qt_cast(l.at(i)); + QActionGroup *g = ::qt_cast(l.at(i)); + if ( g ) + dropInPlace( g, y ); + else if ( a ) + dropInPlace( new PopupMenuEditorItem( a, this ), y ); + } +} + +void PopupMenuEditor::safeDec() +{ + do { + currentIndex--; + } while ( currentIndex > 0 && !currentItem()->isVisible() ); + if ( currentIndex == 0 && + !currentItem()->isVisible() && + parentMenu ) { + parentMenu->setFocus(); + } +} + +void PopupMenuEditor::safeInc() +{ + int max = itemList.count() + 1; + if ( currentIndex < max ) { + do { + currentIndex++; + } while ( currentIndex < max && !currentItem()->isVisible() ); // skip invisible items + } +} + +void PopupMenuEditor::clearCurrentField() +{ + if ( currentIndex >= (int)itemList.count() ) + return; // currentIndex is addItem or addSeparator + PopupMenuEditorItem * i = currentItem(); + hideSubMenu(); + if ( i->isSeparator() ) + return; + if ( currentField == 0 ) { + QIconSet icons( 0 ); + SetActionIconsCommand * cmd = new SetActionIconsCommand( "Remove icon", + formWnd, + i->action(), + this, + icons ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } else if ( currentField == 2 ) { + i->action()->setAccel( 0 ); + } + resizeToContents(); + showSubMenu(); + return; +} + +void PopupMenuEditor::navigateUp( bool ctrl ) +{ + if ( currentIndex > 0 ) { + hideSubMenu(); + if ( ctrl ) { + ExchangeActionInPopupCommand * cmd = + new ExchangeActionInPopupCommand( "Move Item Up", + formWnd, + this, + currentIndex, + currentIndex - 1 ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + safeDec(); + } else { + safeDec(); + } + showSubMenu(); + } else if ( parentMenu ) { + parentMenu->setFocus(); + parentMenu->update(); + } +} + +void PopupMenuEditor::navigateDown( bool ctrl ) +{ + hideSubMenu(); + if ( ctrl ) { + if ( currentIndex < ( (int)itemList.count() - 1 ) ) { // safe index + ExchangeActionInPopupCommand * cmd = + new ExchangeActionInPopupCommand( "Move Item Down", + formWnd, + this, + currentIndex, + currentIndex + 1 ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + safeInc(); + } + } else { // ! Ctrl + safeInc(); + } + if ( currentIndex >= (int)itemList.count() ) + currentField = 1; + showSubMenu(); +} + +void PopupMenuEditor::navigateLeft() +{ + if ( currentItem()->isSeparator() || + currentIndex >= (int)itemList.count() || + currentField == 0 ) { + if ( parentMenu ) { + hideSubMenu(); + parentMenu->setFocus(); + } else if ( !currentItem()->isSeparator() ) { + currentField = 2; + } + } else { + currentField--; + } +} + +void PopupMenuEditor::navigateRight() +{ + if ( !currentItem()->isSeparator() && + currentIndex < (int)itemList.count() ) { + if ( currentField == 2 ) { + focusOnSubMenu(); + } else { + currentField++; + currentField %= 3; + } + } +} + +void PopupMenuEditor::enterEditMode( QKeyEvent * e ) +{ + PopupMenuEditorItem * i = currentItem(); + + if ( i == &addSeparator ) { + i = createItem( new QSeparatorAction( 0 ) ); + } else if ( i->isSeparator() ) { + return; + } else if ( currentField == 0 ) { + choosePixmap(); + } else if ( currentField == 1 ) { + showLineEdit(); + return; + } else {// currentField == 2 + setAccelerator( e->key(), e->state() ); + } + showSubMenu(); + return; +} + +void PopupMenuEditor::leaveEditMode( QKeyEvent * e ) +{ + setFocus(); + lineEdit->hide(); + + PopupMenuEditorItem * i = 0; + if ( e && e->key() == Qt::Key_Escape ) { + update(); + return; + } + + if ( currentIndex >= (int)itemList.count() ) { + // new item was created + QAction * a = formWnd->mainWindow()->actioneditor()->newActionEx(); + QString actionText = lineEdit->text(); + actionText.replace("&&", "&"); + QString menuText = lineEdit->text(); + a->setText( actionText ); + a->setMenuText( menuText ); + i = createItem( a ); + QString n = constructName( i ); + formWindow()->unify( a, n, TRUE ); + a->setName( n ); + MetaDataBase::addEntry( a ); + MetaDataBase::setPropertyChanged( a, "menuText", TRUE ); + ActionEditor *ae = (ActionEditor*)formWindow()->mainWindow()->child( 0, "ActionEditor" ); + if ( ae ) + ae->updateActionName( a ); + } else { + i = itemList.at( currentIndex ); + RenameActionCommand * cmd = new RenameActionCommand( "Rename Item", + formWnd, + i->action(), + this, + lineEdit->text() ); + formWnd->commandHistory()->addCommand( cmd ); + cmd->execute(); + } + resizeToContents(); + + if ( !i ) + return; + + if ( i->isSeparator() ) + hideSubMenu(); + else + showSubMenu(); +} + +QString PopupMenuEditor::constructName( PopupMenuEditorItem *item ) +{ + QString s; + QString name = item->action()->menuText(); + QWidget *e = parentEditor(); + PopupMenuEditor *p = ::qt_cast(e); + if ( p ) { + int idx = p->find( item->m ); + PopupMenuEditorItem * i = ( idx > -1 ? p->at( idx ) : 0 ); + s = ( i ? QString( i->action()->name() ).remove( "Action" ) : QString( "" ) ); + } else { + MenuBarEditor *b = ::qt_cast(e); + if ( b ) { + int idx = b->findItem( item->m ); + MenuBarEditorItem * i = ( idx > -1 ? b->item( idx ) : 0 ); + s = ( i ? i->menuText().lower() : QString( "" ) ); + } + } + // replace illegal characters + + return ( RenameMenuCommand::makeLegal( s ) + + RenameMenuCommand::makeLegal( name ) + "Action" ); +} diff --git a/tools/designer/designer/popupmenueditor.h b/tools/designer/designer/popupmenueditor.h new file mode 100644 index 0000000..1bfda4b --- /dev/null +++ b/tools/designer/designer/popupmenueditor.h @@ -0,0 +1,242 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef POPUPMENUEDITOR_H +#define POPUPMENUEDITOR_H + +#include +#include +#include + +class PopupMenuEditor; +class QMenuItem; + +class PopupMenuEditorItem : public QObject +{ + Q_OBJECT + + friend class PopupMenuEditor; + + PopupMenuEditorItem( PopupMenuEditor * menu = 0, QObject * parent = 0, const char * name = 0 ); + +public: + enum ItemType { + Unknown = -1, + Separator = 0, + Action = 1 + }; + + PopupMenuEditorItem( QAction * action, PopupMenuEditor * menu, + QObject * parent = 0, const char * name = 0 ); + PopupMenuEditorItem( PopupMenuEditorItem * item, PopupMenuEditor * menu, + QObject * parent = 0, const char * name = 0 ); + ~PopupMenuEditorItem(); + + void init(); + + ItemType type() const; + QAction * action() const { return a; } + + void setVisible( bool enable ); + bool isVisible() const; + + void setSeparator( bool enable ) { separator = enable; } + bool isSeparator() const { return separator; } + + void setRemovable( bool enable ) { removable = enable; } + bool isRemovable() const { return removable; } + + void showMenu( int x, int y ); + void hideMenu(); + void focusOnMenu(); + PopupMenuEditor * subMenu() const { return s; } + + int count() const; + + bool eventFilter( QObject *, QEvent * event ); + +public slots: + void selfDestruct(); + +protected: + +private: + QAction * a; + PopupMenuEditor * s; + PopupMenuEditor * m; + uint separator : 1; + uint removable : 1; +}; + +class FormWindow; +class MainWindow; +class QLineEdit; + +#include + +class PopupMenuEditor : public QWidget +{ + Q_OBJECT + + friend class PopupMenuEditorItem; + friend class MenuBarEditor; + friend class Resource; + +public: + PopupMenuEditor( FormWindow * fw, QWidget * parent = 0, const char * name = 0 ); + PopupMenuEditor( FormWindow * fw, PopupMenuEditor * menu, QWidget * parent, const char * name = 0 ); + ~PopupMenuEditor(); + + void init(); + + void insert( PopupMenuEditorItem * item, int index = -1 ); + void insert( QAction * action, int index = -1 ); + void insert( QActionGroup * actionGroup, int index = -1 ); + int find( const QAction * action ); + int find( PopupMenuEditor * menu ); + int count(); + PopupMenuEditorItem * at( int index ); + PopupMenuEditorItem * at( QPoint pos ) { return itemAt( pos.y() ); } + void exchange( int a, int b ); + + void cut( int index ); + void copy( int index ); + void paste( int index ); + + void insertedActions( QPtrList & list ); + + void show(); + void choosePixmap( int index = -1 ); + void showLineEdit( int index = -1); + void setAccelerator( int key, Qt::ButtonState state, int index = -1 ); + + FormWindow * formWindow() { return formWnd; } + bool isCreatingAccelerator() { return ( currentField == 2 ); } + + QPtrList * items() { return &itemList; } + + QWidget * parentEditor() { return parentMenu; } + +signals: + void inserted( QAction * ); + void removed( QAction * ); + +public slots: + + void cut() { cut( currentIndex ); } + void copy() { copy( currentIndex ); } + void paste() { paste( currentIndex ); } + + void remove( int index ); + void remove( QAction * a ) { remove( find( a ) ); } + + void resizeToContents(); + void showSubMenu(); + void hideSubMenu(); + void focusOnSubMenu(); + +protected: + PopupMenuEditorItem * createItem( QAction * a = 0 ); + void removeItem( int index = -1 ); + PopupMenuEditorItem * currentItem(); + PopupMenuEditorItem * itemAt( int y ); + void setFocusAt( const QPoint & pos ); + + bool eventFilter( QObject * o, QEvent * e ); + void paintEvent( QPaintEvent * e ); + void mousePressEvent( QMouseEvent * e ); + void mouseDoubleClickEvent( QMouseEvent * e ); + void mouseMoveEvent( QMouseEvent * e ); + void dragEnterEvent( QDragEnterEvent * e ); + void dragLeaveEvent( QDragLeaveEvent * e ); + void dragMoveEvent( QDragMoveEvent * e ); + void dropEvent( QDropEvent * e ); + void keyPressEvent( QKeyEvent * e ); + void focusInEvent( QFocusEvent * e ); + void focusOutEvent( QFocusEvent * e ); + + void drawItems( QPainter * p ); + void drawItem( QPainter * p, PopupMenuEditorItem * i, const QRect & r, int f ) const; + void drawWinFocusRect( QPainter * p, const QRect & r ) const; + + QSize contentsSize(); + int itemHeight( const PopupMenuEditorItem * item ) const; + int itemPos( const PopupMenuEditorItem * item ) const; + + int snapToItem( int y ); + void dropInPlace( PopupMenuEditorItem * i, int y ); + void dropInPlace( QActionGroup * g, int y ); + + void safeDec(); + void safeInc(); + + void clearCurrentField(); + void navigateUp( bool ctrl ); + void navigateDown( bool ctrl ); + void navigateLeft(); + void navigateRight(); + void enterEditMode( QKeyEvent * e ); + void leaveEditMode( QKeyEvent * e ); + + QString constructName( PopupMenuEditorItem *item ); + +private: + FormWindow * formWnd; + QLineEdit * lineEdit; + QWidget * dropLine; + QPtrList itemList; + PopupMenuEditorItem addItem; + PopupMenuEditorItem addSeparator; + QWidget * parentMenu; + + int iconWidth; + int textWidth; + int accelWidth; + int arrowWidth; + int borderSize; + + int currentField; + int currentIndex; + QPoint mousePressPos; + static PopupMenuEditorItem * draggedItem; + + enum ClipboardOperation { + None = 0, + Cut = 1, + Copy = 2 + }; + static int clipboardOperation; + static PopupMenuEditorItem * clipboardItem; +}; + +#endif //POPUPMENUEDITOR_H diff --git a/tools/designer/designer/preferences.ui b/tools/designer/designer/preferences.ui new file mode 100644 index 0000000..c2990ac --- /dev/null +++ b/tools/designer/designer/preferences.ui @@ -0,0 +1,670 @@ + +Preferences +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + Preferences + + + + 0 + 0 + 482 + 480 + + + + Preferences + + + true + + + <b>Preferences</b><p>Change the preferences of Qt Designer. There is always one tab with general preferences. There may be additional tabs, depending on which plugins are installed.</p> + + + + unnamed + + + 11 + + + 6 + + + + tabWidget + + + + pageGeneral + + + General + + + + unnamed + + + + groupBox4 + + + File Saving + + + + unnamed + + + + checkBoxAutoSave + + + Enable Auto Sa&ve + + + Alt+V + + + true + + + + + layout3 + + + + unnamed + + + + textLabelAutoSave + + + Auto Save &Interval: + + + timeEditAutoSave + + + + + timeEditAutoSave + + + + + + + + + + + + buttonGroup2 + + + Plu&gin Paths + + + + unnamed + + + + textEditPluginPaths + + + + + + + Spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + A splash screen is displayed when starting Qt Designer if this option is checked. + + + + + GroupBox5 + + + Ge&neral + + + + unnamed + + + 11 + + + 6 + + + + checkBoxWorkspace + + + Restore Last &Workspace on Startup + + + Alt+W + + + true + + + Restore last workspace + + + The current workspace settings will be restored the next time you start Qt Designer if this option is checked. + + + + + checkBoxSplash + + + Show &Splash Screen on Startup + + + true + + + Show Splashscreen + + + A splash screen is displayed when starting Qt Designer if this option is checked. + + + + + checkBoxStartDialog + + + Show Start &Dialog + + + true + + + + + checkAutoEdit + + + Disable Data&base Auto-Edit in Preview + + + Alt+B + + + true + + + + + checkBoxTextLabels + + + Show Toolbutton Lab&els + + + Alt+E + + + Text Labels + + + Text labels will be usin in the toolbars if this is checked. + + + + + + + groupBoxGrid + + + G&rid + + + true + + + + + + + unnamed + + + 11 + + + 6 + + + + checkBoxSnapGrid + + + Sn&ap to Grid + + + Alt+A + + + true + + + Snap to the grid + + + <b>Customize the grid-settings for all forms.</b><p>When <b>Snap to Grid</b> is checked, the widgets snap to the grid using the the X/Y resolution.</p> + + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + spinGridX + + + 50 + + + 5 + + + 10 + + + Grid resolution + + + <b>Customize the grid-settings for all forms.</b><p>When <b>Show Grid</b> is checked, a grid is shown on all forms using the X/Y resolution.</p> + + + + + spinGridY + + + 50 + + + 5 + + + 10 + + + Grid resolution + + + <b>Customize the grid-settings for all forms.</b><p>When <b>Show Grid</b> is checked, a grid is shown on all forms using the X/Y resolution.</p> + + + + + Label1 + + + Grid-&X: + + + spinGridX + + + + + Label1_2 + + + Grid-&Y: + + + spinGridY + + + + + + + + + ButtonGroup1 + + + Backgro&und + + + + unnamed + + + 11 + + + 6 + + + + buttonColor + + + false + + + + 0 + 0 + 0 + 0 + + + + TabFocus + + + false + + + Choose a color + + + Select a color in the color dialog. + + + + + radioColor + + + NoFocus + + + Co&lor + + + Use a background color + + + Use a background color. + + + + + radioPixmap + + + &Pixmap + + + true + + + Use a background pixmap + + + Use a background pixmap. + + + + + buttonPixmap + + + + 0 + 0 + 0 + 0 + + + + TabFocus + + + false + + + Select a pixmap + + + Choose a pixmap file. + + + + + + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + helpButton + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + false + + + Close the dialog and discard any changes. + + + + + + + + + StyledButton +
    styledbutton.h
    + + 40 + 25 + + 0 + + 5 + 5 + 0 + 0 + + image0 + clicked() + changed() + color + pixmap + scale +
    +
    + + + 789c9dd2cb8e9b301406e07d9e0225bba89a09601350d505302c5b7559a9eac23e6672b363620c0ca9faeef53949da2e2a55eab123f9e38f2f217e5e475f3e7f8cd6cf8bde0b7f8008f6c2456b3518337ffdf6e1fb62992451e8691ac5cb778be55304d1277b6e71fc12c6ab0d157222e61bd8e4c812196f6216535a13f318624a6764b2495842e99558249014c81e99c6294b69d3376291424ae9806431638cd28628183081f4489e70ce13e4852878c129ad905992f18cd291283295517a466ed32ddfa64847945bb595c80e99a739cf29d54499ab9c528b2c58c10b86344428540148400a26b8a0541241b482d215523299494a0551c9562ae409091c32e0c82351410b942aa4e22a53941e882d36e41ed966d8903b2215f215f99a6143b6442afaafff5aff485658622584a091941256948443d1cabbdd6ebf3f28753c09a9e9cdc1fe703c9e4ea19f689a0430fa4c8908082be093d08d016bbb0bbd5e7ceafade5b30de19d083b3fa9e008cd39b9fafd69495b473af7fcfb15325c1d61eea0afaf005ddf97b5295c658a866338f97591babef7340fa396c6c5ca9e7fe650807d0bf566b4262299986ba335a3b4a2cc84b69ac85b1b673037d8fabf95b023a9c09cc7530e104dd5419ed6e27083fb09a7c752db5a9bd31cde4ec634ed8a39aebbe337618c3f6fdc5dee6d8b0bb0d6b5b8b1fad43d78fe4e14e3f6aace8e29d9d736777fea3c686eee0138c9726d4d00c548df7a315ff750f7ebc5ffc04a0e5308d + + + + + buttonOk + clicked() + Preferences + accept() + + + buttonCancel + clicked() + Preferences + reject() + + + radioColor + toggled(bool) + buttonColor + setEnabled(bool) + + + radioPixmap + toggled(bool) + buttonPixmap + setEnabled(bool) + + + + buttonOk + buttonCancel + tabWidget + radioColor + radioPixmap + buttonColor + buttonPixmap + checkBoxSnapGrid + spinGridX + spinGridY + checkBoxWorkspace + checkBoxSplash + checkBoxStartDialog + checkAutoEdit + checkBoxTextLabels + helpButton + + + init() + destroy() + + + + styledbutton.h + styledbutton.h + +
    diff --git a/tools/designer/designer/previewframe.cpp b/tools/designer/designer/previewframe.cpp new file mode 100644 index 0000000..4cecc8d --- /dev/null +++ b/tools/designer/designer/previewframe.cpp @@ -0,0 +1,64 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include + +#include "previewframe.h" + +PreviewFrame::PreviewFrame( QWidget *parent, const char *name ) + : QVBox( parent, name ) +{ + setMinimumSize(200, 200); + setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + setLineWidth(1); + + PreviewWorkspace * w = new PreviewWorkspace( this ); + w->setEraseColor(colorGroup().dark()); + previewWidget = new PreviewWidget( w ); + previewWidget->move( 10, 10 ); +} + +void PreviewFrame::setPreviewPalette(QPalette pal) +{ + previewWidget->setPalette(pal); +} + +void PreviewWorkspace::paintEvent( QPaintEvent* ) +{ + QPainter p ( this ); + p.setPen( QPen( white ) ); + p.drawText ( 0, height() / 2, width(), height(), AlignHCenter, + "The moose in the noose\nate the goose who was loose." ); +} + diff --git a/tools/designer/designer/previewframe.h b/tools/designer/designer/previewframe.h new file mode 100644 index 0000000..a01fdcf --- /dev/null +++ b/tools/designer/designer/previewframe.h @@ -0,0 +1,66 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PREVIEWFRAME_H +#define PREVIEWFRAME_H + +#include +#include + +#include "previewwidgetimpl.h" + +class PreviewWorkspace : public QWorkspace +{ + Q_OBJECT +public: + PreviewWorkspace( QWidget* parent = 0, const char* name = 0 ) + : QWorkspace( parent, name ) {} + ~PreviewWorkspace() {} + +protected: + void paintEvent( QPaintEvent* ); +}; + +class PreviewFrame : public QVBox +{ + Q_OBJECT + +public: + PreviewFrame( QWidget *parent = 0, const char *name = 0 ); + void setPreviewPalette(QPalette); + +private: + PreviewWidget *previewWidget; +}; + +#endif diff --git a/tools/designer/designer/previewwidget.ui b/tools/designer/designer/previewwidget.ui new file mode 100644 index 0000000..11a549a --- /dev/null +++ b/tools/designer/designer/previewwidget.ui @@ -0,0 +1,311 @@ + +PreviewWidgetBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + PreviewWidgetBase + + + + 0 + 0 + 378 + 236 + + + + + 1 + 1 + + + + Preview Window + + + + unnamed + + + 11 + + + 6 + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + Layout17 + + + + unnamed + + + 0 + + + 6 + + + + ButtonGroup1 + + + ButtonGroup + + + + unnamed + + + 11 + + + 6 + + + + RadioButton1 + + + RadioButton1 + + + true + + + + + RadioButton2 + + + RadioButton2 + + + + + RadioButton3 + + + RadioButton3 + + + + + + + ButtonGroup2 + + + ButtonGroup2 + + + + unnamed + + + 11 + + + 6 + + + + CheckBox1 + + + CheckBox1 + + + true + + + + + CheckBox2 + + + CheckBox2 + + + + + + + ProgressBar1 + + + 50 + + + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + LineEdit1 + + + LineEdit + + + + + + ComboBox + + + + ComboBox1 + + + + + Layout13 + + + + unnamed + + + 0 + + + 6 + + + + SpinBox1 + + + + + PushButton1 + + + PushButton + + + + + + + ScrollBar1 + + + Horizontal + + + + + Slider1 + + + Horizontal + + + + + textView + + + + 32767 + 50 + + + + <p> +<a href="http://www.trolltech.com/">http://www.trolltech.com</a> +</p> +<p> +<a href="http://www.kde.org/">http://www.kde.org</a> +</p> + + + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + init() + destroy() + + diff --git a/tools/designer/designer/previewwidgetimpl.cpp b/tools/designer/designer/previewwidgetimpl.cpp new file mode 100644 index 0000000..8e60336 --- /dev/null +++ b/tools/designer/designer/previewwidgetimpl.cpp @@ -0,0 +1,72 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qobjectlist.h" +#include "previewwidgetimpl.h" + +PreviewWidget::PreviewWidget( QWidget *parent, const char *name ) + : PreviewWidgetBase( parent, name ) +{ + // install event filter on child widgets + QObjectList *l = queryList("QWidget"); + QObjectListIt it(*l); + QObject * obj; + while ((obj = it.current()) != 0) { + ++it; + obj->installEventFilter(this); + ((QWidget*)obj)->setFocusPolicy(NoFocus); + } +} + +void PreviewWidget::closeEvent(QCloseEvent *e) +{ + e->ignore(); +} + +bool PreviewWidget::eventFilter(QObject *, QEvent *e) +{ + switch ( e->type() ) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::Enter: + case QEvent::Leave: + return TRUE; // ignore; + default: + break; + } + return FALSE; +} diff --git a/tools/designer/designer/previewwidgetimpl.h b/tools/designer/designer/previewwidgetimpl.h new file mode 100644 index 0000000..d4e44b4 --- /dev/null +++ b/tools/designer/designer/previewwidgetimpl.h @@ -0,0 +1,50 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PREVIEWWIDGETIMPL_H +#define PREVIEWWIDGETIMPL_H + +#include "previewwidget.h" + +class PreviewWidget : public PreviewWidgetBase +{ + Q_OBJECT + +public: + PreviewWidget( QWidget *parent = 0, const char *name = 0 ); + + void closeEvent(QCloseEvent *); + bool eventFilter(QObject *, QEvent *); +}; + +#endif diff --git a/tools/designer/designer/project.cpp b/tools/designer/designer/project.cpp new file mode 100644 index 0000000..3eae1c4 --- /dev/null +++ b/tools/designer/designer/project.cpp @@ -0,0 +1,1598 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +**1 This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "project.h" +#include "formwindow.h" +#include "designerappiface.h" +#include "../interfaces/languageinterface.h" +#include "pixmapcollection.h" +#ifndef QT_NO_SQL +#include "dbconnectionimpl.h" +#endif +#include "resource.h" +#include +#include "outputwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mainwindow.h" +#include + +#ifndef QT_NO_SQL +#include +#include +#include +#endif + +#include +#ifdef Q_OS_UNIX +# include +#endif + +#ifndef QT_NO_SQL +DatabaseConnection::~DatabaseConnection() +{ + delete iface; +} + +bool DatabaseConnection::refreshCatalog() +{ +#ifndef QT_NO_SQL + if ( loaded ) + return TRUE; + if ( !open() ) + return FALSE; + tbls = conn->tables( QSql::TableType( QSql::Tables | QSql::Views ) ); + flds.clear(); + for ( QStringList::Iterator it = tbls.begin(); it != tbls.end(); ++it ) { + QSqlRecord fil = conn->record( *it ); + QStringList lst; + for ( uint j = 0; j < fil.count(); ++j ) + lst << fil.field( j )->name(); + flds.insert( *it, lst ); + } + loaded = TRUE; + conn->close(); + return loaded; +#else + return FALSE; +#endif +} + +#ifndef QT_NO_SQL +void DatabaseConnection::remove() +{ + if ( nm == "(default)" ) + QSqlDatabase::removeDatabase( QSqlDatabase::defaultConnection ); + else + QSqlDatabase::removeDatabase( nm ); + // the above will effectively delete the current connection + conn = 0; +} +#endif + +bool DatabaseConnection::open( bool suppressDialog ) +{ +#ifndef QT_NO_SQL + // register our name, if nec + if ( nm == "(default)" ) { + if ( !QSqlDatabase::contains() ) // default doesn't exists? + conn = QSqlDatabase::addDatabase( drv ); + else + conn = QSqlDatabase::database(); + } else { + if ( !QSqlDatabase::contains( nm ) ) + conn = QSqlDatabase::addDatabase( drv, nm ); + else + conn = QSqlDatabase::database( nm ); + } + conn->setDatabaseName( dbName ); + conn->setUserName( uname ); + conn->setPassword( pword ); + conn->setHostName( hname ); + conn->setPort( prt ); + bool success = conn->open(); + for( ; suppressDialog == FALSE ; ) { + bool done = FALSE; + if ( !success ) { + DatabaseConnectionEditor dia( this, 0 , 0 , TRUE ); + switch( dia.exec() ) { + case QDialog::Accepted: + done = FALSE; + break; + case QDialog::Rejected: + done = TRUE; + break; + } + } + if ( done ) + break; + conn->setUserName( uname ); + conn->setPassword( pword ); + conn->setHostName( hname ); + conn->setPort( prt ); + success = conn->open(); + if ( !success ) { + switch( QMessageBox::warning( project->messageBoxParent(), QApplication::tr( "Connection" ), + QApplication::tr( "Could not connect to the database.\n" + "Press 'OK' to continue or 'Cancel' to " + "specify different\nconnection information.\n" ) + + QString( "[" + conn->lastError().driverText() + "\n" + + conn->lastError().databaseText() + "]\n" ), + QApplication::tr( "&OK" ), + QApplication::tr( "&Cancel" ), QString::null, 0, 1 ) ) { + case 0: // OK or Enter + continue; + case 1: // Cancel or Escape + done = TRUE; + break; + } + } else + break; + if ( done ) + break; + } + if ( !success ) { + dbErr = conn->lastError().driverText() + "\n" + conn->lastError().databaseText(); + remove(); + } + return success; +#else + return FALSE; +#endif +} + +void DatabaseConnection::close() +{ + if ( !loaded ) + return; +#ifndef QT_NO_SQL + if ( conn ) { + conn->close(); + } +#endif +} + +DesignerDatabase *DatabaseConnection::iFace() +{ + if ( !iface ) + iface = new DesignerDatabaseImpl( this ); + return iface; +} + +#endif + +//////// + +bool Project::isDummy() const +{ + return isDummyProject; +} + +Project::Project( const QString &fn, const QString &pName, + QPluginManager *pm, bool isDummy, + const QString &l ) + : proName( pName ), projectSettingsPluginManager( pm ), isDummyProject( isDummy ) +{ + modified = TRUE; + pixCollection = new PixmapCollection( this ); + iface = 0; + lang = l; + is_cpp = lang == "C++"; + cfg.insert( "(all)", "qt warn_on release" ); + templ = "app"; + setFileName( fn ); + if ( !pName.isEmpty() ) + proName = pName; + sourcefiles.setAutoDelete( TRUE ); + modified = FALSE; + objs.setAutoDelete( FALSE ); + fakeFormFiles.setAutoDelete( FALSE ); +} + +Project::~Project() +{ + if ( singleProjectMode() ) + removeTempProject(); + delete iface; + delete pixCollection; +} + +void Project::setModified( bool b ) +{ + modified = b; + emit projectModified(); +} + +#ifndef QT_NO_SQL +DatabaseConnection *Project::databaseConnection( const QString &name ) +{ + for ( DatabaseConnection *conn = dbConnections.first(); + conn; + conn = dbConnections.next() ) { + if ( conn->name() == name ) + return conn; + } + return 0; +} +#endif + +void Project::setFileName( const QString &fn, bool doClear ) +{ + if ( fn == filename ) + return; + + if ( singleProjectMode() ) { + QString qsa = QString( getenv( "HOME" ) ) + QString( "/.qsa" ); + if ( !QFile::exists( qsa ) ) { + QDir d; + d.mkdir( qsa ); + } + if ( fn == singleProFileName ) + return; + singleProFileName = fn; + static int counter = 0; + QString str_counter = QString::number( counter++ ); + str_counter = "/.qsa/" + str_counter; + LanguageInterface *iface = MetaDataBase::languageInterface( language() ); + filename = QString( getenv( "HOME" ) + str_counter + QString( "tmp_" ) + + QFileInfo( fn ).baseName() + "/" + QFileInfo( fn ).baseName() + ".pro" ); + removeTempProject(); + if ( iface && iface->supports( LanguageInterface::CompressProject ) ) { + filename = iface->uncompressProject( makeAbsolute( singleProFileName ), + QString( getenv( "HOME" ) + + str_counter + QString( "tmp_" ) + + QFileInfo( fn ).baseName() ) ); + proName = makeAbsolute( singleProFileName ); + } + } else { + filename = fn; + if ( !filename.endsWith( ".pro" ) ) + filename += ".pro"; + proName = filename; + } + + + if ( proName.contains( '.' ) ) + proName = proName.left( proName.find( '.' ) ); + + if ( !doClear ) + return; + clear(); + if ( QFile::exists( filename ) ) + parse(); +} + +QString Project::fileName( bool singlePro ) const +{ + if ( singlePro ) + return singleProFileName; + return filename; +} + +QString Project::databaseDescription() const +{ + return dbFile; +} + +QString Project::projectName() const +{ + return proName; +} + +static QString parse_part( const QString &part ) +{ + QString res; + bool inName = FALSE; + QString currName; + for ( int i = 0; i < (int)part.length(); ++i ) { + QChar c = part[ i ]; + if ( !inName ) { + if ( c != ' ' && c != '\t' && c != '\n' && c != '=' && c != '\\' && c != '+' ) + inName = TRUE; + else + continue; + } + if ( inName ) { + if ( c == '\n' ) + break; + res += c; + } + } + return res; +} + +QStringList parse_multiline_part( const QString &contents, const QString &key, int *start = 0 ) +{ + if ( start ) + *start = -1; + QString lastWord; + // Account for things like win32: SOURCES + int extraWhiteSpaceCount = 0; + int braceCount = 0; + for ( int i = 0; i < (int)contents.length(); ++i ) { + QChar c( contents[ i ] ); + switch ( c ) { + case '{': + braceCount++; + lastWord = ""; + break; + case '}': + braceCount--; + lastWord = ""; + break; + case ' ': case '\t': + if (!key.startsWith(lastWord)) { + lastWord = ""; + extraWhiteSpaceCount = 0; + } else { + extraWhiteSpaceCount++; + } + break; + case '\\': case '\n': + lastWord = ""; + break; + case '#': + while ( contents[ i ] != '\n' && i < (int)contents.length() ) + ++i; + break; + default: + lastWord += c; + } + + // ### we should read the 'bla { SOURCES= ... }' stuff as well (braceCount > 0) + if ( lastWord == key && braceCount == 0 ) { + if ( start ) + *start = i - lastWord.length() - extraWhiteSpaceCount + 1; + QStringList lst; + bool inName = FALSE; + QString currName; + bool hadEqual = FALSE; + for ( ; i < (int)contents.length(); ++i ) { + c = contents[ i ]; + if ( !hadEqual && c != '=' ) + continue; + if ( !hadEqual ) { + hadEqual = TRUE; + continue; + } + if ( ( c.isLetter() || + c.isDigit() || + c == '.' || + c == '/' || + c == '_' || + c == '\\' || + c == '\"' || + c == '\'' || + c == '=' || + c == '$' || + c == '-' || + c == '(' || + c == ')' || + c == ':' || + c == '+' || + c == ',' || + c == '~' || + c == '{' || + c == '}' || + c == '@' ) && + c != ' ' && c != '\t' && c != '\n' ) { + if ( !inName ) + currName = QString::null; + if ( c != '\\' || contents[i+1] != '\n' ) { + currName += c; + inName = TRUE; + } + } else { + if ( inName ) { + inName = FALSE; + if ( currName.simplifyWhiteSpace() != "\\" ) + lst.append( currName ); + } + if ( c == '\n' && i > 0 && contents[ (int)i - 1 ] != '\\' ) + break; + } + } + return lst; + } + } + + return QStringList(); +} + +void Project::parse() +{ + QFile f( filename ); + if ( !f.exists() || !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + QString contents = ts.read(); + f.close(); + + proName = QFileInfo( filename ).baseName(); + + QStringList::ConstIterator it; + + int i = contents.find( "LANGUAGE" ); + if ( i != -1 ) { + lang = ""; + is_cpp = FALSE; + QString part = contents.mid( i + QString( "LANGUAGE" ).length() ); + lang = parse_part( part ); + is_cpp = lang == "C++"; + } + + i = contents.find( "DBFILE" ); + if ( i != -1 ) { + dbFile = ""; + QString part = contents.mid( i + QString( "DBFILE" ).length() ); + dbFile = parse_part( part ); + } + + QStringList uifiles = parse_multiline_part( contents, "FORMS" ); + uifiles += parse_multiline_part( contents, "INTERFACES" ); // compatibility + for ( it = uifiles.begin(); it != uifiles.end(); ++it ) { + if ( (*it).startsWith( "__APPOBJ" ) ) + continue; + (void) new FormFile( *it, FALSE, this ); + } + + + i = contents.find( "TEMPLATE" ); + if ( i != -1 ) { + templ = ""; + QString part = contents.mid( i + QString( "TEMPLATE" ).length() ); + templ = parse_part( part ); + } + + readPlatformSettings( contents, "CONFIG", cfg ); + readPlatformSettings( contents, "LIBS", lbs ); + readPlatformSettings( contents, "INCLUDEPATH", inclPath ); + readPlatformSettings( contents, "DEFINES", defs ); + readPlatformSettings( contents, "SOURCES", sources ); + readPlatformSettings( contents, "HEADERS", headers ); + + LanguageInterface *iface = MetaDataBase::languageInterface( lang ); + if ( iface ) { + QStringList sourceKeys; + iface->sourceProjectKeys( sourceKeys ); + for ( QStringList::Iterator it = sourceKeys.begin(); it != sourceKeys.end(); ++it ) { + QStringList lst = parse_multiline_part( contents, *it ); + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) + (void) new SourceFile( *it, FALSE, this ); + } + } + + updateCustomSettings(); + + for ( it = csList.begin(); it != csList.end(); ++it ) { + i = contents.find( *it ); + if ( i != -1 ) { + QString val = ""; + QString part = contents.mid( i + QString( *it ).length() ); + val = parse_part( part ); + customSettings.replace( *it, val ); + } + } + + loadConnections(); + + QStringList images = parse_multiline_part( contents, "IMAGES" ); + + // ### remove that for the final - this is beta-compatibility + if ( images.isEmpty() && QDir( QFileInfo( filename ).dirPath( TRUE ) + "/images" ).exists() ) { + images = QDir( QFileInfo( filename ).dirPath( TRUE ) + "/images" ).entryList(); + for ( int i = 0; i < (int)images.count(); ++i ) + images[ i ].prepend( "images/" ); + modified = TRUE; + } + + for ( QStringList::ConstIterator pit = images.begin(); pit != images.end(); ++pit ) + pixCollection->load( *pit ); +} + +void Project::clear() +{ + dbFile = ""; + proName = "unnamed"; + desc = ""; +} + +bool Project::removeSourceFile( SourceFile *sf ) +{ + if ( !sourcefiles.containsRef( sf ) ) + return FALSE; + if ( !sf->close() ) + return FALSE; + sourcefiles.removeRef( sf ); + modified = TRUE; + emit sourceFileRemoved( sf ); + return TRUE; +} + +void Project::setDatabaseDescription( const QString &db ) +{ + dbFile = db; +} + +void Project::setDescription( const QString &s ) +{ + desc = s; +} + +QString Project::description() const +{ + return desc; +} + + +bool Project::isValid() const +{ + // #### do more checking here? + if ( filename.isEmpty() || proName.isEmpty() ) + return FALSE; + + return TRUE; +} + +QString Project::makeAbsolute( const QString &f ) +{ + if ( isDummy() ) + return f; + QString encodedUrl = QFileInfo( filename ).dirPath( TRUE ); + QUrl::encode( encodedUrl ); + QUrl u( encodedUrl, f ); + return u.path(); +} + +QString Project::makeRelative( const QString &f ) +{ + if ( isDummy() ) + return f; + QString p = QFileInfo( filename ).dirPath( TRUE ); + QString f2 = f; +#if defined(Q_WS_WIN32) + if ( p.endsWith("/") ) + p = p.left( p.length() - 1 ); + if ( f2.left( p.length() ).lower() == p.lower() ) +#else + if ( f2.left( p.length() ) == p ) +#endif + f2.remove( 0, p.length() + 1 ); + return f2; +} + +static void remove_contents( QString &contents, const QString &s ) +{ + int i = contents.find( s ); + if ( i != -1 ) { + int start = i; + int end = contents.find( '\n', i ); + if ( end == -1 ) + end = contents.length() - 1; + contents.remove( start, end - start + 1 ); + } +} + +static void remove_multiline_contents( QString &contents, const QString &s, int *strt = 0 ) +{ + int i = contents.find( s ); + int startBrace = contents.findRev("{", i); + int endBrace = contents.findRev("}", i); + // We found a startBrace before i, but no endBrace after the startBrace before i + if (startBrace != -1 && endBrace < startBrace) + return; + if ( strt ) + *strt = i; + int start = i; + bool lastWasBackspash = TRUE; + if ( i != -1 && ( i == 0 || contents[ i - 1 ] != '{' || contents[ i - 1 ] != ':' ) && !(i > 0 && contents[i-1] != '\n')) { + for ( ; i < (int)contents.length(); ++i ) { + if ( contents[ i ] == '\n' && !lastWasBackspash ) + break; + lastWasBackspash = ( contents[ i ] == '\\' || + lastWasBackspash && ( contents[ i ] == ' ' || contents[ i ] == '\t' ) ); + } + contents.remove( start, i - start + 1 ); + } +} + +void Project::save( bool onlyProjectFile ) +{ + bool anythingModified = FALSE; + + // save sources and forms + if ( !onlyProjectFile ) { + + saveConnections(); + + for ( SourceFile *sf = sourcefiles.first(); sf; sf = sourcefiles.next() ) { + anythingModified = anythingModified || sf->isModified(); + if ( !sf->save() ) + return; + } + + for ( FormFile *ff = formfiles.first(); ff; ff = formfiles.next() ) { + anythingModified = anythingModified || ff->isModified(); + if ( !ff->save() ) + return; + } + } + + if ( isDummy() || filename.isEmpty() ) + return; + + if ( !modified ) { + if ( singleProjectMode() ) { + LanguageInterface *iface = MetaDataBase::languageInterface( language() ); + if ( iface && iface->supports( LanguageInterface::CompressProject ) ) + iface->compressProject( makeAbsolute( filename ), singleProFileName, anythingModified ); + } + return; + } + + QFile f( filename ); + QString original = ""; + + // read the existing file + bool hasPreviousContents = FALSE; + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + original = ts.read(); + f.close(); + hasPreviousContents = TRUE; + remove_contents( original, "{SOURCES+=" ); // ### compatibility with early 3.0 betas + remove_contents( original, "DBFILE" ); + remove_contents( original, "LANGUAGE" ); + remove_contents( original, "TEMPLATE" ); + removePlatformSettings( original, "CONFIG" ); + removePlatformSettings( original, "DEFINES" ); + removePlatformSettings( original, "LIBS" ); + removePlatformSettings( original, "INCLUDEPATH" ); + removePlatformSettings( original, "SOURCES" ); + removePlatformSettings( original, "HEADERS" ); + remove_multiline_contents( original, "FORMS" ); + remove_multiline_contents( original, "INTERFACES" ); // compatibility + remove_multiline_contents( original, "IMAGES" ); + for ( QStringList::Iterator it = csList.begin(); it != csList.end(); ++it ) + remove_contents( original, *it ); + } + + if (!original.isEmpty()) { + // Removes any new lines at the beginning of the file + while (original.startsWith("\n")) + original.remove(0, 1); + } + + // the contents of the saved file + QString contents; + + // template + contents += "TEMPLATE\t= " + templ + "\n"; + + // language + contents += "LANGUAGE\t= " + lang + "\n"; + contents += "\n"; + + // config + writePlatformSettings( contents, "CONFIG", cfg ); + LanguageInterface *iface = MetaDataBase::languageInterface( lang ); + if ( iface ) { + QStringList sourceKeys; + iface->sourceProjectKeys( sourceKeys ); + for ( QStringList::Iterator spit = sourceKeys.begin(); spit != sourceKeys.end(); ++spit ) + remove_multiline_contents( contents, *spit ); + } + + // libs, defines, includes + writePlatformSettings( contents, "LIBS", lbs ); + writePlatformSettings( contents, "DEFINES", defs ); + writePlatformSettings( contents, "INCLUDEPATH", inclPath ); + writePlatformSettings( contents, "SOURCES", sources ); + writePlatformSettings( contents, "HEADERS", headers ); + + // unix + if ( !hasPreviousContents ) { + contents += + "unix {\n" + " UI_DIR = .ui\n" + " MOC_DIR = .moc\n" + " OBJECTS_DIR = .obj\n" + "}\n\n"; + } + + // sources + if ( !sourcefiles.isEmpty() && iface ) { + QMap sourceToKey; + for ( SourceFile *f = sourcefiles.first(); f; f = sourcefiles.next() ) { + QString key = iface->projectKeyForExtension( QFileInfo( f->fileName() ).extension() ); + QStringList lst = sourceToKey[ key ]; + lst << makeRelative( f->fileName() ); + sourceToKey.replace( key, lst ); + } + + for ( QMap::Iterator skit = sourceToKey.begin(); + skit != sourceToKey.end(); ++skit ) { + QString part = skit.key() + "\t+= "; + QStringList lst = *skit; + for ( QStringList::Iterator sit = lst.begin(); sit != lst.end(); ++sit ) { + part += *sit; + part += ++sit != lst.end() ? " \\\n\t" : ""; + --sit; + } + part += "\n\n"; + contents += part; + } + } + + // forms and interfaces + if ( !formfiles.isEmpty() ) { + contents += "FORMS\t= "; + for ( QPtrListIterator fit = formfiles; fit.current(); ++fit ) { + contents += fit.current()->fileName() + + (fit != formfiles.last() ? " \\\n\t" : ""); + } + contents += "\n\n"; + } + + // images + if ( !pixCollection->isEmpty() ) { + contents += "IMAGES\t= "; + QValueList pixmaps = pixCollection->pixmaps(); + for ( QValueList::Iterator it = pixmaps.begin(); + it != pixmaps.end(); ++it ) { + contents += makeRelative( (*it).absname ); + contents += ++it != pixmaps.end() ? " \\\n\t" : ""; + --it; + } + contents += "\n\n"; + } + + // database + if ( !dbFile.isEmpty() ) + contents += "DBFILE\t= " + dbFile + "\n"; + + // custom settings + for ( QStringList::Iterator it = csList.begin(); it != csList.end(); ++it ) { + QString val = *customSettings.find( *it ); + if ( !val.isEmpty() ) + contents += *it + "\t= " + val + "\n"; + } + + if ( !f.open( IO_WriteOnly | IO_Translate ) ) { + QMessageBox::warning( messageBoxParent(), + "Save Project Failed", "Couldn't write project file " + filename ); + return; + } + + QTextStream os( &f ); + os << contents; + if (hasPreviousContents) + os << original; + + f.close(); + + setModified( FALSE ); + + if ( singleProjectMode() ) { + LanguageInterface *iface = MetaDataBase::languageInterface( language() ); + if ( iface && iface->supports( LanguageInterface::CompressProject ) ) + iface->compressProject( makeAbsolute( filename ), singleProFileName, TRUE ); + } +} + +#ifndef QT_NO_SQL +QPtrList Project::databaseConnections() const +{ + return dbConnections; +} +#endif + +#ifndef QT_NO_SQL +void Project::setDatabaseConnections( const QPtrList &lst ) +{ + dbConnections = lst; +} +#endif + +#ifndef QT_NO_SQL +void Project::addDatabaseConnection( DatabaseConnection *conn ) +{ + dbConnections.append( conn ); + modified = TRUE; +} +#endif + +#ifndef QT_NO_SQL +void Project::removeDatabaseConnection( const QString &c ) +{ + for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) { + if ( conn->name() == c ) { + conn->remove(); + dbConnections.removeRef( conn ); + delete conn; + return; + } + } +} +#endif + +#ifndef QT_NO_SQL +QStringList Project::databaseConnectionList() +{ + QStringList lst; + for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) + lst << conn->name(); + return lst; +} +#endif + +#ifndef QT_NO_SQL +QStringList Project::databaseTableList( const QString &connection ) +{ + DatabaseConnection *conn = databaseConnection( connection ); + if ( !conn ) { + return QStringList(); + } + return conn->tables(); +} +#endif + +#ifndef QT_NO_SQL +QStringList Project::databaseFieldList( const QString &connection, const QString &table ) +{ + DatabaseConnection *conn = databaseConnection( connection ); + if ( !conn ) + return QStringList(); + return conn->fields( table ); +} +#endif + +#ifndef QT_NO_SQL +static QString makeIndent( int indent ) +{ + QString s; + s.fill( ' ', indent * 4 ); + return s; +} +#endif + +#ifndef QT_NO_SQL +static void saveSingleProperty( QTextStream &ts, const QString& name, const QString& value, int indent ) +{ + ts << makeIndent( indent ) << "" << endl; + ++indent; + ts << makeIndent( indent ) << "" << value << "" << endl; + --indent; + ts << makeIndent( indent ) << "" << endl; +} +#endif + +void Project::saveConnections() +{ +#ifndef QT_NO_SQL + if ( dbFile.isEmpty() ) { + QFileInfo fi( fileName() ); + setDatabaseDescription( fi.baseName() + ".db" ); + } + + QFile f( makeAbsolute( dbFile ) ); + + if ( dbConnections.isEmpty() ) { + if ( f.exists() ) + f.remove(); + setDatabaseDescription( "" ); + modified = TRUE; + return; + } + + /* .db xml */ + if ( f.open( IO_WriteOnly | IO_Translate ) ) { + QTextStream ts( &f ); + ts.setCodec( QTextCodec::codecForName( "UTF-8" ) ); + ts << "" << endl; + + /* db connections */ + int indent = 0; + for ( DatabaseConnection *conn = dbConnections.first(); conn; conn = dbConnections.next() ) { + ts << makeIndent( indent ) << "" << endl; + ++indent; + saveSingleProperty( ts, "name", conn->name(), indent ); + saveSingleProperty( ts, "driver", conn->driver(), indent ); + saveSingleProperty( ts, "database", conn->database(), indent ); + saveSingleProperty( ts, "username", conn->username(), indent ); + saveSingleProperty( ts, "hostname", conn->hostname(), indent ); + saveSingleProperty( ts, "port", QString::number( conn->port() ), indent ); + + /* connection tables */ + QStringList tables = conn->tables(); + for ( QStringList::Iterator it = tables.begin(); + it != tables.end(); ++it ) { + ts << makeIndent( indent ) << "" << endl; + ++indent; + saveSingleProperty( ts, "name", (*it), indent ); + + /* tables fields */ + QStringList fields = conn->fields( *it ); + for ( QStringList::Iterator it2 = fields.begin(); + it2 != fields.end(); ++it2 ) { + ts << makeIndent( indent ) << "" << endl; + ++indent; + saveSingleProperty( ts, "name", (*it2), indent ); + --indent; + ts << makeIndent( indent ) << "" << endl; + } + + --indent; + ts << makeIndent( indent ) << "
    " << endl; + } + + --indent; + ts << makeIndent( indent ) << "
    " << endl; + } + + ts << "
    " << endl; + f.close(); + } +#endif +} + +#ifndef QT_NO_SQL +static QDomElement loadSingleProperty( QDomElement e, const QString& name ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); + !n.isNull(); + n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.toElement().attribute("name") == name ) + return n; + } + return n; +} +#endif + +void Project::loadConnections() +{ +#ifndef QT_NO_SQL + if ( dbFile.isEmpty() || !QFile::exists( makeAbsolute( dbFile ) ) ) + return; + + QFile f( makeAbsolute( dbFile ) ); + if ( f.open( IO_ReadOnly ) ) { + QDomDocument doc; + QString errMsg; + int errLine; + if ( doc.setContent( &f, &errMsg, &errLine ) ) { + QDomElement e; + e = doc.firstChild().toElement(); + + /* connections */ + QDomNodeList connections = e.toElement().elementsByTagName( "connection" ); + for ( uint i = 0; i < connections.length(); i++ ) { + QDomElement connection = connections.item(i).toElement(); + QDomElement connectionName = loadSingleProperty( connection, "name" ); + QDomElement connectionDriver = loadSingleProperty( connection, "driver" ); + QDomElement connectionDatabase = loadSingleProperty( connection, + "database" ); + QDomElement connectionUsername = loadSingleProperty( connection, + "username" ); + QDomElement connectionHostname = loadSingleProperty( connection, + "hostname" ); + QDomElement connectionPort = loadSingleProperty( connection, + "port" ); + + DatabaseConnection *conn = new DatabaseConnection( this ); + conn->setName( connectionName.firstChild().firstChild().toText().data() ); + conn->setDriver( connectionDriver.firstChild().firstChild().toText().data() ); + conn->setDatabase( connectionDatabase.firstChild().firstChild().toText().data() ); + conn->setUsername( connectionUsername.firstChild().firstChild().toText().data() ); + conn->setHostname( connectionHostname.firstChild().firstChild().toText().data() ); + conn->setPort( QString( connectionPort.firstChild().firstChild().toText().data() ).toInt() ); + + /* connection tables */ + QDomNodeList tables = connection.toElement().elementsByTagName( "table" ); + for ( uint j = 0; j < tables.length(); j++ ) { + QDomElement table = tables.item(j).toElement(); + QDomElement tableName = loadSingleProperty( table, "name" ); + conn->addTable( tableName.firstChild().firstChild().toText().data() ); + + /* table fields */ + QStringList fieldList; + QDomNodeList fields = table.toElement().elementsByTagName( "field" ); + for ( uint k = 0; k < fields.length(); k++ ) { + QDomElement field = fields.item(k).toElement(); + QDomElement fieldName = loadSingleProperty( field, "name" ); + fieldList.append( fieldName.firstChild().firstChild().toText().data() ); + } + conn->setFields( tableName.firstChild().firstChild().toText().data(), + fieldList ); + } + + dbConnections.append( conn ); + } + } else { + qDebug( QString("Parse error: ") + errMsg + QString(" in line %d"), errLine ); + } + f.close(); + } +#endif +} + +/*! Opens the database \a connection. The connection remains open and +can be closed again with closeDatabase(). +*/ + +bool Project::openDatabase( const QString &connection, bool suppressDialog ) +{ +#ifndef QT_NO_SQL + DatabaseConnection *conn = databaseConnection( connection ); + if ( connection.isEmpty() && !conn ) + conn = databaseConnection( "(default)" ); + if ( !conn ) + return FALSE; + bool b = conn->open( suppressDialog ); + return b; +#else + Q_UNUSED( connection ); + Q_UNUSED( suppressDialog ); + return FALSE; +#endif +} + +/*! Closes the database \a connection. +*/ +void Project::closeDatabase( const QString &connection ) +{ +#ifndef QT_NO_SQL + DatabaseConnection *conn = databaseConnection( connection ); + if ( connection.isEmpty() && !conn ) + conn = databaseConnection( "(default)" ); + if ( !conn ) + return; + conn->close(); +#else + Q_UNUSED( connection ); +#endif +} + +// void Project::formClosed( FormWindow *fw ) +// { +// formWindows.remove( fw ); +// } + +QObjectList *Project::formList( bool resolveFakeObjects ) const +{ + QObjectList *l = new QObjectList; + for ( QPtrListIterator forms(formfiles); forms.current(); ++forms ) { + FormFile* f = forms.current(); + if ( f->formWindow() ) { + if ( resolveFakeObjects && f->formWindow()->isFake() ) + l->append( objectForFakeForm( f->formWindow() ) ); + else + l->append( f->formWindow()->child( 0, "QWidget" ) ); + } else if ( f->isFake() ) { + l->append( objectForFakeFormFile( f ) ); + } + } + return l; +} + +DesignerProject *Project::iFace() +{ + if ( !iface ) + iface = new DesignerProjectImpl( this ); + return iface; +} + +void Project::setLanguage( const QString &l ) +{ + if ( l == lang ) + return; + lang = l; + is_cpp = lang == "C++"; + updateCustomSettings(); + modified = TRUE; +} + +QString Project::language() const +{ + return lang; +} + +void Project::setCustomSetting( const QString &key, const QString &value ) +{ + customSettings.remove( key ); + customSettings.insert( key, value ); + modified = TRUE; +} + +QString Project::customSetting( const QString &key ) const +{ + return *customSettings.find( key ); +} + +void Project::updateCustomSettings() +{ + if ( !projectSettingsPluginManager ) + return; + +/* + ProjectSettingsInterface *iface = 0; + projectSettingsPluginManager->queryInterface( lang, (QUnknownInterface**)&iface ); + if ( !iface ) + return; + csList = iface->projectSettings(); + iface->release(); +*/ + + QInterfacePtr iface; + projectSettingsPluginManager->queryInterface( lang, &iface ); + if ( !iface ) + return; + csList = iface->projectSettings(); + customSettings.clear(); + +} + +void Project::setActive( bool b ) +{ + pixCollection->setActive( b ); +} + +void Project::addSourceFile( SourceFile *sf ) +{ + sourcefiles.append( sf ); + modified = TRUE; + emit sourceFileAdded( sf ); +} + + +SourceFile* Project::findSourceFile( const QString& filename, SourceFile *ignore ) const +{ + QPtrListIterator it(sourcefiles); + while ( it.current() ) { + if ( it.current() != ignore && it.current()->fileName() == filename ) + return it.current(); + ++it; + } + return 0; +} + +FormFile* Project::findFormFile( const QString& filename, FormFile *ignore ) const +{ + QPtrListIterator it(formfiles); + while ( it.current() ) { + if ( it.current() != ignore && it.current()->fileName() == filename ) + return it.current(); + ++it; + } + return 0; +} + +void Project::setIncludePath( const QString &platform, const QString &path ) +{ + if ( inclPath[platform] == path ) + return; + inclPath.replace( platform, path ); + modified = TRUE; +} + +void Project::setLibs( const QString &platform, const QString &path ) +{ + lbs.replace( platform, path ); +} + +void Project::setDefines( const QString &platform, const QString &path ) +{ + defs.replace( platform, path ); +} + +void Project::setConfig( const QString &platform, const QString &config ) +{ + cfg.replace( platform, config ); +} + +QString Project::config( const QString &platform ) const +{ + return cfg[ platform ]; +} + +QString Project::libs( const QString &platform ) const +{ + return lbs[ platform ]; +} + +QString Project::defines( const QString &platform ) const +{ + return defs[ platform ]; +} + +QString Project::includePath( const QString &platform ) const +{ + return inclPath[ platform ]; +} + +QString Project::templte() const +{ + return templ; +} + +void Project::setTemplate( const QString &t ) +{ + templ = t; +} + +void Project::readPlatformSettings( const QString &contents, + const QString &setting, + QMap &res ) +{ + const QString platforms[] = { "", "win32", "unix", "mac", QString::null }; + for ( int i = 0; platforms[ i ] != QString::null; ++i ) { + QString p = platforms[ i ]; + if ( !p.isEmpty() ) + p += ":"; + QStringList lst = parse_multiline_part( contents, p + setting ); + QString s = lst.join( " " ); + QString key = platforms[ i ]; + if ( key.isEmpty() ) + key = "(all)"; + res.replace( key, s ); + } +} + +void Project::removePlatformSettings( QString &contents, const QString &setting ) +{ + const QString platforms[] = { "win32", "unix", "mac", "", QString::null }; + for ( int i = 0; platforms[ i ] != QString::null; ++i ) { + QString p = platforms[ i ]; + if ( !p.isEmpty() ) + p += ":"; + remove_multiline_contents( contents, p + setting ); + } +} + +void Project::writePlatformSettings( QString &contents, const QString &setting, + const QMap &input ) +{ + const QString platforms[] = { "", "win32", "unix", "mac", QString::null }; + int i; + LanguageInterface *iface = MetaDataBase::languageInterface( lang ); + if (iface && (setting == "SOURCES" || setting == "HEADERS")) // The (all) part will be saved later on + i = 1; + else + i = 0; + for (; platforms[ i ] != QString::null; ++i ) { + QString p = platforms[ i ]; + if ( !p.isEmpty() ) + p += ":"; + QString key = platforms[ i ]; + if ( key.isEmpty() ) + key = "(all)"; + QMap::ConstIterator it = input.find( key ); + if ( it == input.end() || (*it).isEmpty() ) + continue; + contents += p + setting + "\t+= " + *it + "\n\n"; + } +} + +void Project::addFormFile( FormFile *ff ) +{ + formfiles.append( ff ); + modified = TRUE; + emit formFileAdded( ff ); +} + +bool Project::removeFormFile( FormFile *ff ) +{ + if ( !formfiles.containsRef( ff ) ) + return FALSE; + if ( !ff->close() ) + return FALSE; + formfiles.removeRef( ff ); + modified = TRUE; + emit formFileRemoved( ff ); + return TRUE; +} + +void Project::addObject( QObject *o ) +{ + bool wasModified = modified; + objs.append( o ); + FormFile *ff = new FormFile( "", FALSE, this, "qt_fakewindow" ); + ff->setFileName( "__APPOBJ" + QString( o->name() ) + ".ui" ); + fakeFormFiles.insert( (void*)o, ff ); + MetaDataBase::addEntry( o ); + if ( hasGUI() ) { + QWidget *parent = MainWindow::self ? MainWindow::self->qWorkspace() : 0; + FormWindow *fw = new FormWindow( ff, MainWindow::self, parent, "qt_fakewindow" ); + fw->setProject( this ); + if ( QFile::exists( ff->absFileName() ) ) + Resource::loadExtraSource( ff, ff->absFileName(), + MetaDataBase::languageInterface( language() ), FALSE ); + if ( MainWindow::self ) + fw->setMainWindow( MainWindow::self ); + if ( MainWindow::self ) { + QApplication::sendPostedEvents( MainWindow::self->qWorkspace(), QEvent::ChildInserted ); + connect( fw, + SIGNAL( undoRedoChanged( bool, bool, const QString &, const QString & ) ), + MainWindow::self, + SLOT( updateUndoRedo( bool, bool, const QString &, const QString & ) ) + ); + } + if ( fw->parentWidget() ) { + fw->parentWidget()->setFixedSize( 1, 1 ); + fw->show(); + } + } else { + if ( QFile::exists( ff->absFileName() ) ) + Resource::loadExtraSource( ff, ff->absFileName(), + MetaDataBase::languageInterface( language() ), FALSE ); + } + emit objectAdded( o ); + modified = wasModified; +} + +void Project::setObjects( const QObjectList &ol ) +{ + for ( QObjectListIt it( ol ); it.current(); ++it ) + addObject( it.current() ); +} + +void Project::removeObject( QObject *o ) +{ + bool wasModified = modified; + objs.removeRef( o ); + MetaDataBase::removeEntry( o ); + fakeFormFiles.remove( (void*)o ); + emit objectRemoved( o ); + modified = wasModified; +} + +QObjectList Project::objects() const +{ + return objs; +} + +FormFile *Project::fakeFormFileFor( QObject *o ) const +{ + return fakeFormFiles.find( (void*)o ); +} + +QObject *Project::objectForFakeForm( FormWindow *fw ) const +{ + for ( QPtrDictIterator it( fakeFormFiles ); it.current(); ++it ) { + if ( it.current()->formWindow() == fw || + it.current() == fw->formFile() ) + return (QObject*)it.currentKey(); + } + return 0; +} + +QObject *Project::objectForFakeFormFile( FormFile *ff ) const +{ + for ( QPtrDictIterator it( fakeFormFiles ); it.current(); ++it ) { + if ( it.current() == ff ) + return (QObject*)it.currentKey(); + } + return 0; +} + +void Project::removeTempProject() +{ + if ( !singleProjectMode() ) + return; + QDir d( QFileInfo( filename ).dirPath() ); + if ( !d.exists( QFileInfo( filename ).dirPath() ) ) + return; + QStringList files = d.entryList( QDir::Files ); + QStringList::Iterator it; + for ( it = files.begin(); it != files.end(); ++it ) { + d.remove( *it ); + } + if ( d.exists( QFileInfo( filename ).dirPath() + "/images" ) ) { + d = QDir( QFileInfo( filename ).dirPath() + "/images" ); + files = d.entryList( QDir::Files ); + for ( it = files.begin(); it != files.end(); ++it ) + d.remove( *it ); + d = QDir( QFileInfo( filename ).dirPath() ); + d.remove( "images" ); + } + d.remove( QFileInfo( filename ).dirPath() ); +#if defined(Q_OS_UNIX) + // ##### implement for all platforms, ideally should be in Qt + ::rmdir( d.absPath().latin1() ); +#endif +} + +void Project::addAndEditFunction( const QString &function, const QString &functionBody, bool openDeveloper ) +{ + for ( SourceFile *f = sourcefiles.first(); f; f = sourcefiles.next() ) { + if ( QFileInfo( f->fileName() ).baseName() == "main" ) { + QValueList funcs; + LanguageInterface *iface = MetaDataBase::languageInterface( language() ); + if ( !iface ) + return; + iface->functions( f->text(), &funcs ); + QString func = function; + int i = func.find( '(' ); + if ( i != -1 ) + func = func.left( i ); + + bool found = FALSE; + for ( QValueList::Iterator it = funcs.begin(); + it != funcs.end(); ++it ) { + if ( (*it).name.left( (*it).name.find( '(' ) ) == func ) { + found = TRUE; + break; + } + } + + if ( !found ) { + QString code = f->text(); + if ( functionBody.isEmpty() ) + code += "\n\n" + iface->createFunctionStart( "", func, "", "" ) + "()\n{\n\n}\n"; + else + code += "\n\n" + iface->createFunctionStart( "", func, "", "" ) + + "()\n" + functionBody + "\n"; + f->setText( code ); + if ( f->editor() ) + f->editor()->refresh( FALSE ); + } + + if ( openDeveloper ) { + if ( MainWindow::self ) + MainWindow::self->editSource( f ); + f->editor()->setFunction( func, "" ); + } + + break; + } + } +} + +bool Project::hasParentObject( QObject *o ) +{ + for ( QObject *p = objs.first(); p; p = objs.next() ) { + QObject *c = p->child( o->name(), o->className() ); + if ( c ) + return TRUE; + } + return FALSE; +} + +QString Project::qualifiedName( QObject *o ) +{ + QString name = o->name(); + QObject *p = o->parent(); + while ( p ) { + name.prepend( QString( p->name() ) + "." ); + if ( objs.findRef( p ) != -1 ) + break; + p = p->parent(); + } + return name; +} + +bool Project::singleProjectMode() const +{ + return !MainWindow::self || MainWindow::self->singleProjectMode(); +} + +QWidget *Project::messageBoxParent() const +{ + return MainWindow::self; +} + +void Project::designerCreated() +{ + for ( FormFile *ff = formfiles.first(); ff; ff = formfiles.next() ) { + FormWindow *fw = ff->formWindow(); + if ( !fw || fw->mainWindow() ) + continue; + fw->setMainWindow( MainWindow::self ); + connect( fw, SIGNAL( undoRedoChanged( bool, bool, const QString &, + const QString & ) ), + MainWindow::self, SLOT( updateUndoRedo( bool, bool, + const QString &, const QString & ) ) ); + fw->reparent( MainWindow::self->qWorkspace(), QPoint( 0, 0 ), FALSE ); + QApplication::sendPostedEvents( MainWindow::self->qWorkspace(), + QEvent::ChildInserted ); + fw->parentWidget()->setFixedSize( 1, 1 ); + fw->show(); + } +} + +void Project::formOpened( FormWindow *fw ) +{ + if ( fw->isFake() ) + return; + emit newFormOpened( fw ); +} + +QString Project::locationOfObject( QObject *o ) +{ + if ( !o ) + return QString::null; + + if ( MainWindow::self ) { + QWidgetList windows = MainWindow::self->qWorkspace()->windowList(); + for ( QWidget *w = windows.first(); w; w = windows.next() ) { + FormWindow *fw = ::qt_cast(w); + SourceEditor *se = ::qt_cast(w); + if ( fw ) { + if ( fw->isFake() ) + return objectForFakeForm( fw )->name() + QString( " [Source]" ); + else + return fw->name() + QString( " [Source]" ); + } else if ( se ) { + if ( !se->object() ) + continue; + if ( se->formWindow() ) + return se->formWindow()->name() + QString( " [Source]" ); + else + return makeRelative( se->sourceFile()->fileName() ); + } + } + } + + if ( ::qt_cast(o) ) { + for ( QPtrListIterator sources = sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + if ( f == o ) + return makeRelative( f->fileName() ); + } + } + + extern QMap *qwf_forms; + if ( !qwf_forms ) { + qWarning( "Project::locationOfObject: qwf_forms is NULL!" ); + return QString::null; + } + + QString s = makeRelative( *qwf_forms->find( (QWidget*)o ) ); + s += " [Source]"; + return s; +} + +bool Project::hasGUI() const +{ + return qApp->type() != QApplication::Tty; +} diff --git a/tools/designer/designer/project.h b/tools/designer/designer/project.h new file mode 100644 index 0000000..4bd3f6c --- /dev/null +++ b/tools/designer/designer/project.h @@ -0,0 +1,280 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PROJECT_H +#define PROJECT_H + +#include + +#include +#include +#include +#include +#include +#include "../interfaces/projectsettingsiface.h" +#include "sourcefile.h" +#include "formfile.h" +#include +#include +#include "formfile.h" + +class QObjectList; +struct DesignerProject; +struct DesignerDatabase; +class PixmapCollection; +class Project; + +#ifndef QT_NO_SQL +class QSqlDatabase; + +class DatabaseConnection +{ +public: + DatabaseConnection( Project *p ) : +#ifndef QT_NO_SQL + conn( 0 ), +#endif + project( p ), loaded( FALSE ), iface( 0 ) {} + ~DatabaseConnection(); + + bool refreshCatalog(); + bool open( bool suppressDialog = TRUE ); + void close(); + DesignerDatabase *iFace(); + + bool isLoaded() const { return loaded; } + void setName( const QString& n ) { nm = n; } + QString name() const { return nm; } + void setDriver( const QString& d ) { drv = d; } + QString driver() const { return drv; } + void setDatabase( const QString& db ) { dbName = db; } + QString database() const { return dbName; } + void setUsername( const QString& u ) { uname = u; } + QString username() const { return uname; } + void setPassword( const QString& p ) { pword = p; } + QString password() const { return pword; } + void setHostname( const QString& h ) { hname = h; } + QString hostname() const { return hname; } + void setPort( int p ) { prt = p; } + int port() const { return prt; } + QString lastError() const { return dbErr; } + void addTable( const QString& t ) { tbls.append(t); } + void setFields( const QString& t, const QStringList& f ) { flds[t] = f; } + QStringList tables() const { return tbls; } + QStringList fields( const QString& t ) { return flds[t]; } + QMap fields() { return flds; } +#ifndef QT_NO_SQL + QSqlDatabase* connection() const { return conn; } + void remove(); +#endif + +private: + QString nm; + QString drv, dbName, uname, pword, hname; + QString dbErr; + int prt; + QStringList tbls; + QMap flds; +#ifndef QT_NO_SQL + QSqlDatabase *conn; +#endif + Project *project; + bool loaded; + DesignerDatabase *iface; +}; + +#endif + +class Project : public QObject +{ + Q_OBJECT + friend class DatabaseConnection; + +public: + Project( const QString &fn, const QString &pName = QString::null, + QPluginManager *pm = 0, bool isDummy = FALSE, + const QString &l = "C++" ); + ~Project(); + + void setFileName( const QString &fn, bool doClear = TRUE ); + QString fileName( bool singlePro = FALSE ) const; + QString projectName() const; + + void setDatabaseDescription( const QString &db ); + QString databaseDescription() const; + + void setDescription( const QString &s ); + QString description() const; + + void setLanguage( const QString &l ); + QString language() const; + + + bool isValid() const; + + // returns TRUE if this project is the project + bool isDummy() const; + + QString makeAbsolute( const QString &f ); + QString makeRelative( const QString &f ); + + void save( bool onlyProjectFile = FALSE ); + +#ifndef QT_NO_SQL + QPtrList databaseConnections() const; + void setDatabaseConnections( const QPtrList &lst ); + void addDatabaseConnection( DatabaseConnection *conn ); + void removeDatabaseConnection( const QString &conn ); + DatabaseConnection *databaseConnection( const QString &name ); + QStringList databaseConnectionList(); + QStringList databaseTableList( const QString &connection ); + QStringList databaseFieldList( const QString &connection, const QString &table ); +#endif + void saveConnections(); + void loadConnections(); + + bool openDatabase( const QString &connection, bool suppressDialog = TRUE ); + void closeDatabase( const QString &connection ); + + QObjectList *formList( bool resolveFakeObjects = FALSE ) const; + + DesignerProject *iFace(); + + void setCustomSetting( const QString &key, const QString &value ); + QString customSetting( const QString &key ) const; + + PixmapCollection *pixmapCollection() const { return pixCollection; } + + void setActive( bool b ); + + QPtrListIterator sourceFiles() const { return QPtrListIterator(sourcefiles); } + void addSourceFile( SourceFile *sf ); + bool removeSourceFile( SourceFile *sf ); + SourceFile* findSourceFile( const QString& filename, SourceFile *ignore = 0 ) const; + + QPtrListIterator formFiles() const { return QPtrListIterator(formfiles); } + void addFormFile( FormFile *ff ); + bool removeFormFile( FormFile *ff ); + FormFile* findFormFile( const QString& filename, FormFile *ignore = 0 ) const; + + void setIncludePath( const QString &platform, const QString &path ); + void setLibs( const QString &platform, const QString &path ); + void setDefines( const QString &platform, const QString &path ); + void setConfig( const QString &platform, const QString &config ); + void setTemplate( const QString &t ); + + QString config( const QString &platform ) const; + QString libs( const QString &platform ) const; + QString defines( const QString &platform ) const; + QString includePath( const QString &platform ) const; + QString templte() const; + + bool isModified() const { return !isDummy() && modified; } + void setModified( bool b ); + + void addObject( QObject *o ); + void setObjects( const QObjectList &ol ); + void removeObject( QObject *o ); + QObjectList objects() const; + FormFile *fakeFormFileFor( QObject *o ) const; + QObject *objectForFakeForm( FormWindow *fw ) const; + QObject *objectForFakeFormFile( FormFile *ff ) const; + + void addAndEditFunction( const QString &functionName, const QString &functionBody, + bool openDeveloper ); + + void removeTempProject(); + bool hasParentObject( QObject *o ); + QString qualifiedName( QObject *o ); + + bool isCpp() const { return is_cpp; } + + void designerCreated(); + + void formOpened( FormWindow *fw ); + + QString locationOfObject( QObject *o ); + + bool hasGUI() const; + +signals: + void projectModified(); + void sourceFileAdded( SourceFile* ); + void sourceFileRemoved( SourceFile* ); + void formFileAdded( FormFile* ); + void formFileRemoved( FormFile* ); + void objectAdded( QObject * ); + void objectRemoved( QObject * ); + void newFormOpened( FormWindow *fw ); + +private: + void parse(); + void clear(); + void updateCustomSettings(); + void readPlatformSettings( const QString &contents, + const QString &setting, + QMap &res ); + void removePlatformSettings( QString &contents, const QString &setting ); + void writePlatformSettings( QString &contents, const QString &setting, + const QMap &input ); + bool singleProjectMode() const; + QWidget *messageBoxParent() const; + +private: + QString filename; + QString proName; + QString desc; + QString dbFile; +#ifndef QT_NO_SQL + QPtrList dbConnections; +#endif + QString lang; + DesignerProject *iface; + QMap customSettings; + QStringList csList; + QPluginManager *projectSettingsPluginManager; + PixmapCollection *pixCollection; + QPtrList sourcefiles; + QPtrList formfiles; + QMap inclPath, defs, lbs, cfg, sources, headers; + QString templ; + bool isDummyProject; + bool modified; + QObjectList objs; + QPtrDict fakeFormFiles; + QString singleProFileName; + bool is_cpp; + +}; + +#endif diff --git a/tools/designer/designer/projectsettings.ui b/tools/designer/designer/projectsettings.ui new file mode 100644 index 0000000..9e3f4bd --- /dev/null +++ b/tools/designer/designer/projectsettings.ui @@ -0,0 +1,308 @@ + +ProjectSettingsBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + ProjectSettingsBase + + + + 0 + 0 + 375 + 224 + + + + Project Settings + + + true + + + + unnamed + + + 11 + + + 6 + + + + tabWidget + + + + tabSettings + + + &Settings + + + + unnamed + + + + TextLabel1_2 + + + &Project File: + + + editProjectFile + + + + + TextLabel1_3 + + + &Language + + + comboLanguage + + + + + buttonDatabaseFile_2 + + + ... + + + + + editDatabaseFile + + + + + TextLabel1_2_2_2 + + + &Database File: + + + editDatabaseFile + + + + + comboLanguage + + + false + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + editProjectFile + + + + + buttonProject + + + ... + + + + + + + Spacer3 + + + Vertical + + + Expanding + + + + 21 + 71 + + + + + + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + + + buttonProject + clicked() + ProjectSettingsBase + chooseProjectFile() + + + buttonOk + clicked() + ProjectSettingsBase + okClicked() + + + buttonCancel + clicked() + ProjectSettingsBase + reject() + + + buttonHelp + clicked() + ProjectSettingsBase + helpClicked() + + + comboLanguage + activated(const QString&) + ProjectSettingsBase + languageChanged(const QString&) + + + + tabWidget + editProjectFile + comboLanguage + buttonHelp + buttonOk + buttonCancel + + + chooseDatabaseFile() + chooseProjectFile() + destroy() + helpClicked() + init() + languageChanged( const QString & ) + okClicked() + + + diff --git a/tools/designer/designer/projectsettingsimpl.cpp b/tools/designer/designer/projectsettingsimpl.cpp new file mode 100644 index 0000000..65d8a4b --- /dev/null +++ b/tools/designer/designer/projectsettingsimpl.cpp @@ -0,0 +1,132 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "projectsettingsimpl.h" +#include "project.h" +#include "formwindow.h" +#include "metadatabase.h" +#include "mainwindow.h" +#include "asciivalidator.h" +#include "mainwindow.h" +#include "sourcefile.h" +#include "workspace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a ProjectSettings which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +ProjectSettings::ProjectSettings( Project *pro, QWidget* parent, const char* name, bool modal, WFlags fl ) + : ProjectSettingsBase( parent, name, modal, fl ), project( pro ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + + editProjectFile->setFocus(); + + if ( project->isDummy() ) { + editProjectFile->setEnabled( FALSE ); + editProjectFile->setText( project->projectName() ); + } else { + if ( project->fileName().isEmpty() || project->fileName() == ".pro" ) { + editProjectFile->setText( tr( "unnamed.pro" ) ); + editProjectFile->selectAll(); + } else { + editProjectFile->setText( project->fileName() ); + } + } + + editDatabaseFile->setText( project->databaseDescription() ); + + comboLanguage->insertStringList( MetaDataBase::languages() ); + for ( int j = 0; j < (int)comboLanguage->count(); ++j ) { + if ( project->language() == comboLanguage->text( j ) ) { + comboLanguage->setCurrentItem( j ); + break; + } + } +} + +/* + * Destroys the object and frees any allocated resources + */ +ProjectSettings::~ProjectSettings() +{ +} + +void ProjectSettings::chooseDatabaseFile() +{ + QString fn = QFileDialog::getSaveFileName(editDatabaseFile->text(), tr("Database Files (*.db);;All Files (*)"), + this); + if ( fn.isEmpty() ) + return; + editDatabaseFile->setText( fn ); +} + +void ProjectSettings::chooseProjectFile() +{ + QString fn = QFileDialog::getSaveFileName(editProjectFile->text(), tr("Project Files (*.pro);;All Files (*)"), + this); + if ( fn.isEmpty() ) + return; + editProjectFile->setText( fn ); +} + +void ProjectSettings::helpClicked() +{ +} + +void ProjectSettings::okClicked() +{ + // ### check for validity + project->setFileName( editProjectFile->text(), FALSE ); + project->setDatabaseDescription( editDatabaseFile->text() ); + project->setLanguage( comboLanguage->text( comboLanguage->currentItem() ) ); + project->setModified( TRUE ); + accept(); +} + +void ProjectSettings::languageChanged( const QString & ) +{ +} diff --git a/tools/designer/designer/projectsettingsimpl.h b/tools/designer/designer/projectsettingsimpl.h new file mode 100644 index 0000000..1d1462e --- /dev/null +++ b/tools/designer/designer/projectsettingsimpl.h @@ -0,0 +1,63 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PROJECTSETTINGSIMPL_H +#define PROJECTSETTINGSIMPL_H + +#include "projectsettings.h" + +class Project; +class QListViewItem; +class FormWindow; +class SourceFile; + +class ProjectSettings : public ProjectSettingsBase +{ + Q_OBJECT + +public: + ProjectSettings( Project *pro, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~ProjectSettings(); + +protected slots: + void chooseDatabaseFile(); + void chooseProjectFile(); + void helpClicked(); + void okClicked(); + void languageChanged( const QString &lang ); + +private: + Project *project; +}; + +#endif diff --git a/tools/designer/designer/propertyeditor.cpp b/tools/designer/designer/propertyeditor.cpp new file mode 100644 index 0000000..708f779 --- /dev/null +++ b/tools/designer/designer/propertyeditor.cpp @@ -0,0 +1,4308 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include // HP-UX compiler needs this here + +#include "propertyeditor.h" +#include "formwindow.h" +#include "command.h" +#include "metadatabase.h" +#include "propertyobject.h" +#include +#include "widgetfactory.h" +#include "globaldefs.h" +#include "defs.h" +#include "asciivalidator.h" +#include "paletteeditorimpl.h" +#include "multilineeditorimpl.h" +#include "mainwindow.h" +#include "project.h" +#include "hierarchyview.h" +#include "database.h" +#include "menubareditor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // FIXME: obsolete +#include +#include +#include + +#include + +static QFontDatabase *fontDataBase = 0; +QString assistantPath(); + +#ifdef Q_WS_MAC +#include +static void setupStyle(QWidget *w) +{ + static QStyle *windowsStyle = 0; + if(!windowsStyle) + windowsStyle = new QWindowsStyle; + w->setStyle(windowsStyle); +} +#else +#define setupStyle(x) +#endif + +static void cleanupFontDatabase() +{ + delete fontDataBase; + fontDataBase = 0; +} + +static QStringList getFontList() +{ + if ( !fontDataBase ) { + fontDataBase = new QFontDatabase; + qAddPostRoutine( cleanupFontDatabase ); + } + return fontDataBase->families(); +} + + +class PropertyWhatsThis : public QWhatsThis +{ +public: + PropertyWhatsThis( PropertyList *l ); + QString text( const QPoint &pos ); + bool clicked( const QString& href ); + +private: + PropertyList *propertyList; + +}; + +PropertyWhatsThis::PropertyWhatsThis( PropertyList *l ) + : QWhatsThis( l->viewport() ), propertyList( l ) +{ +} + +QString PropertyWhatsThis::text( const QPoint &pos ) +{ + return propertyList->whatsThisAt( pos ); +} + +bool PropertyWhatsThis::clicked( const QString& href ) +{ + if ( !href.isEmpty() ) { + QAssistantClient *ac = MainWindow::self->assistantClient(); + ac->showPage( QString( qInstallPathDocs() ) + "/html/" + href ); + } + return FALSE; // do not hide window +} + + +/*! + \class PropertyItem propertyeditor.h + \brief Base class for all property items + + This is the base class for each property item for the + PropertyList. A simple property item has just a name and a value to + provide an editor for a datatype. But more complex datatypes might + provide an expandable item for editing single parts of the + datatype. See hasSubItems(), initChildren() for that. +*/ + +/*! If this item should be a child of another property item, specify + \a prop as the parent item. +*/ + +PropertyItem::PropertyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : QListViewItem( l, after ), listview( l ), property( prop ), propertyName( propName ) +{ + setSelectable( FALSE ); + open = FALSE; + setText( 0, propertyName ); + changed = FALSE; + setText( 1, "" ); + resetButton = 0; +} + +PropertyItem::~PropertyItem() +{ + if ( resetButton ) + delete resetButton->parentWidget(); + resetButton = 0; +} + +void PropertyItem::toggle() +{ +} + +void PropertyItem::updateBackColor() +{ + if ( itemAbove() && this != listview->firstChild() ) { + if ( ( ( PropertyItem*)itemAbove() )->backColor == *backColor1 ) + backColor = *backColor2; + else + backColor = *backColor1; + } else { + backColor = *backColor1; + } + if ( listview->firstChild() == this ) + backColor = *backColor1; +} + +QColor PropertyItem::backgroundColor() +{ + updateBackColor(); + if ( (QListViewItem*)this == listview->currentItem() ) + return *selectedBack; + return backColor; +} + +/*! If a subclass is a expandable item, this is called when the child +items should be created. +*/ + +void PropertyItem::createChildren() +{ +} + +/*! If a subclass is a expandable item, this is called when the child +items should be initialized. +*/ + +void PropertyItem::initChildren() +{ +} + +void PropertyItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Base, backgroundColor() ); + g.setColor( QColorGroup::Foreground, Qt::black ); + g.setColor( QColorGroup::Text, Qt::black ); + int indent = 0; + if ( column == 0 ) { + indent = 20 + ( property ? 20 : 0 ); + p->fillRect( 0, 0, width, height(), backgroundColor() ); + p->save(); + p->translate( indent, 0 ); + } + + if ( isChanged() && column == 0 ) { + p->save(); + QFont f = p->font(); + f.setBold( TRUE ); + p->setFont( f ); + } + + if ( !hasCustomContents() || column != 1 ) { + QListViewItem::paintCell( p, g, column, width - indent, align ); + } else { + p->fillRect( 0, 0, width, height(), backgroundColor() ); + drawCustomContents( p, QRect( 0, 0, width, height() ) ); + } + + if ( isChanged() && column == 0 ) + p->restore(); + if ( column == 0 ) + p->restore(); + if ( hasSubItems() && column == 0 ) { + p->save(); + p->setPen( cg.foreground() ); + p->setBrush( cg.base() ); + p->drawRect( 5, height() / 2 - 4, 9, 9 ); + p->drawLine( 7, height() / 2, 11, height() / 2 ); + if ( !isOpen() ) + p->drawLine( 9, height() / 2 - 2, 9, height() / 2 + 2 ); + p->restore(); + } + p->save(); + p->setPen( QPen( cg.dark(), 1 ) ); + p->drawLine( 0, height() - 1, width, height() - 1 ); + p->drawLine( width - 1, 0, width - 1, height() ); + p->restore(); + + if ( listview->currentItem() == this && column == 0 && + !listview->hasFocus() && !listview->viewport()->hasFocus() ) + paintFocus( p, cg, QRect( 0, 0, width, height() ) ); +} + +void PropertyItem::paintBranches( QPainter * p, const QColorGroup & cg, + int w, int y, int h ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Base, backgroundColor() ); + QListViewItem::paintBranches( p, g, w, y, h ); +} + +void PropertyItem::paintFocus( QPainter *p, const QColorGroup &cg, const QRect &r ) +{ + p->save(); + QApplication::style().drawPrimitive(QStyle::PE_Panel, p, r, cg, + QStyle::Style_Sunken, QStyleOption(1,1) ); + p->restore(); +} + +/*! Subclasses which are expandable items have to return TRUE + here. Default is FALSE. +*/ + +bool PropertyItem::hasSubItems() const +{ + return FALSE; +} + +/*! Returns the parent property item here if this is a child or 0 + otherwise. + */ + +PropertyItem *PropertyItem::propertyParent() const +{ + return property; +} + +bool PropertyItem::isOpen() const +{ + return open; +} + +void PropertyItem::setOpen( bool b ) +{ + if ( b == open ) + return; + open = b; + + if ( !open ) { + children.setAutoDelete( TRUE ); + children.clear(); + children.setAutoDelete( FALSE ); + qApp->processEvents(); + listview->updateEditorSize(); + return; + } + + createChildren(); + initChildren(); + qApp->processEvents(); + listview->updateEditorSize(); +} + +/*! Subclasses have to show the editor of the item here +*/ + +void PropertyItem::showEditor() +{ + createResetButton(); + resetButton->parentWidget()->show(); +} + +/*! Subclasses have to hide the editor of the item here +*/ + +void PropertyItem::hideEditor() +{ + createResetButton(); + resetButton->parentWidget()->hide(); +} + +/*! This is called to init the value of the item. Reimplement in + subclasses to init the editor +*/ + +void PropertyItem::setValue( const QVariant &v ) +{ + val = v; +} + +QVariant PropertyItem::value() const +{ + return val; +} + +bool PropertyItem::isChanged() const +{ + return changed; +} + +void PropertyItem::setChanged( bool b, bool updateDb ) +{ + if ( propertyParent() ) + return; + if ( changed == b ) + return; + changed = b; + repaint(); + if ( updateDb ) { + MetaDataBase::setPropertyChanged( listview->propertyEditor()->widget(), name(), changed ); + } + updateResetButtonState(); +} + +QString PropertyItem::name() const +{ + return propertyName; +} + +void PropertyItem::createResetButton() +{ + if ( resetButton ) { + resetButton->parentWidget()->lower(); + return; + } + QHBox *hbox = new QHBox( listview->viewport() ); + hbox->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + hbox->setLineWidth( 1 ); + resetButton = new QPushButton( hbox ); + setupStyle( resetButton ); + resetButton->setPixmap( QPixmap::fromMimeSource( "designer_resetproperty.png" ) ); + resetButton->setFixedWidth( resetButton->sizeHint().width() ); + hbox->layout()->setAlignment( Qt::AlignRight ); + listview->addChild( hbox ); + hbox->hide(); + QObject::connect( resetButton, SIGNAL( clicked() ), + listview, SLOT( resetProperty() ) ); + QToolTip::add( resetButton, PropertyEditor::tr( "Reset the property to its default value" ) ); + QWhatsThis::add( resetButton, PropertyEditor::tr( "Click this button to reset the property to its default value" ) ); + updateResetButtonState(); +} + +void PropertyItem::updateResetButtonState() +{ + if ( !resetButton ) + return; + if ( propertyParent() || !WidgetFactory::canResetProperty( listview->propertyEditor()->widget(), name() ) ) + resetButton->setEnabled( FALSE ); + else + resetButton->setEnabled( isChanged() ); +} + +/*! Call this to place/resize the item editor correctly (normally + call it from showEditor()) +*/ + +void PropertyItem::placeEditor( QWidget *w ) +{ + createResetButton(); + QRect r = listview->itemRect( this ); + if ( !r.size().isValid() ) { + listview->ensureItemVisible( this ); +#if defined(Q_WS_WIN) + listview->repaintContents( FALSE ); +#endif + r = listview->itemRect( this ); + } + r.setX( listview->header()->sectionPos( 1 ) ); + r.setWidth( listview->header()->sectionSize( 1 ) - 1 ); + r.setWidth( r.width() - resetButton->width() - 2 ); + r = QRect( listview->viewportToContents( r.topLeft() ), r.size() ); + w->resize( r.size() ); + listview->moveChild( w, r.x(), r.y() ); + resetButton->parentWidget()->resize( resetButton->sizeHint().width() + 10, r.height() ); + listview->moveChild( resetButton->parentWidget(), r.x() + r.width() - 8, r.y() ); + resetButton->setFixedHeight( QMAX( 0, r.height() - 3 ) ); +} + +/*! This should be called by subclasses if the user changed the value + of the property and this value should be applied to the widget property +*/ + +void PropertyItem::notifyValueChange() +{ + if ( !propertyParent() ) { + listview->valueChanged( this ); + setChanged( TRUE ); + if ( hasSubItems() ) + initChildren(); + } else { + propertyParent()->childValueChanged( this ); + setChanged( TRUE ); + } +} + +/*! If a subclass is a expandable item reimplement this as this is + always called if a child item changed its value. So update the + display of the item here then. +*/ + +void PropertyItem::childValueChanged( PropertyItem * ) +{ +} + +/*! When adding a child item, call this (normally from addChildren() +*/ + +void PropertyItem::addChild( PropertyItem *i ) +{ + children.append( i ); +} + +int PropertyItem::childCount() const +{ + return children.count(); +} + +PropertyItem *PropertyItem::child( int i ) const +{ + // ARRRRRRRRG + return ( (PropertyItem*)this )->children.at( i ); +} + +/*! If the contents of the item is not displayable with a text, but + you want to draw it yourself (using drawCustomContents()), return + TRUE here. +*/ + +bool PropertyItem::hasCustomContents() const +{ + return FALSE; +} + +/*! + \sa hasCustomContents() +*/ + +void PropertyItem::drawCustomContents( QPainter *, const QRect & ) +{ +} + +QString PropertyItem::currentItem() const +{ + return QString::null; +} + +int PropertyItem::currentIntItem() const +{ + return -1; +} + +void PropertyItem::setCurrentItem( const QString & ) +{ +} + +void PropertyItem::setCurrentItem( int ) +{ +} + +int PropertyItem::currentIntItemFromObject() const +{ + return -1; +} + +QString PropertyItem::currentItemFromObject() const +{ + return QString::null; +} + +void PropertyItem::setFocus( QWidget *w ) +{ + if ( !qApp->focusWidget() || + listview->propertyEditor()->formWindow() && + ( !MainWindow::self->isAFormWindowChild( qApp->focusWidget() ) && + !qApp->focusWidget()->inherits( "Editor" ) ) ) + w->setFocus(); +} + +void PropertyItem::setText( int col, const QString &t ) +{ + QString txt( t ); + if ( col == 1 ) + txt = txt.replace( "\n", " " ); + QListViewItem::setText( col, txt ); +} + +// -------------------------------------------------------------- + +PropertyTextItem::PropertyTextItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool comment, bool multiLine, bool ascii, bool a ) + : PropertyItem( l, after, prop, propName ), withComment( comment ), + hasMultiLines( multiLine ), asciiOnly( ascii ), accel( a ) +{ + lin = 0; + box = 0; +} + +QLineEdit *PropertyTextItem::lined() +{ + if ( lin ) + return lin; + if ( hasMultiLines ) { + box = new QHBox( listview->viewport() ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + box->hide(); + } + + lin = 0; + if ( hasMultiLines ) + lin = new QLineEdit( box ); + else + lin = new QLineEdit( listview->viewport() ); + + if ( asciiOnly ) { + if ( PropertyItem::name() == "name" ) { + lin->setValidator( new AsciiValidator( QString(":"), lin, "ascii_validator" ) ); + if ( listview->propertyEditor()->formWindow()->isFake() ) + lin->setEnabled( FALSE ); + } else { + lin->setValidator( new AsciiValidator( QString("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9" + "\xaa\xab\xac\xad\xae\xaf\xb1\xb2\xb3" + "\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc" + "\xbd\xbe\xbf"), lin, "ascii_validator" ) ); + } + } if ( !hasMultiLines ) { + lin->hide(); + } else { + button = new QPushButton( tr("..."), box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getText() ) ); + lin->setFrame( FALSE ); + } + connect( lin, SIGNAL( returnPressed() ), + this, SLOT( setValue() ) ); + connect( lin, SIGNAL( textChanged( const QString & ) ), + this, SLOT( setValue() ) ); + if ( PropertyItem::name() == "name" || PropertyItem::name() == "itemName" ) + connect( lin, SIGNAL( returnPressed() ), + listview->propertyEditor()->formWindow()->commandHistory(), + SLOT( checkCompressedCommand() ) ); + lin->installEventFilter( listview ); + return lin; +} + +PropertyTextItem::~PropertyTextItem() +{ + delete (QLineEdit*)lin; + lin = 0; + delete (QHBox*)box; + box = 0; +} + +void PropertyTextItem::setChanged( bool b, bool updateDb ) +{ + PropertyItem::setChanged( b, updateDb ); + if ( withComment && childCount() > 0 ) + ( (PropertyTextItem*)PropertyItem::child( 0 ) )->lined()->setEnabled( b ); +} + +bool PropertyTextItem::hasSubItems() const +{ + return withComment; +} + +void PropertyTextItem::childValueChanged( PropertyItem *child ) +{ + if ( PropertyItem::name() != "name" ) + MetaDataBase::setPropertyComment( listview->propertyEditor()->widget(), + PropertyItem::name(), child->value().toString() ); + else + MetaDataBase::setExportMacro( listview->propertyEditor()->widget(), child->value().toString() ); + listview->propertyEditor()->formWindow()->commandHistory()->setModified( TRUE ); +} + +void PropertyTextItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin || lin->text().length() == 0 ) { + lined()->blockSignals( TRUE ); + lined()->setText( value().toString() ); + lined()->blockSignals( FALSE ); + } + + QWidget* w; + if ( hasMultiLines ) + w = box; + else + w= lined(); + + placeEditor( w ); + if ( !w->isVisible() || !lined()->hasFocus() ) { + w->show(); + setFocus( lined() ); + } +} + +void PropertyTextItem::createChildren() +{ + PropertyTextItem *i = new PropertyTextItem( listview, this, this, + PropertyItem::name() == "name" ? + "export macro" : "comment", FALSE, FALSE, + PropertyItem::name() == "name" ); + i->lined()->setEnabled( isChanged() ); + addChild( i ); +} + +void PropertyTextItem::initChildren() +{ + if ( !childCount() ) + return; + PropertyItem *item = PropertyItem::child( 0 ); + if ( item ) { + if ( PropertyItem::name() != "name" ) + item->setValue( MetaDataBase::propertyComment( listview->propertyEditor()->widget(), + PropertyItem::name() ) ); + else + item->setValue( MetaDataBase::exportMacro( listview->propertyEditor()->widget() ) ); + } +} + +void PropertyTextItem::hideEditor() +{ + PropertyItem::hideEditor(); + QWidget* w; + if ( hasMultiLines ) + w = box; + else + w = lined(); + + w->hide(); +} + +void PropertyTextItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + if ( lin ) { + lined()->blockSignals( TRUE ); + int oldCursorPos; + oldCursorPos = lin->cursorPosition(); + lined()->setText( v.toString() ); + if ( oldCursorPos < (int)lin->text().length() ) + lin->setCursorPosition( oldCursorPos ); + lined()->blockSignals( FALSE ); + } + setText( 1, v.toString() ); + PropertyItem::setValue( v ); +} + +void PropertyTextItem::setValue() +{ + setText( 1, lined()->text() ); + QVariant v; + if ( accel ) { + v = QVariant( QKeySequence( lined()->text() ) ); + if ( v.toString().isNull() ) + return; // not yet valid input + } else { + v = lined()->text(); + } + PropertyItem::setValue( v ); + notifyValueChange(); +} + +void PropertyTextItem::getText() +{ + bool richText = !::qt_cast(listview->propertyEditor()->widget()) || + ( text( 0 ) == "whatsThis" ); + bool doWrap = FALSE; + QString txt = MultiLineEditor::getText( listview, value().toString(), richText, &doWrap ); + if ( !txt.isEmpty() ) { + setText( 1, txt ); + PropertyItem::setValue( txt ); + notifyValueChange(); + lined()->blockSignals( TRUE ); + lined()->setText( txt ); + lined()->blockSignals( FALSE ); + } +} + +// -------------------------------------------------------------- + +PropertyDoubleItem::PropertyDoubleItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QLineEdit *PropertyDoubleItem::lined() +{ + if ( lin ) + return lin; + lin = new QLineEdit( listview->viewport() ); + lin->setValidator( new QDoubleValidator( lin, "double_validator" ) ); + + connect( lin, SIGNAL( returnPressed() ), + this, SLOT( setValue() ) ); + connect( lin, SIGNAL( textChanged( const QString & ) ), + this, SLOT( setValue() ) ); + lin->installEventFilter( listview ); + return lin; +} + +PropertyDoubleItem::~PropertyDoubleItem() +{ + delete (QLineEdit*)lin; + lin = 0; +} + +void PropertyDoubleItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) { + lined()->blockSignals( TRUE ); + lined()->setText( QString::number( value().toDouble() ) ); + lined()->blockSignals( FALSE ); + } + QWidget* w = lined(); + + placeEditor( w ); + if ( !w->isVisible() || !lined()->hasFocus() ) { + w->show(); + setFocus( lined() ); + } +} + + +void PropertyDoubleItem::hideEditor() +{ + PropertyItem::hideEditor(); + QWidget* w = lined(); + w->hide(); +} + +void PropertyDoubleItem::setValue( const QVariant &v ) +{ + if ( value() == v ) + return; + if ( lin ) { + lined()->blockSignals( TRUE ); + int oldCursorPos; + oldCursorPos = lin->cursorPosition(); + lined()->setText( QString::number( v.toDouble() ) ); + if ( oldCursorPos < (int)lin->text().length() ) + lin->setCursorPosition( oldCursorPos ); + lined()->blockSignals( FALSE ); + } + setText( 1, QString::number( v.toDouble() ) ); + PropertyItem::setValue( v ); +} + +void PropertyDoubleItem::setValue() +{ + setText( 1, lined()->text() ); + QVariant v = lined()->text().toDouble(); + PropertyItem::setValue( v ); + notifyValueChange(); +} + + +// -------------------------------------------------------------- + +PropertyDateItem::PropertyDateItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QDateEdit *PropertyDateItem::lined() +{ + if ( lin ) + return lin; + lin = new QDateEdit( listview->viewport() ); + QObjectList *l = lin->queryList( "QLineEdit" ); + for ( QObject *o = l->first(); o; o = l->next() ) + o->installEventFilter( listview ); + delete l; + connect( lin, SIGNAL( valueChanged( const QDate & ) ), + this, SLOT( setValue() ) ); + return lin; +} + +PropertyDateItem::~PropertyDateItem() +{ + delete (QDateEdit*)lin; + lin = 0; +} + +void PropertyDateItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) { + lined()->blockSignals( TRUE ); + lined()->setDate( value().toDate() ); + lined()->blockSignals( FALSE ); + } + placeEditor( lin ); + if ( !lin->isVisible() ) { + lin->show(); + setFocus( lin ); + } +} + +void PropertyDateItem::hideEditor() +{ + PropertyItem::hideEditor(); + if ( lin ) + lin->hide(); +} + +void PropertyDateItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( lin ) { + lined()->blockSignals( TRUE ); + if ( lined()->date() != v.toDate() ) + lined()->setDate( v.toDate() ); + lined()->blockSignals( FALSE ); + } + setText( 1, v.toDate().toString( ::Qt::ISODate ) ); + PropertyItem::setValue( v ); +} + +void PropertyDateItem::setValue() +{ + setText( 1, lined()->date().toString( ::Qt::ISODate ) ); + QVariant v; + v = lined()->date(); + PropertyItem::setValue( v ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyTimeItem::PropertyTimeItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QTimeEdit *PropertyTimeItem::lined() +{ + if ( lin ) + return lin; + lin = new QTimeEdit( listview->viewport() ); + connect( lin, SIGNAL( valueChanged( const QTime & ) ), + this, SLOT( setValue() ) ); + QObjectList *l = lin->queryList( "QLineEdit" ); + for ( QObject *o = l->first(); o; o = l->next() ) + o->installEventFilter( listview ); + delete l; + return lin; +} + +PropertyTimeItem::~PropertyTimeItem() +{ + delete (QTimeEdit*)lin; + lin = 0; +} + +void PropertyTimeItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) { + lined()->blockSignals( TRUE ); + lined()->setTime( value().toTime() ); + lined()->blockSignals( FALSE ); + } + placeEditor( lin ); + if ( !lin->isVisible() ) { + lin->show(); + setFocus( lin ); + } +} + +void PropertyTimeItem::hideEditor() +{ + PropertyItem::hideEditor(); + if ( lin ) + lin->hide(); +} + +void PropertyTimeItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( lin ) { + lined()->blockSignals( TRUE ); + if ( lined()->time() != v.toTime() ) + lined()->setTime( v.toTime() ); + lined()->blockSignals( FALSE ); + } + setText( 1, v.toTime().toString( ::Qt::ISODate ) ); + PropertyItem::setValue( v ); +} + +void PropertyTimeItem::setValue() +{ + setText( 1, lined()->time().toString( ::Qt::ISODate ) ); + QVariant v; + v = lined()->time(); + PropertyItem::setValue( v ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyDateTimeItem::PropertyDateTimeItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QDateTimeEdit *PropertyDateTimeItem::lined() +{ + if ( lin ) + return lin; + lin = new QDateTimeEdit( listview->viewport() ); + connect( lin, SIGNAL( valueChanged( const QDateTime & ) ), + this, SLOT( setValue() ) ); + QObjectList *l = lin->queryList( "QLineEdit" ); + for ( QObject *o = l->first(); o; o = l->next() ) + o->installEventFilter( listview ); + delete l; + return lin; +} + +PropertyDateTimeItem::~PropertyDateTimeItem() +{ + delete (QDateTimeEdit*)lin; + lin = 0; +} + +void PropertyDateTimeItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) { + lined()->blockSignals( TRUE ); + lined()->setDateTime( value().toDateTime() ); + lined()->blockSignals( FALSE ); + } + placeEditor( lin ); + if ( !lin->isVisible() ) { + lin->show(); + setFocus( lin ); + } +} + +void PropertyDateTimeItem::hideEditor() +{ + PropertyItem::hideEditor(); + if ( lin ) + lin->hide(); +} + +void PropertyDateTimeItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( lin ) { + lined()->blockSignals( TRUE ); + if ( lined()->dateTime() != v.toDateTime() ) + lined()->setDateTime( v.toDateTime() ); + lined()->blockSignals( FALSE ); + } + setText( 1, v.toDateTime().toString( ::Qt::ISODate ) ); + PropertyItem::setValue( v ); +} + +void PropertyDateTimeItem::setValue() +{ + setText( 1, lined()->dateTime().toString( ::Qt::ISODate ) ); + QVariant v; + v = lined()->dateTime(); + PropertyItem::setValue( v ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyBoolItem::PropertyBoolItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + comb = 0; +} + +QComboBox *PropertyBoolItem::combo() +{ + if ( comb ) + return comb; + comb = new QComboBox( FALSE, listview->viewport() ); + comb->hide(); + comb->insertItem( tr( "False" ) ); + comb->insertItem( tr( "True" ) ); + connect( comb, SIGNAL( activated( int ) ), + this, SLOT( setValue() ) ); + comb->installEventFilter( listview ); + return comb; +} + +PropertyBoolItem::~PropertyBoolItem() +{ + delete (QComboBox*)comb; + comb = 0; +} + +void PropertyBoolItem::toggle() +{ + bool b = value().toBool(); + setValue( QVariant( !b, 0 ) ); + setValue(); +} + +void PropertyBoolItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !comb ) { + combo()->blockSignals( TRUE ); + if ( value().toBool() ) + combo()->setCurrentItem( 1 ); + else + combo()->setCurrentItem( 0 ); + combo()->blockSignals( FALSE ); + } + placeEditor( combo() ); + if ( !combo()->isVisible() || !combo()->hasFocus() ) { + combo()->show(); + setFocus( combo() ); + } +} + +void PropertyBoolItem::hideEditor() +{ + PropertyItem::hideEditor(); + combo()->hide(); +} + +void PropertyBoolItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( comb ) { + combo()->blockSignals( TRUE ); + if ( v.toBool() ) + combo()->setCurrentItem( 1 ); + else + combo()->setCurrentItem( 0 ); + combo()->blockSignals( FALSE ); + } + QString tmp = tr( "True" ); + if ( !v.toBool() ) + tmp = tr( "False" ); + setText( 1, tmp ); + PropertyItem::setValue( v ); +} + +void PropertyBoolItem::setValue() +{ + if ( !comb ) + return; + setText( 1, combo()->currentText() ); + bool b = combo()->currentItem() == 0 ? (bool)FALSE : (bool)TRUE; + PropertyItem::setValue( QVariant( b, 0 ) ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyIntItem::PropertyIntItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool s ) + : PropertyItem( l, after, prop, propName ), signedValue( s ) +{ + spinBx = 0; +} + +QSpinBox *PropertyIntItem::spinBox() +{ + if ( spinBx ) + return spinBx; + if ( signedValue ) + spinBx = new QSpinBox( -INT_MAX, INT_MAX, 1, listview->viewport() ); + else + spinBx = new QSpinBox( 0, INT_MAX, 1, listview->viewport() ); + spinBx->hide(); + spinBx->installEventFilter( listview ); + QObjectList *ol = spinBx->queryList( "QLineEdit" ); + if ( ol && ol->first() ) + ol->first()->installEventFilter( listview ); + delete ol; + connect( spinBx, SIGNAL( valueChanged( int ) ), + this, SLOT( setValue() ) ); + return spinBx; +} + +PropertyIntItem::~PropertyIntItem() +{ + delete (QSpinBox*)spinBx; + spinBx = 0; +} + +void PropertyIntItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !spinBx ) { + spinBox()->blockSignals( TRUE ); + if ( signedValue ) + spinBox()->setValue( value().toInt() ); + else + spinBox()->setValue( value().toUInt() ); + spinBox()->blockSignals( FALSE ); + } + placeEditor( spinBox() ); + if ( !spinBox()->isVisible() || !spinBox()->hasFocus() ) { + spinBox()->show(); + setFocus( spinBox() ); + } +} + +void PropertyIntItem::hideEditor() +{ + PropertyItem::hideEditor(); + spinBox()->hide(); +} + +void PropertyIntItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + if ( spinBx ) { + spinBox()->blockSignals( TRUE ); + if ( signedValue ) + spinBox()->setValue( v.toInt() ); + else + spinBox()->setValue( v.toUInt() ); + spinBox()->blockSignals( FALSE ); + } + + if ( signedValue ) + setText( 1, QString::number( v.toInt() ) ); + else + setText( 1, QString::number( v.toUInt() ) ); + PropertyItem::setValue( v ); +} + +void PropertyIntItem::setValue() +{ + if ( !spinBx ) + return; + setText( 1, QString::number( spinBox()->value() ) ); + if ( signedValue ) + PropertyItem::setValue( spinBox()->value() ); + else + PropertyItem::setValue( (uint)spinBox()->value() ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyLayoutItem::PropertyLayoutItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + spinBx = 0; +} + +PropertyLayoutItem::~PropertyLayoutItem() +{ + delete (QSpinBox*)spinBx; + spinBx = 0; +} + +QSpinBox* PropertyLayoutItem::spinBox() +{ + if ( spinBx ) + return spinBx; + spinBx = new QSpinBox( -1, INT_MAX, 1, listview->viewport() ); + spinBx->setSpecialValueText( tr( "default" ) ); + spinBx->hide(); + spinBx->installEventFilter( listview ); + QObjectList *ol = spinBx->queryList( "QLineEdit" ); + if ( ol && ol->first() ) + ol->first()->installEventFilter( listview ); + delete ol; + connect( spinBx, SIGNAL( valueChanged( int ) ), + this, SLOT( setValue() ) ); + return spinBx; +} + +void PropertyLayoutItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !spinBx ) { + spinBox()->blockSignals( TRUE ); + spinBox()->setValue( value().toInt() ); + spinBox()->blockSignals( TRUE ); + } + placeEditor( spinBox() ); + if ( !spinBox()->isVisible() || !spinBox()->hasFocus() ) { + spinBox()->show(); + setFocus( spinBox() ); + } +} + +void PropertyLayoutItem::hideEditor() +{ + PropertyItem::hideEditor(); + spinBox()->hide(); +} + +void PropertyLayoutItem::setValue( const QVariant &v ) +{ + if ( spinBx ) { + spinBox()->blockSignals( TRUE ); + spinBox()->setValue( v.toInt() ); + spinBox()->blockSignals( FALSE ); + } + QString s = v.toString(); + if ( v.toInt() == -1 ) + s = spinBox()->specialValueText(); + setText( 1, s ); + PropertyItem::setValue( v ); +} + +void PropertyLayoutItem::setValue() +{ + if ( !spinBx ) + return; + PropertyItem::setValue( spinBox()->value() ); + notifyValueChange(); +} + + +// -------------------------------------------------------------- + +PropertyListItem::PropertyListItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool e ) + : PropertyItem( l, after, prop, propName ), editable( e ) +{ + comb = 0; + oldInt = -1; +} + +QComboBox *PropertyListItem::combo() +{ + if ( comb ) + return comb; + comb = new QComboBox( editable, listview->viewport() ); + comb->hide(); + connect( comb, SIGNAL( activated( int ) ), + this, SLOT( setValue() ) ); + comb->installEventFilter( listview ); + if ( editable ) { + QObjectList *ol = comb->queryList( "QLineEdit" ); + if ( ol && ol->first() ) + ol->first()->installEventFilter( listview ); + delete ol; + } + return comb; +} + +PropertyListItem::~PropertyListItem() +{ + delete (QComboBox*)comb; + comb = 0; +} + +void PropertyListItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !comb ) { + combo()->blockSignals( TRUE ); + combo()->clear(); + combo()->insertStringList( value().toStringList() ); + combo()->blockSignals( FALSE ); + } + placeEditor( combo() ); + if ( !combo()->isVisible() || !combo()->hasFocus() ) { + combo()->show(); + setFocus( combo() ); + } +} + +void PropertyListItem::hideEditor() +{ + PropertyItem::hideEditor(); + combo()->hide(); +} + +void PropertyListItem::setValue( const QVariant &v ) +{ + if ( comb ) { + combo()->blockSignals( TRUE ); + combo()->clear(); + combo()->insertStringList( v.toStringList() ); + combo()->blockSignals( FALSE ); + } + setText( 1, v.toStringList().first() ); + PropertyItem::setValue( v ); +} + +void PropertyListItem::setValue() +{ + if ( !comb ) + return; + setText( 1, combo()->currentText() ); + QStringList lst; + for ( uint i = 0; i < combo()->listBox()->count(); ++i ) + lst << combo()->listBox()->item( i )->text(); + PropertyItem::setValue( lst ); + notifyValueChange(); + oldInt = currentIntItem(); + oldString = currentItem(); +} + +QString PropertyListItem::currentItem() const +{ + return ( (PropertyListItem*)this )->combo()->currentText(); +} + +void PropertyListItem::setCurrentItem( const QString &s ) +{ + if ( comb && currentItem().lower() == s.lower() ) + return; + + if ( !comb ) { + combo()->blockSignals( TRUE ); + combo()->clear(); + combo()->insertStringList( value().toStringList() ); + combo()->blockSignals( FALSE ); + } + for ( uint i = 0; i < combo()->listBox()->count(); ++i ) { + if ( combo()->listBox()->item( i )->text().lower() == s.lower() ) { + combo()->setCurrentItem( i ); + setText( 1, combo()->currentText() ); + break; + } + } + oldInt = currentIntItem(); + oldString = currentItem(); +} + +void PropertyListItem::addItem( const QString &s ) +{ + combo()->insertItem( s ); +} + +void PropertyListItem::setCurrentItem( int i ) +{ + if ( comb && i == combo()->currentItem() ) + return; + + if ( !comb ) { + combo()->blockSignals( TRUE ); + combo()->clear(); + combo()->insertStringList( value().toStringList() ); + combo()->blockSignals( FALSE ); + } + combo()->setCurrentItem( i ); + setText( 1, combo()->currentText() ); + oldInt = currentIntItem(); + oldString = currentItem(); +} + +int PropertyListItem::currentIntItem() const +{ + return ( (PropertyListItem*)this )->combo()->currentItem(); +} + +int PropertyListItem::currentIntItemFromObject() const +{ + return oldInt; +} + +QString PropertyListItem::currentItemFromObject() const +{ + return oldString; +} + +// -------------------------------------------------------------- + +PropertyCoordItem::PropertyCoordItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, Type t ) + : PropertyItem( l, after, prop, propName ), typ( t ) +{ + lin = 0; + +} + +QLineEdit *PropertyCoordItem::lined() +{ + if ( lin ) + return lin; + lin = new QLineEdit( listview->viewport() ); + lin->setReadOnly( TRUE ); + lin->installEventFilter( listview ); + lin->hide(); + return lin; +} + +void PropertyCoordItem::createChildren() +{ + PropertyItem *i = this; + if ( typ == Rect || typ == Point ) { + i = new PropertyIntItem( listview, i, this, tr( "x" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, tr( "y" ), TRUE ); + addChild( i ); + } + if ( typ == Rect || typ == Size ) { + i = new PropertyIntItem( listview, i, this, tr( "width" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, tr( "height" ), TRUE ); + addChild( i ); + } +} + +void PropertyCoordItem::initChildren() +{ + PropertyItem *item = 0; + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == tr( "x" ) ) { + if ( typ == Rect ) + item->setValue( val.toRect().x() ); + else if ( typ == Point ) + item->setValue( val.toPoint().x() ); + } else if ( item->name() == tr( "y" ) ) { + if ( typ == Rect ) + item->setValue( val.toRect().y() ); + else if ( typ == Point ) + item->setValue( val.toPoint().y() ); + } else if ( item->name() == tr( "width" ) ) { + if ( typ == Rect ) + item->setValue( val.toRect().width() ); + else if ( typ == Size ) + item->setValue( val.toSize().width() ); + } else if ( item->name() == tr( "height" ) ) { + if ( typ == Rect ) + item->setValue( val.toRect().height() ); + else if ( typ == Size ) + item->setValue( val.toSize().height() ); + } + } +} + +PropertyCoordItem::~PropertyCoordItem() +{ + delete (QLineEdit*)lin; + lin = 0; +} + +void PropertyCoordItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !lin ) + lined()->setText( text( 1 ) ); + placeEditor( lined() ); + if ( !lined()->isVisible() || !lined()->hasFocus() ) { + lined()->show(); + setFocus( lined() ); + } +} + +void PropertyCoordItem::hideEditor() +{ + PropertyItem::hideEditor(); + lined()->hide(); +} + +void PropertyCoordItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + QString s; + if ( typ == Rect ) + s = "[ " + QString::number( v.toRect().x() ) + ", " + QString::number( v.toRect().y() ) + ", " + + QString::number( v.toRect().width() ) + ", " + QString::number( v.toRect().height() ) + " ]"; + else if ( typ == Point ) + s = "[ " + QString::number( v.toPoint().x() ) + ", " + + QString::number( v.toPoint().y() ) + " ]"; + else if ( typ == Size ) + s = "[ " + QString::number( v.toSize().width() ) + ", " + + QString::number( v.toSize().height() ) + " ]"; + setText( 1, s ); + if ( lin ) + lined()->setText( s ); + PropertyItem::setValue( v ); +} + +bool PropertyCoordItem::hasSubItems() const +{ + return TRUE; +} + +void PropertyCoordItem::childValueChanged( PropertyItem *child ) +{ + if ( typ == Rect ) { + QRect r = value().toRect(); + if ( child->name() == tr( "x" ) ) + r.moveBy( -r.x() + child->value().toInt(), 0 ); + else if ( child->name() == tr( "y" ) ) + r.moveBy( 0, -r.y() + child->value().toInt() ); + else if ( child->name() == tr( "width" ) ) + r.setWidth( child->value().toInt() ); + else if ( child->name() == tr( "height" ) ) + r.setHeight( child->value().toInt() ); + setValue( r ); + } else if ( typ == Point ) { + QPoint r = value().toPoint(); + if ( child->name() == tr( "x" ) ) + r.setX( child->value().toInt() ); + else if ( child->name() == tr( "y" ) ) + r.setY( child->value().toInt() ); + setValue( r ); + } else if ( typ == Size ) { + QSize r = value().toSize(); + if ( child->name() == tr( "width" ) ) + r.setWidth( child->value().toInt() ); + else if ( child->name() == tr( "height" ) ) + r.setHeight( child->value().toInt() ); + setValue( r ); + } + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyPixmapItem::PropertyPixmapItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, Type t ) + : PropertyItem( l, after, prop, propName ), type( t ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + pixPrev = new QLabel( box ); + pixPrev->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Minimum ) ); + pixPrev->setBackgroundColor( pixPrev->colorGroup().color( QColorGroup::Base ) ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + pixPrev->setFrameStyle( QFrame::NoFrame ); + box->installEventFilter( listview ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getPixmap() ) ); +} + +PropertyPixmapItem::~PropertyPixmapItem() +{ + delete (QHBox*)box; +} + +void PropertyPixmapItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + listView()->viewport()->setFocus(); + } +} + +void PropertyPixmapItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyPixmapItem::setValue( const QVariant &v ) +{ + QString s; + if ( type == Pixmap ) + pixPrev->setPixmap( v.toPixmap() ); + else if ( type == IconSet ) + pixPrev->setPixmap( v.toIconSet().pixmap() ); + else + pixPrev->setPixmap( v.toImage() ); + PropertyItem::setValue( v ); + repaint(); +} + +void PropertyPixmapItem::getPixmap() +{ + QPixmap pix = qChoosePixmap( listview, listview->propertyEditor()->formWindow(), value().toPixmap() ); + if ( !pix.isNull() ) { + if ( type == Pixmap ) + setValue( pix ); + else if ( type == IconSet ) + setValue( QIconSet( pix ) ); + else + setValue( pix.convertToImage() ); + + notifyValueChange(); + } +} + +bool PropertyPixmapItem::hasCustomContents() const +{ + return TRUE; +} + +void PropertyPixmapItem::drawCustomContents( QPainter *p, const QRect &r ) +{ + QPixmap pix; + if ( type == Pixmap ) + pix = value().toPixmap(); + else if ( type == IconSet ) + pix = value().toIconSet().pixmap(); + else + pix = value().toImage(); + + if ( !pix.isNull() ) { + p->save(); + p->setClipRect( QRect( QPoint( (int)(p->worldMatrix().dx() + r.x()), + (int)(p->worldMatrix().dy() + r.y()) ), + r.size() ) ); + p->drawPixmap( r.x(), r.y() + ( r.height() - pix.height() ) / 2, pix ); + p->restore(); + } +} + + +// -------------------------------------------------------------- + +PropertyColorItem::PropertyColorItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool children ) + : PropertyItem( l, after, prop, propName ), withChildren( children ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + colorPrev = new QFrame( box ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + colorPrev->setFrameStyle( QFrame::Plain | QFrame::Box ); + colorPrev->setLineWidth( 2 ); + QPalette pal = colorPrev->palette(); + QColorGroup cg = pal.active(); + cg.setColor( QColorGroup::Foreground, cg.color( QColorGroup::Base ) ); + pal.setActive( cg ); + pal.setInactive( cg ); + pal.setDisabled( cg ); + colorPrev->setPalette( pal ); + box->installEventFilter( listview ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getColor() ) ); +} + +void PropertyColorItem::createChildren() +{ + PropertyItem *i = this; + i = new PropertyIntItem( listview, i, this, tr( "Red" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, tr( "Green" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, tr( "Blue" ), TRUE ); + addChild( i ); +} + +void PropertyColorItem::initChildren() +{ + PropertyItem *item = 0; + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == tr( "Red" ) ) + item->setValue( val.toColor().red() ); + else if ( item->name() == tr( "Green" ) ) + item->setValue( val.toColor().green() ); + else if ( item->name() == tr( "Blue" ) ) + item->setValue( val.toColor().blue() ); + } +} + +PropertyColorItem::~PropertyColorItem() +{ + delete (QHBox*)box; +} + +void PropertyColorItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + listView()->viewport()->setFocus(); + } +} + +void PropertyColorItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyColorItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + QString s; + setText( 1, v.toColor().name() ); + colorPrev->setBackgroundColor( v.toColor() ); + PropertyItem::setValue( v ); +} + +bool PropertyColorItem::hasSubItems() const +{ + return withChildren; +} + +void PropertyColorItem::childValueChanged( PropertyItem *child ) +{ + QColor c( val.toColor() ); + if ( child->name() == tr( "Red" ) ) + c.setRgb( child->value().toInt(), c.green(), c.blue() ); + else if ( child->name() == tr( "Green" ) ) + c.setRgb( c.red(), child->value().toInt(), c.blue() ); + else if ( child->name() == tr( "Blue" ) ) + c.setRgb( c.red(), c.green(), child->value().toInt() ); + setValue( c ); + notifyValueChange(); +} + +void PropertyColorItem::getColor() +{ + QColor c = QColorDialog::getColor( val.asColor(), listview ); + if ( c.isValid() ) { + setValue( c ); + notifyValueChange(); + } +} + +bool PropertyColorItem::hasCustomContents() const +{ + return TRUE; +} + +void PropertyColorItem::drawCustomContents( QPainter *p, const QRect &r ) +{ + p->save(); + p->setPen( QPen( black, 1 ) ); + p->setBrush( val.toColor() ); + p->drawRect( r.x() + 2, r.y() + 2, r.width() - 5, r.height() - 5 ); + p->restore(); +} + +// -------------------------------------------------------------- + +PropertyFontItem::PropertyFontItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + lined = new QLineEdit( box ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + lined->setFrame( FALSE ); + lined->setReadOnly( TRUE ); + box->setFocusProxy( lined ); + box->installEventFilter( listview ); + lined->installEventFilter( listview ); + button->installEventFilter( listview ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getFont() ) ); +} + +void PropertyFontItem::createChildren() +{ + PropertyItem *i = this; + i = new PropertyListItem( listview, i, this, tr( "Family" ), FALSE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, tr( "Point Size" ), TRUE ); + addChild( i ); + i = new PropertyBoolItem( listview, i, this, tr( "Bold" ) ); + addChild( i ); + i = new PropertyBoolItem( listview, i, this, tr( "Italic" ) ); + addChild( i ); + i = new PropertyBoolItem( listview, i, this, tr( "Underline" ) ); + addChild( i ); + i = new PropertyBoolItem( listview, i, this, tr( "Strikeout" ) ); + addChild( i ); +} + +void PropertyFontItem::initChildren() +{ + PropertyItem *item = 0; + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == tr( "Family" ) ) { + ( (PropertyListItem*)item )->setValue( getFontList() ); + ( (PropertyListItem*)item )->setCurrentItem( val.toFont().family() ); + } else if ( item->name() == tr( "Point Size" ) ) + item->setValue( val.toFont().pointSize() ); + else if ( item->name() == tr( "Bold" ) ) + item->setValue( QVariant( val.toFont().bold(), 0 ) ); + else if ( item->name() == tr( "Italic" ) ) + item->setValue( QVariant( val.toFont().italic(), 0 ) ); + else if ( item->name() == tr( "Underline" ) ) + item->setValue( QVariant( val.toFont().underline(), 0 ) ); + else if ( item->name() == tr( "Strikeout" ) ) + item->setValue( QVariant( val.toFont().strikeOut(), 0 ) ); + } +} + +PropertyFontItem::~PropertyFontItem() +{ + delete (QHBox*)box; +} + +void PropertyFontItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() || !lined->hasFocus() ) { + box->show(); + setFocus( lined ); + } +} + +void PropertyFontItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyFontItem::setValue( const QVariant &v ) +{ + if ( value() == v ) + return; + + setText( 1, v.toFont().family() + "-" + QString::number( v.toFont().pointSize() ) ); + lined->setText( v.toFont().family() + "-" + QString::number( v.toFont().pointSize() ) ); + PropertyItem::setValue( v ); +} + +void PropertyFontItem::getFont() +{ + bool ok = FALSE; + QFont f = QFontDialog::getFont( &ok, val.toFont(), listview ); + if ( ok && f != val.toFont() ) { + setValue( f ); + notifyValueChange(); + } +} + +bool PropertyFontItem::hasSubItems() const +{ + return TRUE; +} + +void PropertyFontItem::childValueChanged( PropertyItem *child ) +{ + QFont f = val.toFont(); + if ( child->name() == tr( "Family" ) ) + f.setFamily( ( (PropertyListItem*)child )->currentItem() ); + else if ( child->name() == tr( "Point Size" ) ) + f.setPointSize( child->value().toInt() ); + else if ( child->name() == tr( "Bold" ) ) + f.setBold( child->value().toBool() ); + else if ( child->name() == tr( "Italic" ) ) + f.setItalic( child->value().toBool() ); + else if ( child->name() == tr( "Underline" ) ) + f.setUnderline( child->value().toBool() ); + else if ( child->name() == tr( "Strikeout" ) ) + f.setStrikeOut( child->value().toBool() ); + setValue( f ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyDatabaseItem::PropertyDatabaseItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool wField ) + : PropertyItem( l, after, prop, propName ), withField( wField ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + lined = new QLineEdit( box ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + lined->setFrame( FALSE ); + lined->setReadOnly( TRUE ); + box->setFocusProxy( lined ); + box->installEventFilter( listview ); + lined->installEventFilter( listview ); + button->installEventFilter( listview ); +} + +void PropertyDatabaseItem::createChildren() +{ + PropertyItem *i = this; + i = new PropertyListItem( listview, i, this, tr( "Connection" ), TRUE ); + addChild( i ); + i = new PropertyListItem( listview, i, this, tr( "Table" ), TRUE ); + addChild( i ); + if ( withField ) { + i = new PropertyListItem( listview, i, this, tr( "Field" ), TRUE ); + addChild( i ); + } +} + +void PropertyDatabaseItem::initChildren() +{ +#ifndef QT_NO_SQL + PropertyItem *item = 0; + QStringList lst = value().toStringList(); + QString conn, table; + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == tr( "Connection" ) ) { + QStringList cl = listview->propertyEditor()->formWindow()->project()->databaseConnectionList(); + if ( !cl.isEmpty() ) + item->setValue( cl ); + else if ( lst.count() > 0 ) + item->setValue( QStringList( lst[ 0 ] ) ); + else if ( withField ) + item->setValue( QStringList( MetaDataBase::fakeProperty( listview->propertyEditor()->formWindow()->mainContainer(), + "database" ).toStringList()[ 0 ] ) ); + + if ( lst.count() > 0 && !lst[ 0 ].isEmpty() ) + item->setCurrentItem( lst[ 0 ] ); + else if ( !isChanged() && withField ) + item->setCurrentItem( MetaDataBase::fakeProperty( listview->propertyEditor()->formWindow()->mainContainer(), + "database" ).toStringList()[ 0 ] ); + else + item->setCurrentItem( 0 ); + conn = item->currentItem(); + } else if ( item->name() == tr( "Table" ) ) { + QStringList cl = listview->propertyEditor()->formWindow()->project()->databaseTableList( conn ); + if ( !cl.isEmpty() ) + item->setValue( cl ); + else if ( lst.count() > 1 ) + item->setValue( QStringList( lst[ 1 ] ) ); + else if ( withField ) { + QStringList fakeLst = MetaDataBase::fakeProperty( listview->propertyEditor()->formWindow()->mainContainer(), "database" ).toStringList(); + if ( fakeLst.count() > 1 ) + item->setValue( fakeLst[ 1 ] ); + } + + if ( lst.count() > 1 && !lst[ 1 ].isEmpty() ) + item->setCurrentItem( lst[ 1 ] ); + else if ( !isChanged() && withField ) { + QStringList fakeLst = MetaDataBase::fakeProperty( listview->propertyEditor()->formWindow()->mainContainer(), "database" ).toStringList(); + if ( fakeLst.count() > 1 ) + item->setCurrentItem( fakeLst[ 1 ] ); + else + item->setCurrentItem( 0 ); + } else + item->setCurrentItem( 0 ); + table = item->currentItem(); + } else if ( item->name() == tr( "Field" ) ) { + QStringList cl = listview->propertyEditor()->formWindow()->project()->databaseFieldList( conn, table ); + if ( !cl.isEmpty() ) + item->setValue( cl ); + else if ( lst.count() > 2 ) + item->setValue( QStringList( lst[ 2 ] ) ); + if ( lst.count() > 2 && !lst[ 2 ].isEmpty() ) + item->setCurrentItem( lst[ 2 ] ); + else + item->setCurrentItem( 0 ); + } + } +#endif +} + +PropertyDatabaseItem::~PropertyDatabaseItem() +{ + delete (QHBox*)box; +} + +void PropertyDatabaseItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() || !lined->hasFocus() ) { + box->show(); + setFocus( lined ); + } +} + +void PropertyDatabaseItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyDatabaseItem::setValue( const QVariant &v ) +{ + if ( value() == v ) + return; + + QStringList lst = v.toStringList(); + QString s = lst.join( "." ); + setText( 1, s ); + lined->setText( s ); + PropertyItem::setValue( v ); +} + +bool PropertyDatabaseItem::hasSubItems() const +{ + return TRUE; +} + +void PropertyDatabaseItem::childValueChanged( PropertyItem *c ) +{ +#ifndef QT_NO_SQL + QStringList lst; + lst << ( (PropertyListItem*)PropertyItem::child( 0 ) )->currentItem() + << ( (PropertyListItem*)PropertyItem::child( 1 ) )->currentItem(); + if ( withField ) + lst << ( (PropertyListItem*)PropertyItem::child( 2 ) )->currentItem(); + if ( c == PropertyItem::child( 0 ) ) { // if the connection changed + lst[ 0 ] = ( (PropertyListItem*)c )->currentItem(); + PropertyItem::child( 1 )->setValue( listview->propertyEditor()->formWindow()->project()->databaseTableList( lst[ 0 ] ) ); + if ( withField ) + PropertyItem::child( 2 )->setValue( listview->propertyEditor()->formWindow()->project()->databaseFieldList( lst[ 0 ], lst[ 1 ] ) ); + } else if ( withField && c == PropertyItem::child( 1 ) ) { // if the table changed + lst[ 1 ] = ( (PropertyListItem*)c )->currentItem(); + if ( withField ) + PropertyItem::child( 2 )->setValue( listview->propertyEditor()->formWindow()->project()->databaseFieldList( lst[ 0 ], lst[ 1 ] ) ); + } + lst.clear(); + lst << ( (PropertyListItem*)PropertyItem::child( 0 ) )->currentItem() + << ( (PropertyListItem*)PropertyItem::child( 1 ) )->currentItem(); + if ( withField ) + lst << ( (PropertyListItem*)PropertyItem::child( 2 ) )->currentItem(); + setValue( lst ); + notifyValueChange(); +#else + Q_UNUSED( c ); +#endif +} + +// -------------------------------------------------------------- + +PropertySizePolicyItem::PropertySizePolicyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + lin = 0; +} + +QLineEdit *PropertySizePolicyItem::lined() +{ + if ( lin ) + return lin; + lin = new QLineEdit( listview->viewport() ); + lin->hide(); + lin->setReadOnly( TRUE ); + return lin; +} + +void PropertySizePolicyItem::createChildren() +{ + QStringList lst; + lst << "Fixed" << "Minimum" << "Maximum" << "Preferred" << "MinimumExpanding" << "Expanding" << "Ignored"; + + PropertyItem *i = this; + i = new PropertyListItem( listview, i, this, tr( "hSizeType" ), FALSE ); + i->setValue( lst ); + addChild( i ); + i = new PropertyListItem( listview, i, this, tr( "vSizeType" ), FALSE ); + i->setValue( lst ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, tr( "horizontalStretch" ), TRUE ); + addChild( i ); + i = new PropertyIntItem( listview, i, this, tr( "verticalStretch" ), TRUE ); + addChild( i ); +} + +void PropertySizePolicyItem::initChildren() +{ + PropertyItem *item = 0; + QSizePolicy sp = val.toSizePolicy(); + for ( int i = 0; i < childCount(); ++i ) { + item = PropertyItem::child( i ); + if ( item->name() == tr( "hSizeType" ) ) + ( (PropertyListItem*)item )->setCurrentItem( size_type_to_int( sp.horData() ) ); + else if ( item->name() == tr( "vSizeType" ) ) + ( (PropertyListItem*)item )->setCurrentItem( size_type_to_int( sp.verData() ) ); + else if ( item->name() == tr( "horizontalStretch" ) ) + ( (PropertyIntItem*)item )->setValue( sp.horStretch() ); + else if ( item->name() == tr( "verticalStretch" ) ) + ( (PropertyIntItem*)item )->setValue( sp.verStretch() ); + } +} + +PropertySizePolicyItem::~PropertySizePolicyItem() +{ + delete (QLineEdit*)lin; +} + +void PropertySizePolicyItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( lined() ); + if ( !lined()->isVisible() || !lined()->hasFocus() ) { + lined()->show(); + listView()->viewport()->setFocus(); + } +} + +void PropertySizePolicyItem::hideEditor() +{ + PropertyItem::hideEditor(); + lined()->hide(); +} + +void PropertySizePolicyItem::setValue( const QVariant &v ) +{ + if ( value() == v ) + return; + + QString s = tr( "%1/%2/%2/%2" ); + s = s.arg( size_type_to_string( v.toSizePolicy().horData() ) ). + arg( size_type_to_string( v.toSizePolicy().verData() ) ). + arg( v.toSizePolicy().horStretch() ). + arg( v.toSizePolicy().verStretch() ); + setText( 1, s ); + lined()->setText( s ); + PropertyItem::setValue( v ); +} + +void PropertySizePolicyItem::childValueChanged( PropertyItem *child ) +{ + QSizePolicy sp = val.toSizePolicy(); + if ( child->name() == tr( "hSizeType" ) ) + sp.setHorData( int_to_size_type( ( ( PropertyListItem*)child )->currentIntItem() ) ); + else if ( child->name() == tr( "vSizeType" ) ) + sp.setVerData( int_to_size_type( ( ( PropertyListItem*)child )->currentIntItem() ) ); + else if ( child->name() == tr( "horizontalStretch" ) ) + sp.setHorStretch( ( ( PropertyIntItem*)child )->value().toInt() ); + else if ( child->name() == tr( "verticalStretch" ) ) + sp.setVerStretch( ( ( PropertyIntItem*)child )->value().toInt() ); + setValue( sp ); + notifyValueChange(); +} + +bool PropertySizePolicyItem::hasSubItems() const +{ + return TRUE; +} + +// -------------------------------------------------------------- + +PropertyPaletteItem::PropertyPaletteItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + palettePrev = new QLabel( box ); + button = new QPushButton( "...", box ); + setupStyle( button ); + button->setFixedWidth( 20 ); + box->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + box->setLineWidth( 2 ); + palettePrev->setFrameStyle( QFrame::NoFrame ); + box->installEventFilter( listview ); + connect( button, SIGNAL( clicked() ), + this, SLOT( getPalette() ) ); +} +PropertyPaletteItem::~PropertyPaletteItem() +{ + delete (QHBox*)box; +} + +void PropertyPaletteItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + listView()->viewport()->setFocus(); + } +} + +void PropertyPaletteItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyPaletteItem::setValue( const QVariant &v ) +{ + QString s; + palettePrev->setPalette( v.toPalette() ); + PropertyItem::setValue( v ); + repaint(); +} + +void PropertyPaletteItem::getPalette() +{ + if ( !listview->propertyEditor()->widget()->isWidgetType() ) + return; + bool ok = FALSE; + QWidget *w = (QWidget*)listview->propertyEditor()->widget(); + if ( ::qt_cast(w) ) + w = ( (QScrollView*)w )->viewport(); + QPalette pal = PaletteEditor::getPalette( &ok, val.toPalette(), +#if defined(QT_NON_COMMERCIAL) + w->backgroundMode(), listview->topLevelWidget(), +#else + w->backgroundMode(), listview, +#endif + "choose_palette", listview->propertyEditor()->formWindow() ); + if ( !ok ) + return; + setValue( pal ); + notifyValueChange(); +} + +bool PropertyPaletteItem::hasCustomContents() const +{ + return TRUE; +} + +void PropertyPaletteItem::drawCustomContents( QPainter *p, const QRect &r ) +{ + QPalette pal( value().toPalette() ); + p->save(); + p->setClipRect( QRect( QPoint( (int)(p->worldMatrix().dx() + r.x()), + (int)(p->worldMatrix().dy() + r.y()) ), + r.size() ) ); + QRect r2( r ); + r2.setX( r2.x() + 2 ); + r2.setY( r2.y() + 2 ); + r2.setWidth( r2.width() - 3 ); + r2.setHeight( r2.height() - 3 ); + p->setPen( QPen( black, 1 ) ); + p->setBrush( pal.active().background() ); + p->drawRect( r2 ); + p->restore(); +} + +// -------------------------------------------------------------- + +PropertyCursorItem::PropertyCursorItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + comb = 0; +} + +QComboBox *PropertyCursorItem::combo() +{ + if ( comb ) + return comb; + comb = new QComboBox( FALSE, listview->viewport() ); + comb->hide(); + QBitmap cur; + + comb->insertItem( QPixmap::fromMimeSource( "designer_arrow.png" ), tr("Arrow"), QObject::ArrowCursor); + comb->insertItem( QPixmap::fromMimeSource( "designer_uparrow.png" ), tr("Up-Arrow"), QObject::UpArrowCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_cross.png" ), tr("Cross"), QObject::CrossCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_wait.png" ), tr("Waiting"), QObject::WaitCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_ibeam.png" ), tr("iBeam"), QObject::IbeamCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_sizev.png" ), tr("Size Vertical"), QObject::SizeVerCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_sizeh.png" ), tr("Size Horizontal"), QObject::SizeHorCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_sizef.png" ), tr("Size Slash"), QObject::SizeBDiagCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_sizeb.png" ), tr("Size Backslash"), QObject::SizeFDiagCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_sizeall.png" ), tr("Size All"), QObject::SizeAllCursor ); + cur = QBitmap( 25, 25, 1 ); + cur.setMask( cur ); + comb->insertItem( cur, tr("Blank"), QObject::BlankCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_vsplit.png" ), tr("Split Vertical"), QObject::SplitVCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_hsplit.png" ), tr("Split Horizontal"), QObject::SplitHCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_hand.png" ), tr("Pointing Hand"), QObject::PointingHandCursor ); + comb->insertItem( QPixmap::fromMimeSource( "designer_no.png" ), tr("Forbidden"), QObject::ForbiddenCursor ); + + connect( comb, SIGNAL( activated( int ) ), + this, SLOT( setValue() ) ); + comb->installEventFilter( listview ); + return comb; +} + +PropertyCursorItem::~PropertyCursorItem() +{ + delete (QComboBox*)comb; +} + +void PropertyCursorItem::showEditor() +{ + PropertyItem::showEditor(); + if ( !comb ) { + combo()->blockSignals( TRUE ); + combo()->setCurrentItem( (int)value().toCursor().shape() ); + combo()->blockSignals( FALSE ); + } + placeEditor( combo() ); + if ( !combo()->isVisible() || !combo()->hasFocus() ) { + combo()->show(); + setFocus( combo() ); + } +} + +void PropertyCursorItem::hideEditor() +{ + PropertyItem::hideEditor(); + combo()->hide(); +} + +void PropertyCursorItem::setValue( const QVariant &v ) +{ + if ( ( !hasSubItems() || !isOpen() ) + && value() == v ) + return; + + combo()->blockSignals( TRUE ); + combo()->setCurrentItem( (int)v.toCursor().shape() ); + combo()->blockSignals( FALSE ); + setText( 1, combo()->currentText() ); + PropertyItem::setValue( v ); +} + +void PropertyCursorItem::setValue() +{ + if ( !comb ) + return; + if ( QVariant( QCursor( combo()->currentItem() ) ) == val ) + return; + setText( 1, combo()->currentText() ); + PropertyItem::setValue( QCursor( combo()->currentItem() ) ); + notifyValueChange(); +} + +// -------------------------------------------------------------- + +PropertyKeysequenceItem::PropertyKeysequenceItem( PropertyList *l, + PropertyItem *after, + PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ), + k1( 0 ), k2( 0 ), k3( 0 ), k4( 0 ), num( 0 ), mouseEnter( FALSE ) +{ + box = new QHBox( listview->viewport() ); + box->hide(); + sequence = new QLineEdit( box ); + connect( sequence, SIGNAL(textChanged( const QString & )), + this, SLOT(setValue()) ); + sequence->installEventFilter( this ); +} + +PropertyKeysequenceItem::~PropertyKeysequenceItem() +{ + delete (QHBox*)box; +} + +void PropertyKeysequenceItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + sequence->setFocus(); + } +} + +void PropertyKeysequenceItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +bool PropertyKeysequenceItem::eventFilter( QObject *o, QEvent *e ) +{ + Q_UNUSED( o ); + if ( e->type() == QEvent::KeyPress ) { + QKeyEvent *k = (QKeyEvent *)e; + if ( !mouseEnter && + (k->key() == QObject::Key_Up || + k->key() == QObject::Key_Down) ) + return FALSE; + handleKeyEvent( k ); + return TRUE; + } else if ( (e->type() == QEvent::FocusIn) || + (e->type() == QEvent::MouseButtonPress) ) { + mouseEnter = ( listview->lastEvent() == PropertyList::MouseEvent ) || + (e->type() == QEvent::MouseButtonPress); + return TRUE; + } + + // Lets eat accelerators now.. + if ( e->type() == QEvent::Accel || + e->type() == QEvent::AccelOverride || + e->type() == QEvent::KeyRelease ) + return TRUE; + return FALSE; +} + +void PropertyKeysequenceItem::handleKeyEvent( QKeyEvent *e ) +{ + int nextKey = e->key(); + + if ( num > 3 || + nextKey == QObject::Key_Control || + nextKey == QObject::Key_Shift || + nextKey == QObject::Key_Meta || + nextKey == QObject::Key_Alt) + return; + + int modifier = translateModifiers( e->state() ); + if (nextKey == QObject::Key_BackTab) + modifier &= ~QObject::SHIFT; + + nextKey |= modifier; + switch( num ) { + case 0: + k1 = nextKey; + break; + case 1: + k2 = nextKey; + break; + case 2: + k3 = nextKey; + break; + case 3: + k4 = nextKey; + break; + default: + break; + } + num++; + QKeySequence ks( k1, k2, k3, k4 ); + sequence->setText( ks ); +} + +int PropertyKeysequenceItem::translateModifiers( int state ) +{ + int result = 0; + if ( state & QObject::ShiftButton ) + result |= QObject::SHIFT; + if ( state & QObject::ControlButton ) + result |= QObject::CTRL; + if ( state & QObject::MetaButton ) + result |= QObject::META; + if ( state & QObject::AltButton ) + result |= QObject::ALT; + return result; +} + +void PropertyKeysequenceItem::setValue() +{ + QVariant v; + v = QVariant( QKeySequence(sequence->text()) ); + if ( v.toString().isNull() ) + return; + setText( 1, sequence->text() ); + PropertyItem::setValue( v ); + if (sequence->hasFocus() + // if the user wants to use F1 as accelerator, Designer will pop up a QWhatsThat widget + || (qApp->focusWidget() && qApp->focusWidget()->inherits("QWhatsThat"))) + notifyValueChange(); + setChanged( TRUE ); +} + +void PropertyKeysequenceItem::setValue( const QVariant &v ) +{ + QKeySequence ks = v.toKeySequence(); + if ( sequence ) { + sequence->setText( ks ); + } + num = ks.count(); + k1 = ks[0]; + k2 = ks[1]; + k3 = ks[2]; + k4 = ks[3]; + setText( 1, ks ); + PropertyItem::setValue( v ); +} + +// -------------------------------------------------------------- + +EnumPopup::EnumPopup( QWidget *parent, const char *name, WFlags f ) + : QFrame( parent, name, f ) +{ + setLineWidth( 1 ); + setFrameStyle( Panel | Plain ); + setPaletteBackgroundColor( Qt::white ); + popLayout = new QVBoxLayout( this, 3 ); + checkBoxList.setAutoDelete( TRUE ); +} + +EnumPopup::~EnumPopup() +{ +} + +void EnumPopup::insertEnums( QValueList lst ) +{ + while ( checkBoxList.count() ) + checkBoxList.removeFirst(); + + itemList = lst; + QCheckBox *cb; + QValueListConstIterator it = itemList.begin(); + for ( ; it != itemList.end(); ++it ) { + cb = new QCheckBox( this ); + cb->setText( (*it).key ); + cb->setChecked( (*it).selected ); + if ( it == itemList.begin() ) + cb->setFocus(); + checkBoxList.append( cb ); + cb->resize( width(), cb->height() ); + popLayout->addWidget( cb ); + } +} + +void EnumPopup::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Key_Escape ) { + hide(); + emit hidden(); + } else if ( e->key() == Key_Enter || e->key() == Key_Return ) { + closeWidget(); + } +} + +void EnumPopup::closeWidget() +{ + QPtrListIterator it( checkBoxList ); + int i = 0; + while ( it.current() != 0 ) { + itemList[i].selected = (*it)->isChecked(); + ++it; + ++i; + } + close(); + emit closed(); +} + +QValueList EnumPopup::enumList() const +{ + return itemList; +} + +EnumBox::EnumBox( QWidget *parent, const char *name ) + : QComboBox( parent, name ) +{ + pop = new EnumPopup( this, "popup", QObject::WType_Popup ); + connect( pop, SIGNAL( hidden() ), this, SLOT( popupHidden() ) ); + connect( pop, SIGNAL( closed() ), this, SLOT( popupClosed() ) ); + popupShown = FALSE; + arrowDown = FALSE; +} + +void EnumBox::popupHidden() +{ + popupShown = FALSE; +} + +void EnumBox::popupClosed() +{ + popupShown = FALSE; + emit valueChanged(); +} + +void EnumBox::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); + const QColorGroup & g = colorGroup(); + p.setPen(g.text()); + + QStyle::SFlags flags = QStyle::Style_Default; + if (isEnabled()) + flags |= QStyle::Style_Enabled; + if (hasFocus()) + flags |= QStyle::Style_HasFocus; + + if ( width() < 5 || height() < 5 ) { + qDrawShadePanel( &p, rect().x(), rect().y(), rect().width(), rect().height(), g, FALSE, 2, + &g.brush( QColorGroup::Button ) ); + return; + } + style().drawComplexControl( QStyle::CC_ComboBox, &p, this, rect(), g, + flags, QStyle::SC_All, + (arrowDown ? + QStyle::SC_ComboBoxArrow : + QStyle::SC_None )); + + QRect re = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxEditField ); + re = QStyle::visualRect(re, this); + p.setClipRect( re ); + + if ( !str.isNull() ) { + p.save(); + p.setFont(font()); + QFontMetrics fm(font()); + int x = re.x(), y = re.y() + fm.ascent(); + p.drawText( x, y, str ); + p.restore(); + } +} + +void EnumBox::insertEnums( QValueList lst ) +{ + pop->insertEnums( lst ); +} + +QValueList EnumBox::enumList() const +{ + return pop->enumList(); +} + +void EnumBox::popup() +{ + if ( popupShown ) { + pop->closeWidget(); + popupShown = FALSE; + return; + } + pop->move( ((QWidget*)parent())->mapToGlobal( geometry().bottomLeft() ) ); + pop->setMinimumWidth( width() ); + emit aboutToShowPopup(); + pop->show(); + popupShown = TRUE; +} + +void EnumBox::mousePressEvent( QMouseEvent *e ) +{ + if ( e->button() != LeftButton ) + return; + + QRect arrowRect = style().querySubControlMetrics( QStyle::CC_ComboBox, this, + QStyle::SC_ComboBoxArrow); + arrowRect = QStyle::visualRect(arrowRect, this); + + arrowRect.setHeight( QMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) ); + + if ( arrowRect.contains( e->pos() ) ) { + arrowDown = TRUE; + repaint( FALSE ); + } + + popup(); + QTimer::singleShot( 100, this, SLOT( restoreArrow() ) ); +} + +void EnumBox::keyPressEvent( QKeyEvent *e ) +{ + if ( e->key() == Key_Space ) { + popup(); + QTimer::singleShot( 100, this, SLOT( restoreArrow() ) ); + } else if ( e->key() == Key_Enter || e->key() == Key_Return ) { + popup(); + } +} + +void EnumBox::restoreArrow() +{ + arrowDown = FALSE; + repaint( FALSE ); +} + +void EnumBox::setText( const QString &text ) +{ + str = text; + repaint( FALSE ); +} + + + +PropertyEnumItem::PropertyEnumItem( PropertyList *l, + PropertyItem *after, + PropertyItem *prop, + const QString &propName ) + : PropertyItem( l, after, prop, propName ) +{ + box = new EnumBox( listview->viewport() ); + box->hide(); + box->installEventFilter( listview ); + connect( box, SIGNAL( aboutToShowPopup() ), this, SLOT( insertEnums() ) ); + connect( box, SIGNAL( valueChanged() ), this, SLOT( setValue() ) ); +} + +PropertyEnumItem::~PropertyEnumItem() +{ + delete (EnumBox*)box; +} + +void PropertyEnumItem::showEditor() +{ + PropertyItem::showEditor(); + placeEditor( box ); + if ( !box->isVisible() ) { + box->show(); + box->setText( enumString ); + listView()->viewport()->setFocus(); + } + box->setFocus(); +} + +void PropertyEnumItem::hideEditor() +{ + PropertyItem::hideEditor(); + box->hide(); +} + +void PropertyEnumItem::setValue( const QVariant &v ) +{ + enumString = ""; + enumList.clear(); + QStringList lst = v.toStringList(); + QValueListConstIterator it = lst.begin(); + for ( ; it != lst.end(); ++it ) + enumList.append( EnumItem( *it, FALSE ) ); + enumList.first().selected = TRUE; + enumString = enumList.first().key; + box->setText( enumString ); + setText( 1, enumString ); + PropertyItem::setValue( v ); +} + +void PropertyEnumItem::insertEnums() +{ + box->insertEnums( enumList ); +} + +void PropertyEnumItem::setValue() +{ + enumList = box->enumList(); + enumString = ""; + QValueListConstIterator it = enumList.begin(); + for ( ; it != enumList.end(); ++it ) { + if ( (*it).selected ) + enumString += "|" + (*it).key; + } + if ( !enumString.isEmpty() ) + enumString.replace( 0, 1, "" ); + + box->setText( enumString ); + setText( 1, enumString ); + notifyValueChange(); +} + +void PropertyEnumItem::setCurrentValues( QStrList lst ) +{ + enumString =""; + QStrList::ConstIterator it = lst.begin(); + QValueList::Iterator eit = enumList.begin(); + for ( ; eit != enumList.end(); ++eit ) { + (*eit).selected = FALSE; + for ( it = lst.begin(); it != lst.end(); ++it ) { + if ( QString( *it ) == (*eit).key ) { + (*eit).selected = TRUE; + enumString += "|" + (*eit).key; + break; + } + } + } + if ( !enumString.isEmpty() ) + enumString.replace( 0, 1, "" ); + box->setText( enumString ); + setText( 1, enumString ); +} + +QString PropertyEnumItem::currentItem() const +{ + return enumString; +} + +QString PropertyEnumItem::currentItemFromObject() const +{ + return enumString; +} + +// -------------------------------------------------------------- + +/*! + \class PropertyList propertyeditor.h + \brief PropertyList is a QListView derived class which is used for editing widget properties + + This class is used for widget properties. It has to be child of a + PropertyEditor. + + To initialize it for editing a widget call setupProperties() which + iterates through the properties of the current widget (see + PropertyEditor::widget()) and builds the list. + + To update the item values, refetchData() can be called. + + If the value of an item has been changed by the user, and this + change should be applied to the widget's property, valueChanged() + has to be called. + + To set the value of an item, setPropertyValue() has to be called. +*/ + +PropertyList::PropertyList( PropertyEditor *e ) + : QListView( e ), editor( e ) +{ + init_colors(); + + whatsThis = new PropertyWhatsThis( this ); + showSorted = FALSE; + header()->setMovingEnabled( FALSE ); + header()->setStretchEnabled( TRUE ); + setResizePolicy( QScrollView::Manual ); + viewport()->setAcceptDrops( TRUE ); + viewport()->installEventFilter( this ); + addColumn( tr( "Property" ) ); + addColumn( tr( "Value" ) ); + connect( header(), SIGNAL( sizeChange( int, int, int ) ), + this, SLOT( updateEditorSize() ) ); + disconnect( header(), SIGNAL( sectionClicked( int ) ), + this, SLOT( changeSortColumn( int ) ) ); + connect( header(), SIGNAL( sectionClicked( int ) ), + this, SLOT( toggleSort() ) ); + connect( this, SIGNAL( pressed( QListViewItem *, const QPoint &, int ) ), + this, SLOT( itemPressed( QListViewItem *, const QPoint &, int ) ) ); + connect( this, SIGNAL( doubleClicked( QListViewItem * ) ), + this, SLOT( toggleOpen( QListViewItem * ) ) ); + setSorting( -1 ); + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOn ); + setColumnWidthMode( 1, Manual ); + mousePressed = FALSE; + pressItem = 0; + theLastEvent = MouseEvent; + header()->installEventFilter( this ); +} + +void PropertyList::toggleSort() +{ + showSorted = !showSorted; + editor->clear(); + editor->setup(); +} + +void PropertyList::resizeEvent( QResizeEvent *e ) +{ + QListView::resizeEvent( e ); + if ( currentItem() ) + ( ( PropertyItem* )currentItem() )->showEditor(); +} + +static QVariant::Type type_to_variant( const QString &s ) +{ + if ( s == "Invalid " ) + return QVariant::Invalid; + if ( s == "Map" ) + return QVariant::Map; + if ( s == "List" ) + return QVariant::List; + if ( s == "String" ) + return QVariant::String; + if ( s == "StringList" ) + return QVariant::StringList; + if ( s == "Font" ) + return QVariant::Font; + if ( s == "Pixmap" ) + return QVariant::Pixmap; + if ( s == "Brush" ) + return QVariant::Brush; + if ( s == "Rect" ) + return QVariant::Rect; + if ( s == "Size" ) + return QVariant::Size; + if ( s == "Color" ) + return QVariant::Color; + if ( s == "Palette" ) + return QVariant::Palette; + if ( s == "ColorGroup" ) + return QVariant::ColorGroup; + if ( s == "IconSet" ) + return QVariant::IconSet; + if ( s == "Point" ) + return QVariant::Point; + if ( s == "Image" ) + return QVariant::Image; + if ( s == "Int" ) + return QVariant::Int; + if ( s == "UInt" ) + return QVariant::UInt; + if ( s == "Bool" ) + return QVariant::Bool; + if ( s == "Double" ) + return QVariant::Double; + if ( s == "CString" ) + return QVariant::CString; + if ( s == "PointArray" ) + return QVariant::PointArray; + if ( s == "Region" ) + return QVariant::Region; + if ( s == "Bitmap" ) + return QVariant::Bitmap; + if ( s == "Cursor" ) + return QVariant::Cursor; + if ( s == "SizePolicy" ) + return QVariant::SizePolicy; + if ( s == "Date" ) + return QVariant::Date; + if ( s == "Time" ) + return QVariant::Time; + if ( s == "DateTime" ) + return QVariant::DateTime; + return QVariant::Invalid; +} + +#ifndef QT_NO_SQL +static bool parent_is_data_aware( QWidget *w ) +{ + QWidget *p = w ? w->parentWidget() : 0; + while ( p && !p->isTopLevel() ) { + if ( ::qt_cast(p) || ::qt_cast(p) ) + return TRUE; + p = p->parentWidget(); + } + return FALSE; +} +#endif + +/*! Sets up the property list by adding an item for each designable +property of the widget which is just edited. +*/ + +void PropertyList::setupProperties() +{ + if ( !editor->widget() ) + return; + bool allProperties = !::qt_cast(editor->widget()); + QStrList lst = editor->widget()->metaObject()->propertyNames( allProperties ); + PropertyItem *item = 0; + QMap unique; + QObject *w = editor->widget(); + QStringList valueSet; + bool parentHasLayout = + w->isWidgetType() && + !editor->formWindow()->isMainContainer( (QWidget*)w ) && ( (QWidget*)w )->parentWidget() && + WidgetFactory::layoutType( ( (QWidget*)w )->parentWidget() ) != WidgetFactory::NoLayout; + for ( QPtrListIterator it( lst ); it.current(); ++it ) { + const QMetaProperty* p = + editor->widget()->metaObject()-> + property( editor->widget()->metaObject()->findProperty( it.current(), allProperties), allProperties ); + if ( !p ) + continue; + if ( unique.contains( QString::fromLatin1( it.current() ) ) ) + continue; + if ( ::qt_cast(editor->widget()) || + ::qt_cast(editor->widget()) ) { + if ( qstrcmp( p->name(), "minimumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "geometry" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "sizePolicy" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumSize" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumSize" ) == 0 ) + continue; + } + unique.insert( QString::fromLatin1( it.current() ), TRUE ); + if ( editor->widget()->isWidgetType() && + editor->formWindow()->isMainContainer( (QWidget*)editor->widget() ) ) { + if ( qstrcmp( p->name(), "geometry" ) == 0 ) + continue; + } else { // hide some toplevel-only stuff + if ( qstrcmp( p->name(), "icon" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "iconText" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "caption" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "sizeIncrement" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "baseSize" ) == 0 ) + continue; + if ( parentHasLayout && qstrcmp( p->name(), "geometry" ) == 0 ) + continue; + if ( ::qt_cast(w) || ::qt_cast(w) ) { + if ( qstrcmp( p->name(), "sizePolicy" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "geometry" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumSize" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumSize" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "enabled" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "paletteForegroundColor" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "paletteBackgroundColor" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "paletteBackgroundPixmap" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "palette" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "font" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "cursor" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "mouseTracking" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "focusPolicy" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "acceptDrops" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "autoMask" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "backgroundOrigin" ) == 0 ) + continue; + } + } + if ( ::qt_cast(w) ) { + if ( qstrcmp( p->name(), "usesDropDown" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "toggleAction" ) == 0 ) + continue; + } + if ( qstrcmp( p->name(), "minimumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "minimumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumHeight" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "maximumWidth" ) == 0 ) + continue; + if ( qstrcmp( p->name(), "buttonGroupId" ) == 0 ) { // #### remove this when designable in Q_PROPERTY can take a function (isInButtonGroup() in this case) + if ( !editor->widget()->isWidgetType() || + !editor->widget()->parent() || + !::qt_cast(editor->widget()->parent()) ) + continue; + } + + bool isPropertyObject = w->isA( "PropertyObject" ); + + if ( ( p->designable(w) || + isPropertyObject && p->designable( ( (PropertyObject*)w )->widgetList().first() ) ) && + ( !isPropertyObject || qstrcmp( p->name(), "name" ) != 0 ) ) { + if ( p->isSetType() ) { + if ( QString( p->name() ) == "alignment" ) { + QStringList lst; + lst << p->valueToKey( AlignAuto ) + << p->valueToKey( AlignLeft ) + << p->valueToKey( AlignHCenter ) + << p->valueToKey( AlignRight ) + << p->valueToKey( AlignJustify ); + item = new PropertyListItem( this, item, 0, "hAlign", FALSE ); + item->setValue( lst ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "hAlign" ) ) + item->setChanged( TRUE, FALSE ); + if ( !::qt_cast(editor->widget()) ) { + lst.clear(); + lst << p->valueToKey( AlignTop ) + << p->valueToKey( AlignVCenter ) + << p->valueToKey( AlignBottom ); + item = new PropertyListItem( this, item, 0, "vAlign", FALSE ); + item->setValue( lst ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "vAlign" ) ) + item->setChanged( TRUE, FALSE ); + item = new PropertyBoolItem( this, item, 0, "wordwrap" ); + if ( ::qt_cast(w) ) + item->setVisible( FALSE ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "wordwrap" ) ) + item->setChanged( TRUE, FALSE ); + } + } else { + QStrList lst( p->enumKeys() ); + QStringList l; + QPtrListIterator it( lst ); + while ( it.current() != 0 ) { + l << QString(*it); + ++it; + } + item = new PropertyEnumItem( this, item, 0, p->name() ); + item->setValue( l ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), p->name() ) ) + item->setChanged( TRUE, FALSE ); + } + } else if ( p->isEnumType() ) { + QStrList l = p->enumKeys(); + QStringList lst; + for ( uint i = 0; i < l.count(); ++i ) { + QString k = l.at( i ); + // filter out enum-masks + if ( k[0] == 'M' && k[1].category() == QChar::Letter_Uppercase ) + continue; + lst << k; + } + item = new PropertyListItem( this, item, 0, p->name(), FALSE ); + item->setValue( lst ); + } else { + QVariant::Type t = QVariant::nameToType( p->type() ); + if ( !addPropertyItem( item, p->name(), t ) ) + continue; + } + } + if ( item && !p->isSetType() ) { + if ( valueSet.findIndex( item->name() ) == -1 ) { + setPropertyValue( item ); + valueSet << item->name(); + } + if ( MetaDataBase::isPropertyChanged( editor->widget(), p->name() ) ) + item->setChanged( TRUE, FALSE ); + } + } + + if ( !::qt_cast(w) && !::qt_cast(w) && !::qt_cast(w) && + w->isWidgetType() && WidgetFactory::layoutType( (QWidget*)w ) != WidgetFactory::NoLayout ) { + item = new PropertyLayoutItem( this, item, 0, "layoutSpacing" ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "layoutSpacing" ) + || MetaDataBase::spacing( editor->widget() ) != -1 ) + layoutInitValue( item, TRUE ); + else + layoutInitValue( item ); + item = new PropertyLayoutItem( this, item, 0, "layoutMargin" ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "layoutMargin" ) + || MetaDataBase::margin( editor->widget() ) != -1 ) + layoutInitValue( item, TRUE ); + else + layoutInitValue( item ); + QWidget *widget = (QWidget*)w; + if ( ( !::qt_cast(widget) && + widget->parentWidget() && ::qt_cast(widget->parentWidget()) ) ) { + item = new PropertyListItem( this, item, 0, "resizeMode", FALSE ); + QStringList lst; + lst << "Auto" << "FreeResize" << "Minimum" << "Fixed"; + item->setValue( lst ); + setPropertyValue( item ); + QString resizeMod = MetaDataBase::resizeMode( editor->widget() ); + if ( !resizeMod.isEmpty() && + resizeMod != WidgetFactory::defaultCurrentItem( editor->widget(), "resizeMode" ) ) { + item->setChanged( TRUE, FALSE ); + MetaDataBase::setPropertyChanged( editor->widget(), "resizeMode", TRUE ); + } + } + } + + if ( !::qt_cast(w) && !::qt_cast(w) && + !::qt_cast(w) && !::qt_cast(w) ) { + item = new PropertyTextItem( this, item, 0, "toolTip", TRUE, FALSE ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "toolTip" ) ) + item->setChanged( TRUE, FALSE ); + item = new PropertyTextItem( this, item, 0, "whatsThis", TRUE, TRUE ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "whatsThis" ) ) + item->setChanged( TRUE, FALSE ); + } + +#ifndef QT_NO_SQL + if ( !::qt_cast(editor->widget()) && !::qt_cast(editor->widget()) && + !::qt_cast(editor->widget()) && parent_is_data_aware( ::qt_cast(editor->widget()) ) ) { + item = new PropertyDatabaseItem( this, item, 0, "database", editor->formWindow()->mainContainer() != w ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "database" ) ) + item->setChanged( TRUE, FALSE ); + } + + if ( ::qt_cast(editor->widget()) || ::qt_cast(editor->widget()) || + ::qt_cast(editor->widget()) ) { + item = new PropertyDatabaseItem( this, item, 0, "database", FALSE ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "database" ) ) + item->setChanged( TRUE, FALSE ); + item = new PropertyBoolItem( this, item, 0, "frameworkCode" ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), "frameworkCode" ) ) + item->setChanged( TRUE, FALSE ); + } +#endif + + if ( w->isA("PropertyObject") ) { + const QWidgetList wl = ( (PropertyObject*)w )->widgetList(); + QPtrListIterator wIt( wl ); + while ( *wIt ) { + if ( (*wIt)->inherits("CustomWidget") ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)*wIt )->customWidget(); + setupCusWidgetProperties( cw, unique, item ); + } + ++wIt; + } + } else if ( w->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)w )->customWidget(); + setupCusWidgetProperties( cw, unique, item ); + } + + setCurrentItem( firstChild() ); + + if ( showSorted ) { + setSorting( 0 ); + sort(); + setSorting( -1 ); + setCurrentItem( firstChild() ); + qApp->processEvents(); + } + + updateEditorSize(); +} + +void PropertyList::setupCusWidgetProperties( MetaDataBase::CustomWidget *cw, + QMap &unique, + PropertyItem *&item ) +{ + if ( !cw ) + return; + + for ( QValueList::Iterator it = + cw->lstProperties.begin(); it != cw->lstProperties.end(); ++it ) { + if ( unique.contains( QString( (*it).property ) ) ) + continue; + unique.insert( QString( (*it).property ), TRUE ); + addPropertyItem( item, (*it).property, type_to_variant( (*it).type ) ); + setPropertyValue( item ); + if ( MetaDataBase::isPropertyChanged( editor->widget(), (*it).property ) ) + item->setChanged( TRUE, FALSE ); + } +} + +bool PropertyList::addPropertyItem( PropertyItem *&item, const QCString &name, QVariant::Type t ) +{ + if ( name == "buddy" ) { + PropertyListItem *itm = new PropertyListItem( this, item, 0, name, TRUE ); + QPtrDict *widgets = editor->formWindow()->widgets(); + QPtrDictIterator it( *widgets ); + QStringList l; + l << ""; + while ( it.current() ) { + if ( editor->formWindow()->canBeBuddy( it.current() ) ) { + if ( l.find( it.current()->name() ) == l.end() ) + l << it.current()->name(); + } + ++it; + } + l.sort(); + itm->setValue( l ); + item = itm; + return TRUE; + } + + switch ( t ) { + case QVariant::String: + item = new PropertyTextItem( this, item, 0, name, TRUE, + ::qt_cast(editor->widget()) || + ::qt_cast(editor->widget()) || + ::qt_cast(editor->widget()) ); + break; + case QVariant::CString: + item = new PropertyTextItem( this, item, 0, + name, name == "name" && + editor->widget() == editor->formWindow()->mainContainer(), + FALSE, TRUE ); + break; + case QVariant::Bool: + item = new PropertyBoolItem( this, item, 0, name ); + break; + case QVariant::Font: + item = new PropertyFontItem( this, item, 0, name ); + break; + case QVariant::Int: + if ( name == "accel" ) + item = new PropertyTextItem( this, item, 0, name, FALSE, FALSE, FALSE, TRUE ); + else if ( name == "layoutSpacing" || name == "layoutMargin" ) + item = new PropertyLayoutItem( this, item, 0, name ); + else if ( name == "resizeMode" ) + item = new PropertyListItem( this, item, 0, name, TRUE ); + else + item = new PropertyIntItem( this, item, 0, name, TRUE ); + break; + case QVariant::Double: + item = new PropertyDoubleItem( this, item, 0, name ); + break; + case QVariant::KeySequence: + item = new PropertyKeysequenceItem( this, item, 0, name ); + break; + case QVariant::UInt: + item = new PropertyIntItem( this, item, 0, name, FALSE ); + break; + case QVariant::StringList: + item = new PropertyListItem( this, item, 0, name, TRUE ); + break; + case QVariant::Rect: + item = new PropertyCoordItem( this, item, 0, name, PropertyCoordItem::Rect ); + break; + case QVariant::Point: + item = new PropertyCoordItem( this, item, 0, name, PropertyCoordItem::Point ); + break; + case QVariant::Size: + item = new PropertyCoordItem( this, item, 0, name, PropertyCoordItem::Size ); + break; + case QVariant::Color: + item = new PropertyColorItem( this, item, 0, name, TRUE ); + break; + case QVariant::Pixmap: + item = new PropertyPixmapItem( this, item, 0, name, PropertyPixmapItem::Pixmap ); + break; + case QVariant::IconSet: + item = new PropertyPixmapItem( this, item, 0, name, PropertyPixmapItem::IconSet ); + break; + case QVariant::Image: + item = new PropertyPixmapItem( this, item, 0, name, PropertyPixmapItem::Image ); + break; + case QVariant::SizePolicy: + item = new PropertySizePolicyItem( this, item, 0, name ); + break; + case QVariant::Palette: + item = new PropertyPaletteItem( this, item, 0, name ); + break; + case QVariant::Cursor: + item = new PropertyCursorItem( this, item, 0, name ); + break; + case QVariant::Date: + item = new PropertyDateItem( this, item, 0, name ); + break; + case QVariant::Time: + item = new PropertyTimeItem( this, item, 0, name ); + break; + case QVariant::DateTime: + item = new PropertyDateTimeItem( this, item, 0, name ); + break; + default: + return FALSE; + } + return TRUE; +} + +void PropertyList::paintEmptyArea( QPainter *p, const QRect &r ) +{ + p->fillRect( r, *backColor2 ); +} + +void PropertyList::setCurrentItem( QListViewItem *i ) +{ + if ( !i ) + return; + + if ( currentItem() ) + ( (PropertyItem*)currentItem() )->hideEditor(); + QListView::setCurrentItem( i ); + ( (PropertyItem*)currentItem() )->showEditor(); +} + +void PropertyList::updateEditorSize() +{ + if ( currentItem() ) + ( ( PropertyItem* )currentItem() )->showEditor(); +} + +/*! This has to be called if the value if \a i should be set as + property to the currently edited widget. +*/ + +void PropertyList::valueChanged( PropertyItem *i ) +{ + if ( !editor->widget() ) + return; + QString pn( tr( "Set '%1' of '%2'" ).arg( i->name() ).arg( editor->widget()->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, editor->formWindow(), + editor->widget(), editor, + i->name(), WidgetFactory::property( editor->widget(), i->name() ), + i->value(), i->currentItem(), i->currentItemFromObject() ); + + cmd->execute(); + editor->formWindow()->commandHistory()->addCommand( cmd, TRUE ); +} + +void PropertyList::layoutInitValue( PropertyItem *i, bool changed ) +{ + if ( !editor->widget() ) + return; + QString pn( tr( "Set '%1' of '%2'" ).arg( i->name() ).arg( editor->widget()->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, editor->formWindow(), + editor->widget(), editor, + i->name(), WidgetFactory::property( editor->widget(), i->name() ), + i->value(), i->currentItem(), i->currentItemFromObject() ); + cmd->execute(); + if ( i->value().toString() != "-1" ) + changed = TRUE; + i->setChanged( changed ); +} + +void PropertyList::itemPressed( QListViewItem *i, const QPoint &p, int c ) +{ + if ( !i ) + return; + PropertyItem *pi = (PropertyItem*)i; + if ( !pi->hasSubItems() ) + return; + + if ( c == 0 && viewport()->mapFromGlobal( p ).x() < 20 ) + toggleOpen( i ); +} + +void PropertyList::toggleOpen( QListViewItem *i ) +{ + if ( !i ) + return; + PropertyItem *pi = (PropertyItem*)i; + if ( pi->hasSubItems() ) { + pi->setOpen( !pi->isOpen() ); + } else { + pi->toggle(); + } +} + +bool PropertyList::eventFilter( QObject *o, QEvent *e ) +{ + if ( !o || !e ) + return TRUE; + + PropertyItem *i = (PropertyItem*)currentItem(); + if ( e->type() == QEvent::KeyPress ) + theLastEvent = KeyEvent; + else if ( e->type() == QEvent::MouseButtonPress ) + theLastEvent = MouseEvent; + + if ( o != this &&e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ( ke->key() == Key_Up || ke->key() == Key_Down ) && + ( o != this || o != viewport() ) && + !( ke->state() & ControlButton ) ) { + QApplication::sendEvent( this, (QKeyEvent*)e ); + return TRUE; + } else if ( ( !::qt_cast(o) || + ( ::qt_cast(o) && ( (QLineEdit*)o )->isReadOnly() ) ) && + i && i->hasSubItems() ) { + if ( !i->isOpen() && + ( ke->key() == Key_Plus || + ke->key() == Key_Right )) + i->setOpen( TRUE ); + else if ( i->isOpen() && + ( ke->key() == Key_Minus || + ke->key() == Key_Left ) ) + i->setOpen( FALSE ); + } else if ( ( ke->key() == Key_Return || ke->key() == Key_Enter ) && ::qt_cast(o) ) { + QKeyEvent ke2( QEvent::KeyPress, Key_Space, 0, 0 ); + QApplication::sendEvent( o, &ke2 ); + return TRUE; + } + } else if ( e->type() == QEvent::FocusOut && ::qt_cast(o) && editor->formWindow() ) { + QTimer::singleShot( 100, editor->formWindow()->commandHistory(), SLOT( checkCompressedCommand() ) ); + } else if ( o == viewport() ) { + QMouseEvent *me; + PropertyListItem* i; + switch ( e->type() ) { + case QEvent::MouseButtonPress: + me = (QMouseEvent*)e; + i = (PropertyListItem*) itemAt( me->pos() ); + if ( i && ( ::qt_cast(i) || ::qt_cast(i) ) ) { + pressItem = i; + pressPos = me->pos(); + mousePressed = TRUE; + } + break; + case QEvent::MouseMove: + me = (QMouseEvent*)e; + if ( me && me->state() & LeftButton && mousePressed) { + + i = (PropertyListItem*) itemAt( me->pos() ); + if ( i && i == pressItem ) { + + if (( pressPos - me->pos() ).manhattanLength() > QApplication::startDragDistance() ){ + if ( ::qt_cast(i) ) { + QColor col = i->value().asColor(); + QColorDrag *drg = new QColorDrag( col, this ); + QPixmap pix( 25, 25 ); + pix.fill( col ); + QPainter p( &pix ); + p.drawRect( 0, 0, pix.width(), pix.height() ); + p.end(); + drg->setPixmap( pix ); + mousePressed = FALSE; + drg->dragCopy(); + } + else if ( ::qt_cast(i) ) { + QPixmap pix = i->value().asPixmap(); + if( !pix.isNull() ) { + QImage img = pix.convertToImage(); + QImageDrag *drg = new QImageDrag( img, this ); + drg->setPixmap( pix ); + mousePressed = FALSE; + drg->dragCopy(); + } + } + } + } + } + break; + default: + break; + } + } else if ( o == header() ) { + if ( e->type() == QEvent::ContextMenu ) { + ((QContextMenuEvent *)e)->accept(); + QPopupMenu menu( 0 ); + menu.setCheckable( TRUE ); + const int cat_id = 1; + const int alpha_id = 2; + menu.insertItem( tr( "Sort &Categorized" ), cat_id ); + int alpha = menu.insertItem( tr( "Sort &Alphabetically" ), alpha_id ); + if ( showSorted ) + menu.setItemChecked( alpha_id, TRUE ); + else + menu.setItemChecked( cat_id, TRUE ); + int res = menu.exec( ( (QContextMenuEvent*)e )->globalPos() ); + if ( res != -1 ) { + bool newShowSorted = ( res == alpha ); + if ( showSorted != newShowSorted ) { + showSorted = newShowSorted; + editor->clear(); + editor->setup(); + } + } + return TRUE; + } + } + + return QListView::eventFilter( o, e ); +} + +/*! This method re-initializes each item of the property list. +*/ + +void PropertyList::refetchData() +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + PropertyItem *i = (PropertyItem*)it.current(); + if ( !i->propertyParent() ) + setPropertyValue( i ); + if ( i->hasSubItems() ) + i->initChildren(); + bool changed = MetaDataBase::isPropertyChanged( editor->widget(), i->name() ); + if ( ( i->name() == "layoutSpacing" || i->name() == "layoutMargin" ) ) { + if ( i->value().toString() != "-1" ) + i->setChanged( TRUE, FALSE ); + else + i->setChanged( FALSE, FALSE ); + } + else if ( changed != i->isChanged() ) + i->setChanged( changed, FALSE ); + } + updateEditorSize(); +} + +static void clearAlignList( QStrList &l ) +{ + if ( l.count() == 1 ) + return; + if ( l.find( "AlignAuto" ) != -1 ) + l.remove( "AlignAuto" ); + if ( l.find( "WordBreak" ) != -1 ) + l.remove( "WordBreak" ); +} + +/*! This method initializes the value of the item \a i to the value + of the corresponding property. +*/ + +void PropertyList::setPropertyValue( PropertyItem *i ) +{ + const QMetaProperty *p = + editor->widget()->metaObject()-> + property( editor->widget()->metaObject()->findProperty( i->name(), TRUE), TRUE ); + if ( !p ) { + if ( i->name() == "hAlign" ) { + int align = editor->widget()->property( "alignment" ).toInt(); + p = editor->widget()->metaObject()-> + property( editor->widget()->metaObject()->findProperty( "alignment", TRUE ), TRUE ); + align &= ~AlignVertical_Mask; + QStrList l = p->valueToKeys( align ); + clearAlignList( l ); + ( (PropertyListItem*)i )->setCurrentItem( l.last() ); + } else if ( i->name() == "vAlign" ) { + int align = editor->widget()->property( "alignment" ).toInt(); + p = editor->widget()->metaObject()-> + property( editor->widget()->metaObject()->findProperty( "alignment", TRUE ), TRUE ); + align &= ~AlignHorizontal_Mask; + ( (PropertyListItem*)i )->setCurrentItem( p->valueToKeys( align ).last() ); + } else if ( i->name() == "wordwrap" ) { + int align = editor->widget()->property( "alignment" ).toInt(); + if ( align & WordBreak ) + i->setValue( QVariant( TRUE, 0 ) ); + else + i->setValue( QVariant( FALSE, 0 ) ); + } else if ( i->name() == "layoutSpacing" ) { + ( (PropertyLayoutItem*)i )->setValue( MetaDataBase::spacing( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ) ) ); + } else if ( i->name() == "layoutMargin" ) { + ( (PropertyLayoutItem*)i )->setValue( MetaDataBase::margin( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ) ) ); + } else if ( i->name() == "resizeMode" ) { + ( (PropertyListItem*)i )->setCurrentItem( MetaDataBase::resizeMode( WidgetFactory::containerOfWidget( (QWidget*)editor->widget() ) ) ); + } else if ( i->name() == "toolTip" || i->name() == "whatsThis" || i->name() == "database" || i->name() == "frameworkCode" ) { + i->setValue( MetaDataBase::fakeProperty( editor->widget(), i->name() ) ); + } else if ( editor->widget()->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)editor->widget() )->customWidget(); + if ( !cw ) + return; + i->setValue( MetaDataBase::fakeProperty( editor->widget(), i->name() ) ); + } + return; + } + if ( p->isSetType() ) + ( (PropertyEnumItem*)i )->setCurrentValues( p->valueToKeys( editor->widget()->property( i->name() ).toInt() ) ); + else if ( p->isEnumType() ) + ( (PropertyListItem*)i )->setCurrentItem( p->valueToKey( editor->widget()->property( i->name() ).toInt() ) ); + else if ( qstrcmp( p->name(), "buddy" ) == 0 ) + ( (PropertyListItem*)i )->setCurrentItem( editor->widget()->property( i->name() ).toString() ); + else + i->setValue( editor->widget()->property( i->name() ) ); +} + +void PropertyList::setCurrentProperty( const QString &n ) +{ + if ( currentItem() && currentItem()->text( 0 ) == n || + currentItem() && ( (PropertyItem*)currentItem() )->propertyParent() && + ( (PropertyItem*)currentItem() )->propertyParent()->text( 0 ) == n ) + return; + + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( it.current()->text( 0 ) == n ) { + setCurrentItem( it.current() ); + break; + } + } +} + +PropertyEditor *PropertyList::propertyEditor() const +{ + return editor; +} + +void PropertyList::resetProperty() +{ + if ( !currentItem() ) + return; + PropertyItem *i = (PropertyItem*)currentItem(); + if ( !MetaDataBase::isPropertyChanged( editor->widget(), i->PropertyItem::name() ) ) + return; + QString pn( tr( "Reset '%1' of '%2'" ).arg( i->name() ).arg( editor->widget()->name() ) ); + SetPropertyCommand *cmd = new SetPropertyCommand( pn, editor->formWindow(), + editor->widget(), editor, + i->name(), i->value(), + WidgetFactory::defaultValue( editor->widget(), i->name() ), + WidgetFactory::defaultCurrentItem( editor->widget(), i->name() ), + i->currentItem(), TRUE ); + cmd->execute(); + editor->formWindow()->commandHistory()->addCommand( cmd, FALSE ); + if ( i->hasSubItems() ) + i->initChildren(); +} + +void PropertyList::viewportDragEnterEvent( QDragEnterEvent *e ) +{ + PropertyListItem *i = (PropertyListItem*) itemAt( e->pos() ); + if( !i ) { + e->ignore(); + return; + } + + if ( ::qt_cast(i) && QColorDrag::canDecode( e ) ) + e->accept(); + else if ( ::qt_cast(i) && QImageDrag::canDecode( e ) ) + e->accept(); + else + e->ignore(); +} + +void PropertyList::viewportDragMoveEvent ( QDragMoveEvent *e ) +{ + PropertyListItem *i = (PropertyListItem*) itemAt( e->pos() ); + if( !i ) { + e->ignore(); + return; + } + + if ( ::qt_cast(i) && QColorDrag::canDecode( e ) ) + e->accept(); + else if ( ::qt_cast(i) && QImageDrag::canDecode( e ) ) + e->accept(); + else + e->ignore(); +} + +void PropertyList::viewportDropEvent ( QDropEvent *e ) +{ + PropertyListItem *i = (PropertyListItem*) itemAt( e->pos() ); + if( !i ) { + e->ignore(); + return; + } + + if ( ::qt_cast(i) && QColorDrag::canDecode( e ) ) { + QColor color; + QColorDrag::decode( e, color ); + i->setValue( QVariant( color ) ); + valueChanged( i ); + e->accept(); + } + else if ( ::qt_cast(i) && QImageDrag::canDecode( e ) ) { + QImage img; + QImageDrag::decode( e, img ); + QPixmap pm; + pm.convertFromImage( img ); + i->setValue( QVariant( pm ) ); + valueChanged( i ); + e->accept(); + } + else + e->ignore(); +} + +QString PropertyList::whatsThisAt( const QPoint &p ) +{ + return whatsThisText( itemAt( p ) ); +} + +void PropertyList::showCurrentWhatsThis() +{ + if ( !currentItem() ) + return; + QPoint p( 0, currentItem()->itemPos() ); + p = viewport()->mapToGlobal( contentsToViewport( p ) ); + QWhatsThis::display( whatsThisText( currentItem() ), p, viewport() ); +} + +QString PropertyList::whatsThisText( QListViewItem *i ) +{ + if ( !i || !editor->widget() ) + return QString::null; + readPropertyDocs(); + if ( ( (PropertyItem*)i )->propertyParent() ) + i = ( (PropertyItem*)i )->propertyParent(); + + const QMetaObject *mo = editor->widget()->metaObject(); + QString prop = ( (PropertyItem*)i )->name(); + while ( mo ) { + QString s; + s = QString( mo->className() ) + "::" + prop; + QMap::Iterator it; + if ( ( it = propertyDocs.find( s ) ) != propertyDocs.end() ) { + return *it; + } + mo = mo->superClass(); + } + + return tr( "

    QWidget::%1

    There is no documentation available for this property.

    " ).arg( prop ); +} + +void PropertyList::readPropertyDocs() +{ + if ( !propertyDocs.isEmpty() ) + return; + + QString docFile = MainWindow::self->documentationPath() + "/propertydocs"; + QFile f( docFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( &f, &errMsg, &errLine ) ) + return; + QDomElement e = doc.firstChild().toElement().firstChild().toElement(); + + for ( ; !e.isNull(); e = e.nextSibling().toElement() ) { + QDomElement n = e.firstChild().toElement(); + QString name; + QString doc; + for ( ; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "name" ) + name = n.firstChild().toText().data(); + else if ( n.tagName() == "doc" ) + doc = n.firstChild().toText().data(); + } + doc.insert( 0, "

    " + name + "

    " ); + propertyDocs.insert( name, doc ); + } +} + +PropertyList::LastEventType PropertyList::lastEvent() +{ + return theLastEvent; +} +// ------------------------------------------------------------ + +EventList::EventList( QWidget *parent, FormWindow *fw, PropertyEditor *e ) + : HierarchyList( parent, fw, TRUE ), editor( e ) +{ + header()->hide(); + removeColumn( 1 ); + setRootIsDecorated( TRUE ); + connect( this, SIGNAL( itemRenamed( QListViewItem *, int, const QString & ) ), + this, SLOT( renamed( QListViewItem * ) ) ); +} + +QString clean_arguments( const QString &s ) +{ + QString slot = s; + QString arg = slot.mid( slot.find( '(' ) + 1 ); + arg = arg.left( arg.findRev( ')' ) ); + QStringList args = QStringList::split( ',', arg ); + slot = slot.left( slot.find( '(' ) + 1 ); + int num = 0; + for ( QStringList::Iterator it = args.begin(); it != args.end(); ++it, ++num ) { + QString a = *it; + int i; + if ( ( i =a.find( ':' ) ) == -1 ) + slot += a.simplifyWhiteSpace(); + else + slot += a.mid( i + 1 ).simplifyWhiteSpace(); + if ( num < (int)args.count() - 1 ) + slot += ","; + } + + slot += ")"; + + return slot; +} + + +void EventList::setup() +{ + clear(); + + if ( !formWindow ) + return; + LanguageInterface *iface = MetaDataBase::languageInterface( formWindow->project()->language() ); + QStrList sigs; + if ( iface ) + sigs = iface->signalNames( editor->widget() ); + QStrListIterator it( sigs ); + while ( it.current() ) { + HierarchyItem *eventItem = new HierarchyItem( HierarchyItem::Event, this, (HierarchyItem*)0, + it.current(), QString::null, QString::null ); + eventItem->setOpen( TRUE ); + QValueList conns = + MetaDataBase::connections( formWindow, editor->widget(), formWindow->mainContainer() ); + HierarchyItem *item = 0; + for ( QValueList::Iterator cit = conns.begin(); + cit != conns.end(); ++cit ) { + QString s = it.current(); + if ( MetaDataBase::normalizeFunction( clean_arguments( QString( (*cit).signal ) ) ) != + MetaDataBase::normalizeFunction( clean_arguments( s ) ) ) + continue; + item = new HierarchyItem( HierarchyItem::EventFunction, eventItem, item, + (*cit).slot, QString::null, QString::null ); + item->setPixmap( 0, QPixmap::fromMimeSource( "designer_editslots.png" ) ); + } + ++it; + } +} + +extern QListViewItem *newItem; + +void EventList::contentsMouseDoubleClickEvent( QMouseEvent *e ) +{ + QListViewItem *i = itemAt( contentsToViewport( e->pos() ) ); + if ( !i || i->parent() ) + return; + QString s; + if ( !formWindow->project()->isCpp() ) { + QString s1 = i->text( 0 ); + int pt = s1.find( "(" ); + if ( pt != -1 ) + s1 = s1.left( pt ); + s = QString( editor->widget()->name() ) + "_" + s1; + } else { + s = QString( editor->widget()->name() ) + "_" + i->text( 0 ); + } + + insertEntry( i, QPixmap::fromMimeSource( "designer_editslots.png" ), s ); +} + +void EventList::setCurrent( QWidget * ) +{ +} + +void EventList::objectClicked( QListViewItem *i ) +{ + if ( !i || !i->parent() ) + return; + formWindow->mainWindow()->editFunction( i->text( 0 ) ); +} + +void EventList::showRMBMenu( QListViewItem *i, const QPoint &pos ) +{ + if ( !i ) + return; + QPopupMenu menu; + const int NEW_ITEM = 1; + const int DEL_ITEM = 2; + menu.insertItem( QPixmap::fromMimeSource( "designer_filenew.png" ), tr( "New Signal Handler" ), NEW_ITEM ); + menu.insertItem( QPixmap::fromMimeSource( "designer_editcut.png" ), tr( "Delete Signal Handler" ), DEL_ITEM ); + int res = menu.exec( pos ); + if ( res == NEW_ITEM ) { + QString s; + if ( !formWindow->project()->isCpp() ) { + QString s1 = ( i->parent() ? i->parent() : i )->text( 0 ); + int pt = s1.find( "(" ); + if ( pt != -1 ) + s1 = s1.left( pt ); + s = QString( editor->widget()->name() ) + "_" + s1; + } else { + s = QString( editor->widget()->name() ) + "_" + ( i->parent() ? i->parent() : i )->text( 0 ); + } + insertEntry( i->parent() ? i->parent() : i, QPixmap::fromMimeSource( "designer_editslots.png" ), s ); + } else if ( res == DEL_ITEM && i->parent() ) { + MetaDataBase::Connection conn; + conn.sender = editor->widget(); + conn.receiver = formWindow->mainContainer(); + conn.signal = i->parent()->text( 0 ); + conn.slot = i->text( 0 ); + delete i; + RemoveConnectionCommand *cmd = new RemoveConnectionCommand( tr( "Remove connection" ), + formWindow, + conn ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + editor->formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + } +} + +void EventList::renamed( QListViewItem *i ) +{ + if ( newItem == i ) + newItem = 0; + if ( !i->parent() ) + return; + QListViewItem *itm = i->parent()->firstChild(); + bool del = FALSE; + while ( itm ) { + if ( itm != i && itm->text( 0 ) == i->text( 0 ) ) { + del = TRUE; + break; + } + itm = itm->nextSibling(); + } + i->setRenameEnabled( 0, FALSE ); + if ( del ) { + delete i; + } else { + MetaDataBase::Connection conn; + conn.sender = editor->widget(); + conn.receiver = formWindow->mainContainer(); + conn.signal = i->parent()->text( 0 ); + conn.slot = i->text( 0 ); + AddConnectionCommand *cmd = new AddConnectionCommand( tr( "Add connection" ), + formWindow, + conn ); + formWindow->commandHistory()->addCommand( cmd ); + // #### we should look if the specified slot already + // exists and if we can connect to this one + QString funcname = i->text( 0 ).latin1(); + if ( funcname.find( '(' ) == -1 ) { // try to create a signature + QString sig = i->parent()->text( 0 ); + sig = sig.mid( sig.find( '(' ) + 1 ); + sig.remove( (int)sig.length() - 1, 1 ); + LanguageInterface *iface = MetaDataBase::languageInterface( formWindow->project()->language() ); + if ( iface ) + sig = iface->createArguments( sig.simplifyWhiteSpace() ); + funcname += "(" + sig + ")"; + } + MetaDataBase::addFunction( formWindow, funcname.latin1(), "virtual", "public", + "slot", formWindow->project()->language(), "void" ); + editor->formWindow()->mainWindow()-> + editFunction( i->text( 0 ).left( i->text( 0 ).find( "(" ) ), TRUE ); + cmd->execute(); + editor->formWindow()->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + editor->formWindow()->formFile()->setModified( TRUE ); + } +} + +void EventList::save( QListViewItem *p ) +{ + QStringList lst; + QListViewItem *i = p->firstChild(); + while ( i ) { + lst << i->text( 0 ); + i = i->nextSibling(); + } +} + +// -------------------------------------------------------------- + +/*! + \class PropertyEditor propertyeditor.h + \brief PropertyEdior toplevel window + + This is the toplevel window of the property editor which contains a + listview for editing properties. +*/ + +PropertyEditor::PropertyEditor( QWidget *parent ) + : QTabWidget( parent, 0, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | + WStyle_StaysOnTop | WStyle_Tool |WStyle_MinMax | WStyle_SysMenu ) +{ + setCaption( tr( "Property Editor" ) ); + wid = 0; + formwindow = 0; + listview = new PropertyList( this ); + addTab( listview, tr( "P&roperties" ) ); + eList = new EventList( this, formWindow(), this ); + addTab( eList, tr( "Signa&l Handlers" ) ); +} + +QObject *PropertyEditor::widget() const +{ + return wid; +} + +void PropertyEditor::setWidget( QObject *w, FormWindow *fw ) +{ + if ( fw && fw->isFake() ) + w = fw->project()->objectForFakeForm( fw ); + eList->setFormWindow( fw ); + if ( w && w == wid ) { + // if there is no properties displayed then we really should show them. + // to do this check the number of properties in the list. + bool ret = (listview->childCount() > 0) ? TRUE : FALSE; + if ( wid->isWidgetType() && WidgetFactory::layoutType( (QWidget*)wid ) != WidgetFactory::NoLayout ) { + QListViewItemIterator it( listview ); + ret = FALSE; + while ( it.current() ) { + if ( it.current()->text( 0 ) == "layoutSpacing" || it.current()->text( 0 ) == "layoutMargin" ) { + ret = TRUE; + break; + } + ++it; + } + } + if ( ret ) + return; + } + + if ( !w || !fw ) { + setCaption( tr( "Property Editor" ) ); + clear(); + wid = 0; + formwindow = 0; + return; + } + + wid = w; + formwindow = fw; + setCaption( tr( "Property Editor (%1)" ).arg( formwindow->name() ) ); + listview->viewport()->setUpdatesEnabled( FALSE ); + listview->setUpdatesEnabled( FALSE ); + clear(); + listview->viewport()->setUpdatesEnabled( TRUE ); + listview->setUpdatesEnabled( TRUE ); + setup(); +} + +void PropertyEditor::clear() +{ + listview->setContentsPos( 0, 0 ); + listview->clear(); + eList->setContentsPos( 0, 0 ); + eList->clear(); +} + +void PropertyEditor::setup() +{ + if ( !formwindow || !wid ) + return; + listview->viewport()->setUpdatesEnabled( FALSE ); + listview->setupProperties(); + listview->viewport()->setUpdatesEnabled( TRUE ); + listview->updateEditorSize(); + + // the forced processing of events in setupProperties() can set wid to 0, so we have to check + if ( wid && !wid->isA( "PropertyObject" ) ) { + eList->viewport()->setUpdatesEnabled( FALSE ); + eList->setup(); + eList->viewport()->setUpdatesEnabled( TRUE ); + } +} + +void PropertyEditor::refetchData() +{ + listview->refetchData(); +} + +void PropertyEditor::emitWidgetChanged() +{ + if ( formwindow && wid ) + formwindow->widgetChanged( wid ); +} + +void PropertyEditor::closed( FormWindow *w ) +{ + if ( w == formwindow ) { + formwindow = 0; + wid = 0; + clear(); + } +} + +void PropertyEditor::closeEvent( QCloseEvent *e ) +{ + emit hidden(); + e->accept(); +} + +PropertyList *PropertyEditor::propertyList() const +{ + return listview; +} + +FormWindow *PropertyEditor::formWindow() const +{ + return formwindow; +} + +QString PropertyEditor::currentProperty() const +{ + if ( !wid ) + return QString::null; + if ( ( (PropertyItem*)listview->currentItem() )->propertyParent() ) + return ( (PropertyItem*)listview->currentItem() )->propertyParent()->name(); + return ( (PropertyItem*)listview->currentItem() )->name(); +} + +QString PropertyEditor::classOfCurrentProperty() const +{ + if ( !wid ) + return QString::null; + QObject *o = wid; + QString curr = currentProperty(); + QMetaObject *mo = o->metaObject(); + while ( mo ) { + QStrList props = mo->propertyNames( FALSE ); + if ( props.find( curr.latin1() ) != -1 ) + return mo->className(); + mo = mo->superClass(); + } + return QString::null; +} + +QMetaObject* PropertyEditor::metaObjectOfCurrentProperty() const +{ + if ( !wid ) + return 0; + return wid->metaObject(); +} + +void PropertyEditor::resetFocus() +{ + if ( listview->currentItem() ) + ( (PropertyItem*)listview->currentItem() )->showEditor(); +} + +EventList *PropertyEditor::eventList() const +{ + return eList; +} + +void PropertyEditor::setPropertyEditorEnabled( bool b ) +{ + if ( !b ) + removePage( listview ); + else + insertTab( listview, tr( "Property Editor" ), 0 ); + updateWindow(); +} + +void PropertyEditor::setSignalHandlersEnabled( bool b ) +{ + if ( !b ) + removePage( eList ); + else + insertTab( eList, tr( "Signal Handlers" ), 0 ); + updateWindow(); +} + +void PropertyEditor::updateWindow() +{ + if ( isHidden() && count() ) { + parentWidget()->show(); + MainWindow::self->setAppropriate( (QDockWindow*)parentWidget(), TRUE ); + } else if ( isShown() && !count() ) { + parentWidget()->hide(); + MainWindow::self->setAppropriate( (QDockWindow*)parentWidget(), FALSE ); + } +} diff --git a/tools/designer/designer/propertyeditor.h b/tools/designer/designer/propertyeditor.h new file mode 100644 index 0000000..c5ad46b --- /dev/null +++ b/tools/designer/designer/propertyeditor.h @@ -0,0 +1,874 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PROPERTYEDITOR_H +#define PROPERTYEDITOR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hierarchyview.h" +#include "metadatabase.h" + +class PropertyList; +class PropertyEditor; +class QPainter; +class QColorGroup; +class QLineEdit; +class QPushButton; +class QHBox; +class QSpinBox; +class QLabel; +class QFrame; +class FormWindow; +class QCloseEvent; +class QResizeEvent; +class PropertyWhatsThis; +class QDateEdit; +class QTimeEdit; +class QDateTimeEdit; + +class PropertyItem : public QListViewItem +{ +public: + PropertyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyItem(); + + void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ); + void paintBranches( QPainter * p, const QColorGroup & cg, + int w, int y, int h ); + void paintFocus( QPainter *p, const QColorGroup &cg, const QRect &r ); + + virtual bool hasSubItems() const; + virtual void createChildren(); + virtual void initChildren(); + + bool isOpen() const; + void setOpen( bool b ); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + QVariant value() const; + QString name() const; + virtual void notifyValueChange(); + + virtual void setChanged( bool b, bool updateDb = TRUE ); + bool isChanged() const; + + virtual void placeEditor( QWidget *w ); + + virtual PropertyItem *propertyParent() const; + virtual void childValueChanged( PropertyItem *child ); + + void addChild( PropertyItem *i ); + int childCount() const; + PropertyItem *child( int i ) const; + + virtual bool hasCustomContents() const; + virtual void drawCustomContents( QPainter *p, const QRect &r ); + + void updateBackColor(); + + void setup() { QListViewItem::setup(); setHeight( QListViewItem::height() + 2 ); } + + virtual QString currentItem() const; + virtual int currentIntItem() const; + virtual void setCurrentItem( const QString &s ); + virtual void setCurrentItem( int i ); + virtual int currentIntItemFromObject() const; + virtual QString currentItemFromObject() const; + + void setFocus( QWidget *w ); + + virtual void toggle(); + void setText( int col, const QString &txt ); + +protected: + PropertyList *listview; + QVariant val; + +private: + QColor backgroundColor(); + void createResetButton(); + void updateResetButtonState(); + +private: + bool open, changed; + PropertyItem *property; + QString propertyName; + QPtrList children; + QColor backColor; + QPushButton *resetButton; + +}; + +class PropertyTextItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyTextItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool comment, bool multiLine, bool ascii = FALSE, bool a = FALSE ); + ~PropertyTextItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + + virtual void setChanged( bool b, bool updateDb = TRUE ); + +private slots: + void setValue(); + void getText(); + +private: + QLineEdit *lined(); + QGuardedPtr lin; + QGuardedPtr box; + QPushButton *button; + bool withComment, hasMultiLines, asciiOnly, accel; + +}; + + +class PropertyBoolItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyBoolItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyBoolItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual void toggle(); + +private slots: + void setValue(); + +private: + QComboBox *combo(); + QGuardedPtr comb; + +}; + +class PropertyIntItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyIntItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool s ); + ~PropertyIntItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QSpinBox *spinBox(); + QGuardedPtr spinBx; + bool signedValue; + +}; + +class PropertyLayoutItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyLayoutItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyLayoutItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QSpinBox *spinBox(); + QGuardedPtr spinBx; + +}; + +class PropertyDoubleItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyDoubleItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyDoubleItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QLineEdit *lined(); + QGuardedPtr lin; +}; + +class PropertyListItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyListItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool editable ); + ~PropertyListItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + + QString currentItem() const; + int currentIntItem() const; + void setCurrentItem( const QString &s ); + void setCurrentItem( int i ); + int currentIntItemFromObject() const; + QString currentItemFromObject() const; + void addItem( const QString &s ); + +private slots: + void setValue(); + +private: + QComboBox *combo(); + QGuardedPtr comb; + int oldInt; + bool editable; + QString oldString; + +}; + +class PropertyFontItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyFontItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyFontItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + +private slots: + void getFont(); + +private: + QGuardedPtr lined; + QGuardedPtr button; + QGuardedPtr box; + +}; + +class PropertyCoordItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + enum Type { Rect, Size, Point }; + + PropertyCoordItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, Type t ); + ~PropertyCoordItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + +private: + QLineEdit *lined(); + QGuardedPtr lin; + Type typ; + +}; + +class PropertyColorItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyColorItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, bool children ); + ~PropertyColorItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + + virtual bool hasCustomContents() const; + virtual void drawCustomContents( QPainter *p, const QRect &r ); + +private slots: + void getColor(); + +private: + QGuardedPtr box; + QGuardedPtr colorPrev; + QGuardedPtr button; + bool withChildren; + +}; + +class PropertyPixmapItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + enum Type { Pixmap, IconSet, Image }; + + PropertyPixmapItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName, Type t ); + ~PropertyPixmapItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + + virtual bool hasCustomContents() const; + virtual void drawCustomContents( QPainter *p, const QRect &r ); + +private slots: + void getPixmap(); + +private: + QGuardedPtr box; + QGuardedPtr pixPrev; + QPushButton *button; + Type type; + +}; + + +class PropertySizePolicyItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertySizePolicyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertySizePolicyItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + +private: + QLineEdit *lined(); + QGuardedPtr lin; + +}; + +class PropertyPaletteItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyPaletteItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyPaletteItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + + virtual bool hasCustomContents() const; + virtual void drawCustomContents( QPainter *p, const QRect &r ); + +private slots: + void getPalette(); + +private: + QGuardedPtr box; + QGuardedPtr palettePrev; + QGuardedPtr button; + +}; + +class PropertyCursorItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyCursorItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyCursorItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QComboBox *combo(); + QGuardedPtr comb; + +}; + +class PropertyKeysequenceItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyKeysequenceItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyKeysequenceItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + bool eventFilter( QObject *o, QEvent *e ); + void handleKeyEvent( QKeyEvent *e ); + int translateModifiers( int state ); + + QGuardedPtr sequence; + QGuardedPtr box; + int k1,k2,k3,k4; + int num; + bool mouseEnter; +}; + +class PropertyDatabaseItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyDatabaseItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName, bool wField ); + ~PropertyDatabaseItem(); + + virtual void createChildren(); + virtual void initChildren(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + virtual bool hasSubItems() const; + virtual void childValueChanged( PropertyItem *child ); + +private: + QGuardedPtr lined; + QGuardedPtr button; + QGuardedPtr box; + bool withField; + +}; + +struct EnumItem { + EnumItem( const QString &k, bool s ) + : key( k ), selected( s ) {} + EnumItem() : key( QString::null ), selected( FALSE ) {} + bool operator==( const EnumItem &item ) const { + return key == item.key; + } + QString key; + bool selected; +}; + +class EnumPopup : public QFrame +{ + Q_OBJECT + +public: + EnumPopup( QWidget *parent, const char *name, WFlags f=0 ); + ~EnumPopup(); + void insertEnums( QValueList lst ); + QValueList enumList() const; + void closeWidget(); + +signals: + void closed(); + void hidden(); + +protected: + void keyPressEvent( QKeyEvent *e ); + +private: + QValueList itemList; + QPtrList checkBoxList; + QVBoxLayout *popLayout; +}; + +class EnumBox : public QComboBox +{ + Q_OBJECT + +public: + EnumBox( QWidget *parent, const char *name = 0 ); + ~EnumBox() {} + void setText( const QString &text ); + void insertEnums( QValueList lst ); + QValueList enumList() const; + +signals: + void aboutToShowPopup(); + void valueChanged(); + +protected: + void paintEvent( QPaintEvent * ); + void mousePressEvent( QMouseEvent *e ); + void keyPressEvent( QKeyEvent *e ); + +protected slots: + void restoreArrow(); + void popupHidden(); + void popupClosed(); + +private: + void popup(); + bool arrowDown; + QString str; + bool popupShown; + EnumPopup *pop; + +}; +class PropertyEnumItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyEnumItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, + const QString &propName ); + ~PropertyEnumItem(); + + void showEditor(); + void hideEditor(); + void setValue( const QVariant &v ); + QString currentItem() const; + QString currentItemFromObject() const; + void setCurrentValues( QStrList lst ); + +private slots: + void setValue(); + void insertEnums(); + +private: + QGuardedPtr box; + QValueList enumList; + QString enumString; +}; + +class PropertyList : public QListView +{ + Q_OBJECT + +public: + PropertyList( PropertyEditor *e ); + + virtual void setupProperties(); + + virtual void setCurrentItem( QListViewItem *i ); + virtual void valueChanged( PropertyItem *i ); + virtual void refetchData(); + virtual void setPropertyValue( PropertyItem *i ); + virtual void setCurrentProperty( const QString &n ); + + void layoutInitValue( PropertyItem *i, bool changed = FALSE ); + PropertyEditor *propertyEditor() const; + QString whatsThisAt( const QPoint &p ); + void showCurrentWhatsThis(); + + enum LastEventType { KeyEvent, MouseEvent }; + LastEventType lastEvent(); + +public slots: + void updateEditorSize(); + void resetProperty(); + void toggleSort(); + +private slots: + void itemPressed( QListViewItem *i, const QPoint &p, int c ); + void toggleOpen( QListViewItem *i ); + bool eventFilter( QObject *o, QEvent *e ); + +protected: + void resizeEvent( QResizeEvent *e ); + void paintEmptyArea( QPainter *p, const QRect &r ); + bool addPropertyItem( PropertyItem *&item, const QCString &name, QVariant::Type t ); + + void viewportDragEnterEvent( QDragEnterEvent * ); + void viewportDragMoveEvent ( QDragMoveEvent * ); + void viewportDropEvent ( QDropEvent * ); + +protected: + PropertyEditor *editor; + +private: + void readPropertyDocs(); + void setupCusWidgetProperties( MetaDataBase::CustomWidget *cw, + QMap &unique, + PropertyItem *&item ); + QString whatsThisText( QListViewItem *i ); + +private: + PropertyListItem* pressItem; + QPoint pressPos; + bool mousePressed; + bool showSorted; + QMap propertyDocs; + PropertyWhatsThis *whatsThis; + LastEventType theLastEvent; +}; + +class EventList : public HierarchyList +{ + Q_OBJECT + +public: + EventList( QWidget *parent, FormWindow *fw, PropertyEditor *e ); + + void setup(); + void setCurrent( QWidget *w ); + +protected: + void contentsMouseDoubleClickEvent( QMouseEvent *e ); + +private: + void save( QListViewItem *p ); + +private slots: + void objectClicked( QListViewItem *i ); + void showRMBMenu( QListViewItem *, const QPoint & ); + void renamed( QListViewItem *i ); + +private: + PropertyEditor *editor; + +}; + + +class PropertyEditor : public QTabWidget +{ + Q_OBJECT + +public: + PropertyEditor( QWidget *parent ); + + QObject *widget() const; + + void clear(); + void setup(); + + void emitWidgetChanged(); + void refetchData(); + + void closed( FormWindow *w ); + + PropertyList *propertyList() const; + FormWindow *formWindow() const; + EventList *eventList() const; + + QString currentProperty() const; + QString classOfCurrentProperty() const; + QMetaObject* metaObjectOfCurrentProperty() const; + + void resetFocus(); + + void setPropertyEditorEnabled( bool b ); + void setSignalHandlersEnabled( bool b ); + +signals: + void hidden(); + +public slots: + void setWidget( QObject *w, FormWindow *fw ); + +protected: + void closeEvent( QCloseEvent *e ); + +private: + void updateWindow(); + +private: + QObject *wid; + PropertyList *listview; + EventList *eList; + FormWindow *formwindow; + +}; + +class PropertyDateItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyDateItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyDateItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QDateEdit *lined(); + QGuardedPtr lin; + +}; + +class PropertyTimeItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyTimeItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyTimeItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QTimeEdit *lined(); + QGuardedPtr lin; + +}; + +class PropertyDateTimeItem : public QObject, + public PropertyItem +{ + Q_OBJECT + +public: + PropertyDateTimeItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ); + ~PropertyDateTimeItem(); + + virtual void showEditor(); + virtual void hideEditor(); + + virtual void setValue( const QVariant &v ); + +private slots: + void setValue(); + +private: + QDateTimeEdit *lined(); + QGuardedPtr lin; + +}; + +#endif diff --git a/tools/designer/designer/propertyobject.cpp b/tools/designer/designer/propertyobject.cpp new file mode 100644 index 0000000..72ccdb0 --- /dev/null +++ b/tools/designer/designer/propertyobject.cpp @@ -0,0 +1,165 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "propertyobject.h" +#include "metadatabase.h" +#include +#include +#include +#include + +PropertyObject::PropertyObject( const QWidgetList &objs ) + : QObject(), objects( objs ), mobj( 0 ) +{ + QPtrVector > v; + v.resize( objects.count() ); + v.setAutoDelete( TRUE ); + + for ( QObject *o = objects.first(); o; o = objects.next() ) { + const QMetaObject *m = o->metaObject(); + QPtrList *mol = new QPtrList; + while ( m ) { + mol->insert( 0, m ); + m = m->superClass(); + } + v.insert( v.count(), mol ); + } + + int numObjects = objects.count(); + int minDepth = v[0]->count(); + int depth = minDepth; + + for ( int i = 0; i < numObjects; ++i ) { + depth = (int)v[i]->count(); + if ( depth < minDepth ) + minDepth = depth; + } + + const QMetaObject *m = v[0]->at( --minDepth ); + + for ( int j = 0; j < numObjects; ++j ) { + if ( v[j]->at( minDepth ) != m ) { + m = v[0]->at( --minDepth ); + j = 0; + } + } + + mobj = m; + + Q_ASSERT( mobj ); +} + +bool PropertyObject::setProperty( const char *name, const QVariant& value ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + o->setProperty( name, value ); + + return TRUE; +} + +QVariant PropertyObject::property( const char *name ) const +{ + return ( (PropertyObject*)this )->objects.first()->property( name ); +} + +void PropertyObject::mdPropertyChanged( const QString &property, bool changed ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setPropertyChanged( o, property, changed ); +} + +bool PropertyObject::mdIsPropertyChanged( const QString &property ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) { + if ( MetaDataBase::isPropertyChanged( o, property ) ) + return TRUE; + } + return FALSE; +} + +void PropertyObject::mdSetPropertyComment( const QString &property, const QString &comment ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setPropertyComment( o, property, comment ); +} + +QString PropertyObject::mdPropertyComment( const QString &property ) +{ + return MetaDataBase::propertyComment( objects.first(), property ); +} + +void PropertyObject::mdSetFakeProperty( const QString &property, const QVariant &value ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setFakeProperty( o, property, value ); +} + +QVariant PropertyObject::mdFakeProperty( const QString &property ) +{ + return MetaDataBase::fakeProperty( objects.first(), property ); +} + +void PropertyObject::mdSetCursor( const QCursor &c ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) { + if ( o->isWidgetType() ) + MetaDataBase::setCursor( (QWidget*)o, c ); + } +} + +QCursor PropertyObject::mdCursor() +{ + return MetaDataBase::cursor( objects.first() ); +} + +void PropertyObject::mdSetPixmapKey( int pixmap, const QString &arg ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setPixmapKey( o, pixmap, arg ); +} + +QString PropertyObject::mdPixmapKey( int pixmap ) +{ + return MetaDataBase::pixmapKey( objects.first(), pixmap ); +} + +void PropertyObject::mdSetExportMacro( const QString ¯o ) +{ + for ( QObject *o = objects.first(); o; o = objects.next() ) + MetaDataBase::setExportMacro( o, macro ); +} + +QString PropertyObject::mdExportMacro() +{ + return MetaDataBase::exportMacro( objects.first() ); +} diff --git a/tools/designer/designer/propertyobject.h b/tools/designer/designer/propertyobject.h new file mode 100644 index 0000000..c844523 --- /dev/null +++ b/tools/designer/designer/propertyobject.h @@ -0,0 +1,43 @@ +#ifndef PROPERTYOBJECT_H +#define PROPERTYOBJECT_H + +#include +#include +#include + +class PropertyObject : public QObject +{ +public: + QMetaObject *metaObject() const { return (QMetaObject*)mobj; } + const char *className() const { return "PropertyObject"; } + QObject* qObject() { return (QObject*)this; } +private: + static QMetaObject *metaObj; + +public: + PropertyObject( const QWidgetList &objs ); + + bool setProperty( const char *name, const QVariant& value ); + QVariant property( const char *name ) const; + + void mdPropertyChanged( const QString &property, bool changed ); + bool mdIsPropertyChanged( const QString &property ); + void mdSetPropertyComment( const QString &property, const QString &comment ); + QString mdPropertyComment( const QString &property ); + void mdSetFakeProperty( const QString &property, const QVariant &value ); + QVariant mdFakeProperty( const QString &property ); + void mdSetCursor( const QCursor &c ); + QCursor mdCursor(); + void mdSetPixmapKey( int pixmap, const QString &arg ); + QString mdPixmapKey( int pixmap ); + void mdSetExportMacro( const QString ¯o ); + QString mdExportMacro(); + QWidgetList widgetList() const { return objects; } + +private: + QWidgetList objects; + const QMetaObject *mobj; + +}; + +#endif diff --git a/tools/designer/designer/qcompletionedit.cpp b/tools/designer/designer/qcompletionedit.cpp new file mode 100644 index 0000000..a293135 --- /dev/null +++ b/tools/designer/designer/qcompletionedit.cpp @@ -0,0 +1,217 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qcompletionedit.h" +#include +#include +#include +#include + +QCompletionEdit::QCompletionEdit( QWidget *parent, const char *name ) + : QLineEdit( parent, name ), aAdd( FALSE ), caseSensitive( FALSE ) +{ + popup = new QVBox( 0, 0, WType_Popup ); + popup->setFrameStyle( QFrame::Box | QFrame::Plain ); + popup->setLineWidth( 1 ); + popup->hide(); + + listbox = new QListBox( popup ); + listbox->setFrameStyle( QFrame::NoFrame ); + listbox->setLineWidth( 1 ); + listbox->installEventFilter( this ); + listbox->setHScrollBarMode( QScrollView::AlwaysOn ); + listbox->setVScrollBarMode( QScrollView::AlwaysOn ); + listbox->setCornerWidget( new QSizeGrip( listbox, "completion sizegrip" ) ); + connect( this, SIGNAL( textChanged( const QString & ) ), + this, SLOT( textDidChange( const QString & ) ) ); + popup->setFocusProxy( listbox ); + installEventFilter( this ); +} + +bool QCompletionEdit::autoAdd() const +{ + return aAdd; +} + +QStringList QCompletionEdit::completionList() const +{ + return compList; +} + +void QCompletionEdit::setCompletionList( const QStringList &l ) +{ + compList = l; +} + +void QCompletionEdit::setAutoAdd( bool add ) +{ + aAdd = add; +} + +void QCompletionEdit::textDidChange( const QString &text ) +{ + if ( text.isEmpty() ) { + popup->close(); + return; + } + updateListBox(); + placeListBox(); +} + +void QCompletionEdit::placeListBox() +{ + if ( listbox->count() == 0 ) { + popup->close(); + return; + } + + popup->resize( QMAX( listbox->sizeHint().width() + listbox->verticalScrollBar()->width() + 4, width() ), + listbox->sizeHint().height() + listbox->horizontalScrollBar()->height() + 4 ); + + QPoint p( mapToGlobal( QPoint( 0, 0 ) ) ); + if ( p.y() + height() + popup->height() <= QApplication::desktop()->height() ) + popup->move( p.x(), p.y() + height() ); + else + popup->move( p.x(), p.y() - listbox->height() ); + popup->show(); + listbox->setCurrentItem( 0 ); + listbox->setSelected( 0, TRUE ); + setFocus(); +} + +void QCompletionEdit::updateListBox() +{ + listbox->clear(); + if ( compList.isEmpty() ) + return; + for ( QStringList::Iterator it = compList.begin(); it != compList.end(); ++it ) { + if ( caseSensitive && (*it).left( text().length() ) == text() || + !caseSensitive && (*it).left( text().length() ).lower() == text().lower() ) + listbox->insertItem( *it ); + } +} + +bool QCompletionEdit::eventFilter( QObject *o, QEvent *e ) +{ + if ( o == popup || o == listbox || o == listbox->viewport() ) { + if ( e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ke->key() == Key_Enter || ke->key() == Key_Return || ke->key() == Key_Tab ) { + if ( ke->key() == Key_Tab && listbox->count() > 1 && + listbox->currentItem() < (int)listbox->count() - 1 ) { + listbox->setCurrentItem( listbox->currentItem() + 1 ); + return TRUE; + } + popup->close(); + setFocus(); + blockSignals( TRUE ); + setText( listbox->currentText() ); + blockSignals( FALSE ); + emit chosen( text() ); + return TRUE; + } else if ( ke->key() == Key_Left || ke->key() == Key_Right || + ke->key() == Key_Up || ke->key() == Key_Down || + ke->key() == Key_Home || ke->key() == Key_End || + ke->key() == Key_Prior || ke->key() == Key_Next ) { + return FALSE; + } else if ( ke->key() == Key_Escape ) { + popup->close(); + setFocus(); + } else if ( ke->key() != Key_Shift && ke->key() != Key_Control && + ke->key() != Key_Alt ) { + updateListBox(); + if ( listbox->count() == 0 || text().length() == 0 ) { + popup->close(); + setFocus(); + } + QApplication::sendEvent( this, e ); + return TRUE; + } + } else if ( e->type() == QEvent::MouseButtonDblClick ) { + popup->close(); + setFocus(); + blockSignals( TRUE ); + setText( listbox->currentText() ); + blockSignals( FALSE ); + emit chosen( text() ); + return TRUE; + } + } else if ( o == this ) { + if ( e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ke->key() == Key_Up || + ke->key() == Key_Down || + ke->key() == Key_Prior || + ke->key() == Key_Next || + ke->key() == Key_Return || + ke->key() == Key_Enter || + ke->key() == Key_Tab || + ke->key() == Key_Escape ) { + QApplication::sendEvent( listbox, e ); + return TRUE; + } + } + } + return QLineEdit::eventFilter( o, e ); +} + +void QCompletionEdit::addCompletionEntry( const QString &entry ) +{ + if ( compList.find( entry ) == compList.end() ) { + compList << entry; + compList.sort(); + } +} + +void QCompletionEdit::removeCompletionEntry( const QString &entry ) +{ + QStringList::Iterator it = compList.find( entry ); + if ( it != compList.end() ) + compList.remove( it ); +} + +void QCompletionEdit::setCaseSensitive( bool b ) +{ + caseSensitive = b; +} + +bool QCompletionEdit::isCaseSensitive() const +{ + return caseSensitive; +} + +void QCompletionEdit::clear() +{ + QLineEdit::clear(); + compList.clear(); +} diff --git a/tools/designer/designer/qcompletionedit.h b/tools/designer/designer/qcompletionedit.h new file mode 100644 index 0000000..514a7f5 --- /dev/null +++ b/tools/designer/designer/qcompletionedit.h @@ -0,0 +1,86 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QCOMPLETIONEDIT_H +#define QCOMPLETIONEDIT_H + +#include +#include + +class QListBox; +class QVBox; + +class QCompletionEdit : public QLineEdit +{ + Q_OBJECT + Q_PROPERTY( bool autoAdd READ autoAdd WRITE setAutoAdd ) + Q_PROPERTY( bool caseSensitive READ isCaseSensitive WRITE setCaseSensitive ) + +public: + QCompletionEdit( QWidget *parent = 0, const char *name = 0 ); + + bool autoAdd() const; + QStringList completionList() const; + bool eventFilter( QObject *o, QEvent *e ); + bool isCaseSensitive() const; + +public slots: + void setCompletionList( const QStringList &l ); + void setAutoAdd( bool add ); + void clear(); + void addCompletionEntry( const QString &entry ); + void removeCompletionEntry( const QString &entry ); + void setCaseSensitive( bool b ); + +signals: + void chosen( const QString &text ); + +private slots: + void textDidChange( const QString &text ); + +private: + void placeListBox(); + void updateListBox(); + +private: + bool aAdd; + QStringList compList; + QListBox *listbox; + QVBox *popup; + bool caseSensitive; + +}; + + + +#endif diff --git a/tools/designer/designer/replacedialog.ui b/tools/designer/designer/replacedialog.ui new file mode 100644 index 0000000..0be991c --- /dev/null +++ b/tools/designer/designer/replacedialog.ui @@ -0,0 +1,325 @@ + +ReplaceDialog +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + ReplaceDialog + + + + 0 + 0 + 286 + 217 + + + + Replace Text + + + + unnamed + + + 11 + + + 6 + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel2 + + + R&eplace + + + comboReplace + + + + + TextLabel1 + + + &Find + + + comboFind + + + + + comboFind + + + + 7 + 0 + 0 + 0 + + + + true + + + + + comboReplace + + + + 7 + 0 + 0 + 0 + + + + true + + + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonReplace + + + &Replace + + + true + + + + + buttonReplaceAll + + + Replace &All + + + + + PushButton2 + + + &Close + + + + + + + ButtonGroup1 + + + Options + + + + unnamed + + + 11 + + + 6 + + + + checkWords + + + &Whole words only + + + + + checkCase + + + Case &sensitive + + + + + checkBegin + + + Start at &Beginning + + + + + + + ButtonGroup2 + + + Direction + + + + unnamed + + + 11 + + + 6 + + + + radioForward + + + Forwar&d + + + true + + + + + radioBackward + + + Bac&kward + + + + + + + + + buttonReplace + clicked() + ReplaceDialog + doReplace() + + + buttonReplaceAll + clicked() + ReplaceDialog + doReplaceAll() + + + PushButton2 + clicked() + ReplaceDialog + reject() + + + + comboFind + comboReplace + checkWords + checkCase + checkBegin + radioForward + radioBackward + buttonReplace + buttonReplaceAll + PushButton2 + + + ../interfaces/editorinterface.h + qlineedit.h + replacedialog.ui.h + + + struct EditorInterface; + + + EditorInterface *editor; + QObject *formWindow; + + + init() + destroy() + doReplace() + doReplaceAll() + setEditor( EditorInterface * e, QObject * fw ) + + + diff --git a/tools/designer/designer/replacedialog.ui.h b/tools/designer/designer/replacedialog.ui.h new file mode 100644 index 0000000..77ed9cc --- /dev/null +++ b/tools/designer/designer/replacedialog.ui.h @@ -0,0 +1,82 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + + +void ReplaceDialog::init() +{ + editor = 0; + formWindow = 0; +} + +void ReplaceDialog::destroy() +{ + if ( editor ) + editor->release(); + editor = 0; + formWindow = 0; +} + +void ReplaceDialog::doReplace() +{ + if ( !editor ) + return; + + if ( !editor->replace( comboFind->currentText(), comboReplace->currentText(), checkCase->isChecked(), + checkWords->isChecked(), radioForward->isChecked(), !checkBegin->isChecked(), FALSE ) ) + checkBegin->setChecked( TRUE ); + else + checkBegin->setChecked( FALSE ); +} + +void ReplaceDialog::doReplaceAll() +{ + if ( !editor ) + return; + + if ( !editor->replace( comboFind->currentText(), comboReplace->currentText(), checkCase->isChecked(), + checkWords->isChecked(), radioForward->isChecked(), !checkBegin->isChecked(), TRUE ) ) + checkBegin->setChecked( TRUE ); + else + checkBegin->setChecked( FALSE ); +} + +void ReplaceDialog::setEditor( EditorInterface * e, QObject * fw ) +{ + if ( fw != formWindow ) + checkBegin->setChecked( TRUE ); + formWindow = fw; + if ( editor ) + editor->release(); + editor = e; + editor->addRef(); +} diff --git a/tools/designer/designer/resource.cpp b/tools/designer/designer/resource.cpp new file mode 100644 index 0000000..257f4e6 --- /dev/null +++ b/tools/designer/designer/resource.cpp @@ -0,0 +1,3359 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "actiondnd.h" +#include "command.h" +#ifndef QT_NO_SQL +#include "database.h" +#endif +#include "formfile.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "menubareditor.h" +#include "metadatabase.h" +#include "pixmapcollection.h" +#include "popupmenueditor.h" +#include "project.h" +#include "resource.h" +#include "widgetfactory.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef QT_NO_TABLE +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static QString makeIndent( int indent ) +{ + QString s; + s.fill( ' ', indent * 4 ); + return s; +} + +static QString entitize( const QString &s, bool attribute = FALSE ) +{ + QString s2 = s; + s2 = s2.replace( "&", "&" ); + s2 = s2.replace( ">", ">" ); + s2 = s2.replace( "<", "<" ); + if ( attribute ) { + s2 = s2.replace( "\"", """ ); + s2 = s2.replace( "'", "'" ); + } + return s2; +} + +#ifdef Q_WS_MACX +static struct { + int key; + const char* name; +} keyname[] = { + { Qt::Key_Space, QT_TRANSLATE_NOOP( "QAccel", "Space" ) }, + { Qt::Key_Escape, QT_TRANSLATE_NOOP( "QAccel", "Esc" ) }, + { Qt::Key_Tab, QT_TRANSLATE_NOOP( "QAccel", "Tab" ) }, + { Qt::Key_Backtab, QT_TRANSLATE_NOOP( "QAccel", "Backtab" ) }, + { Qt::Key_Backspace, QT_TRANSLATE_NOOP( "QAccel", "Backspace" ) }, + { Qt::Key_Return, QT_TRANSLATE_NOOP( "QAccel", "Return" ) }, + { Qt::Key_Enter, QT_TRANSLATE_NOOP( "QAccel", "Enter" ) }, + { Qt::Key_Insert, QT_TRANSLATE_NOOP( "QAccel", "Ins" ) }, + { Qt::Key_Delete, QT_TRANSLATE_NOOP( "QAccel", "Del" ) }, + { Qt::Key_Pause, QT_TRANSLATE_NOOP( "QAccel", "Pause" ) }, + { Qt::Key_Print, QT_TRANSLATE_NOOP( "QAccel", "Print" ) }, + { Qt::Key_SysReq, QT_TRANSLATE_NOOP( "QAccel", "SysReq" ) }, + { Qt::Key_Home, QT_TRANSLATE_NOOP( "QAccel", "Home" ) }, + { Qt::Key_End, QT_TRANSLATE_NOOP( "QAccel", "End" ) }, + { Qt::Key_Left, QT_TRANSLATE_NOOP( "QAccel", "Left" ) }, + { Qt::Key_Up, QT_TRANSLATE_NOOP( "QAccel", "Up" ) }, + { Qt::Key_Right, QT_TRANSLATE_NOOP( "QAccel", "Right" ) }, + { Qt::Key_Down, QT_TRANSLATE_NOOP( "QAccel", "Down" ) }, + { Qt::Key_Prior, QT_TRANSLATE_NOOP( "QAccel", "PgUp" ) }, + { Qt::Key_Next, QT_TRANSLATE_NOOP( "QAccel", "PgDown" ) }, + { Qt::Key_CapsLock, QT_TRANSLATE_NOOP( "QAccel", "CapsLock" ) }, + { Qt::Key_NumLock, QT_TRANSLATE_NOOP( "QAccel", "NumLock" ) }, + { Qt::Key_ScrollLock, QT_TRANSLATE_NOOP( "QAccel", "ScrollLock" ) }, + { Qt::Key_Menu, QT_TRANSLATE_NOOP( "QAccel", "Menu" ) }, + { Qt::Key_Help, QT_TRANSLATE_NOOP( "QAccel", "Help" ) }, + + // Multimedia keys + { Qt::Key_Back, QT_TRANSLATE_NOOP( "QAccel", "Back" ) }, + { Qt::Key_Forward, QT_TRANSLATE_NOOP( "QAccel", "Forward" ) }, + { Qt::Key_Stop, QT_TRANSLATE_NOOP( "QAccel", "Stop" ) }, + { Qt::Key_Refresh, QT_TRANSLATE_NOOP( "QAccel", "Refresh" ) }, + { Qt::Key_VolumeDown, QT_TRANSLATE_NOOP( "QAccel", "Volume Down" ) }, + { Qt::Key_VolumeMute, QT_TRANSLATE_NOOP( "QAccel", "Volume Mute" ) }, + { Qt::Key_VolumeUp, QT_TRANSLATE_NOOP( "QAccel", "Volume Up" ) }, + { Qt::Key_BassBoost, QT_TRANSLATE_NOOP( "QAccel", "Bass Boost" ) }, + { Qt::Key_BassUp, QT_TRANSLATE_NOOP( "QAccel", "Bass Up" ) }, + { Qt::Key_BassDown, QT_TRANSLATE_NOOP( "QAccel", "Bass Down" ) }, + { Qt::Key_TrebleUp, QT_TRANSLATE_NOOP( "QAccel", "Treble Up" ) }, + { Qt::Key_TrebleDown, QT_TRANSLATE_NOOP( "QAccel", "Treble Down" ) }, + { Qt::Key_MediaPlay, QT_TRANSLATE_NOOP( "QAccel", "Media Play" ) }, + { Qt::Key_MediaStop, QT_TRANSLATE_NOOP( "QAccel", "Media Stop" ) }, + { Qt::Key_MediaPrev, QT_TRANSLATE_NOOP( "QAccel", "Media Previous" ) }, + { Qt::Key_MediaNext, QT_TRANSLATE_NOOP( "QAccel", "Media Next" ) }, + { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP( "QAccel", "Media Record" ) }, + { Qt::Key_HomePage, QT_TRANSLATE_NOOP( "QAccel", "Home" ) }, + { Qt::Key_Favorites, QT_TRANSLATE_NOOP( "QAccel", "Favorites" ) }, + { Qt::Key_Search, QT_TRANSLATE_NOOP( "QAccel", "Search" ) }, + { Qt::Key_Standby, QT_TRANSLATE_NOOP( "QAccel", "Standby" ) }, + { Qt::Key_OpenUrl, QT_TRANSLATE_NOOP( "QAccel", "Open URL" ) }, + { Qt::Key_LaunchMail, QT_TRANSLATE_NOOP( "QAccel", "Launch Mail" ) }, + { Qt::Key_LaunchMedia, QT_TRANSLATE_NOOP( "QAccel", "Launch Media" ) }, + { Qt::Key_Launch0, QT_TRANSLATE_NOOP( "QAccel", "Launch (0)" ) }, + { Qt::Key_Launch1, QT_TRANSLATE_NOOP( "QAccel", "Launch (1)" ) }, + { Qt::Key_Launch2, QT_TRANSLATE_NOOP( "QAccel", "Launch (2)" ) }, + { Qt::Key_Launch3, QT_TRANSLATE_NOOP( "QAccel", "Launch (3)" ) }, + { Qt::Key_Launch4, QT_TRANSLATE_NOOP( "QAccel", "Launch (4)" ) }, + { Qt::Key_Launch5, QT_TRANSLATE_NOOP( "QAccel", "Launch (5)" ) }, + { Qt::Key_Launch6, QT_TRANSLATE_NOOP( "QAccel", "Launch (6)" ) }, + { Qt::Key_Launch7, QT_TRANSLATE_NOOP( "QAccel", "Launch (7)" ) }, + { Qt::Key_Launch8, QT_TRANSLATE_NOOP( "QAccel", "Launch (8)" ) }, + { Qt::Key_Launch9, QT_TRANSLATE_NOOP( "QAccel", "Launch (9)" ) }, + { Qt::Key_LaunchA, QT_TRANSLATE_NOOP( "QAccel", "Launch (A)" ) }, + { Qt::Key_LaunchB, QT_TRANSLATE_NOOP( "QAccel", "Launch (B)" ) }, + { Qt::Key_LaunchC, QT_TRANSLATE_NOOP( "QAccel", "Launch (C)" ) }, + { Qt::Key_LaunchD, QT_TRANSLATE_NOOP( "QAccel", "Launch (D)" ) }, + { Qt::Key_LaunchE, QT_TRANSLATE_NOOP( "QAccel", "Launch (E)" ) }, + { Qt::Key_LaunchF, QT_TRANSLATE_NOOP( "QAccel", "Launch (F)" ) }, + + // -------------------------------------------------------------- + // More consistent namings + { Qt::Key_Print, QT_TRANSLATE_NOOP( "QAccel", "Print Screen" ) }, + { Qt::Key_Prior, QT_TRANSLATE_NOOP( "QAccel", "Page Up" ) }, + { Qt::Key_Next, QT_TRANSLATE_NOOP( "QAccel", "Page Down" ) }, + { Qt::Key_CapsLock, QT_TRANSLATE_NOOP( "QAccel", "Caps Lock" ) }, + { Qt::Key_NumLock, QT_TRANSLATE_NOOP( "QAccel", "Num Lock" ) }, + { Qt::Key_NumLock, QT_TRANSLATE_NOOP( "QAccel", "Number Lock" ) }, + { Qt::Key_ScrollLock, QT_TRANSLATE_NOOP( "QAccel", "Scroll Lock" ) }, + { Qt::Key_Insert, QT_TRANSLATE_NOOP( "QAccel", "Insert" ) }, + { Qt::Key_Delete, QT_TRANSLATE_NOOP( "QAccel", "Delete" ) }, + { Qt::Key_Escape, QT_TRANSLATE_NOOP( "QAccel", "Escape" ) }, + { Qt::Key_SysReq, QT_TRANSLATE_NOOP( "QAccel", "System Request" ) }, + + { 0, 0 } +}; +#endif +static QString platformNeutralKeySequence(const QKeySequence &ks) +{ +#ifndef Q_WS_MACX + return QString(ks); +#else + uint k; + QString str; + QString p; + for (k = 0; k < ks.count(); ++k) { + int keycombo = ks[k]; + int basekey = keycombo & ~(Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META); + if (keycombo & Qt::CTRL) + str += "Ctrl+"; + if (keycombo & Qt::ALT) + str += "Alt+"; + if (keycombo & Qt::META) + str += "Meta+"; + if (keycombo & Qt::SHIFT) + str += "Shift+"; + + // begin copy and paste from QKeySequence :( + if (basekey & Qt::UNICODE_ACCEL) { + // Note: This character should NOT be upper()'ed, since + // the encoded string should indicate EXACTLY what the + // key represents! Hence a 'Ctrl+Shift+c' is posible to + // represent, but is clearly impossible to trigger... + p = QChar(basekey & 0xffff); + } else if ( basekey >= Qt::Key_F1 && basekey <= Qt::Key_F35 ) { + p = QAccel::tr( "F%1" ).arg(basekey - Qt::Key_F1 + 1); + } else if ( basekey > Qt::Key_Space && basekey <= Qt::Key_AsciiTilde ) { + p.sprintf( "%c", basekey ); + } else { + int i = 0; + while (keyname[i].name) { + if (basekey == keyname[i].key) { + p = QAccel::tr(keyname[i].name); + break; + } + ++i; + } + // If we can't find the actual translatable keyname, + // fall back on the unicode representation of it... + // Or else characters like Key_aring may not get displayed + // ( Really depends on you locale ) + if ( !keyname[i].name ) + // Note: This character should NOT be upper()'ed, see above! + p = QChar(basekey & 0xffff); + } + // end copy... + str += p + ", "; + } + str.truncate(str.length() - 2); + return str; +#endif +} + +static QString mkBool( bool b ) +{ + return b? "true" : "false"; +} + +/*! + \class Resource resource.h + \brief Class for saving/loading, etc. forms + + This class is used for saving and loading forms, code generation, + transferring data of widgets over the clipboard, etc.. + +*/ + + +Resource::Resource() +{ + mainwindow = 0; + formwindow = 0; + toplevel = 0; + copying = FALSE; + pasting = FALSE; + hadGeometry = FALSE; + langIface = 0; + hasFunctions = FALSE; +} + +Resource::Resource( MainWindow* mw ) + : mainwindow( mw ) +{ + formwindow = 0; + toplevel = 0; + copying = FALSE; + pasting = FALSE; + hadGeometry = FALSE; + langIface = 0; + hasFunctions = FALSE; +} + +Resource::~Resource() +{ + if ( langIface ) + langIface->release(); +} + +void Resource::setWidget( FormWindow *w ) +{ + formwindow = w; + toplevel = w; +} + +QWidget *Resource::widget() const +{ + return toplevel; +} + +bool Resource::load( FormFile *ff, Project *defProject ) +{ + if ( !ff || ff->absFileName().isEmpty() ) + return FALSE; + currFileName = ff->absFileName(); + mainContainerSet = FALSE; + + QFile f( ff->absFileName() ); + f.open( IO_ReadOnly | IO_Translate ); + + bool b = load( ff, &f, defProject ); + f.close(); + + return b; +} + +#undef signals +#undef slots + +bool Resource::load( FormFile *ff, QIODevice* dev, Project *defProject ) +{ + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( dev, &errMsg, &errLine ) ) { + return FALSE; + } + + DomTool::fixDocument( doc ); + + QWidget *p = mainwindow ? mainwindow->qWorkspace() : 0; + toplevel = formwindow = new FormWindow( ff, p, 0 ); + if ( defProject ) + formwindow->setProject( defProject ); + else if ( MainWindow::self ) + formwindow->setProject( MainWindow::self->currProject() ); + if ( mainwindow ) + formwindow->setMainWindow( mainwindow ); + MetaDataBase::addEntry( formwindow ); + + if ( !langIface ) { + QString lang = "Qt Script"; + if ( mainwindow ) + lang = mainwindow->currProject()->language(); + langIface = MetaDataBase::languageInterface( lang ); + if ( langIface ) + langIface->addRef(); + } + + uiFileVersion = doc.firstChild().toElement().attribute("version"); + QDomElement e = doc.firstChild().toElement().firstChild().toElement(); + + QDomElement forwards = e; + while ( forwards.tagName() != "forwards" && !forwards.isNull() ) + forwards = forwards.nextSibling().toElement(); + + QDomElement includes = e; + while ( includes.tagName() != "includes" && !includes.isNull() ) + includes = includes.nextSibling().toElement(); + + QDomElement variables = e; + while ( variables.tagName() != "variables" && !variables.isNull() ) + variables = variables.nextSibling().toElement(); + + QDomElement signals = e; + while ( signals.tagName() != "signals" && !signals.isNull() ) + signals = signals.nextSibling().toElement(); + + QDomElement slots = e; + while ( slots.tagName() != "slots" && !slots.isNull() ) + slots = slots.nextSibling().toElement(); + + QDomElement functions = e; + while ( functions.tagName() != "functions" && !functions.isNull() ) + functions = functions.nextSibling().toElement(); + + QDomElement connections = e; + while ( connections.tagName() != "connections" && !connections.isNull() ) + connections = connections.nextSibling().toElement(); + + QDomElement imageCollection = e; + images.clear(); + while ( imageCollection.tagName() != "images" && !imageCollection.isNull() ) + imageCollection = imageCollection.nextSibling().toElement(); + + QDomElement customWidgets = e; + while ( customWidgets.tagName() != "customwidgets" && !customWidgets.isNull() ) + customWidgets = customWidgets.nextSibling().toElement(); + + QDomElement tabOrder = e; + while ( tabOrder.tagName() != "tabstops" && !tabOrder.isNull() ) + tabOrder = tabOrder.nextSibling().toElement(); + + QDomElement actions = e; + while ( actions.tagName() != "actions" && !actions.isNull() ) + actions = actions.nextSibling().toElement(); + + QDomElement toolbars = e; + while ( toolbars.tagName() != "toolbars" && !toolbars.isNull() ) + toolbars = toolbars.nextSibling().toElement(); + + QDomElement menubar = e; + while ( menubar.tagName() != "menubar" && !menubar.isNull() ) + menubar = menubar.nextSibling().toElement(); + + QDomElement widget; + while ( !e.isNull() ) { + if ( e.tagName() == "widget" ) { + widgets.clear(); + widget = e; + } else if ( e.tagName() == "include" ) { // compatibility with 2.x + MetaDataBase::Include inc; + inc.location = "global"; + if ( e.attribute( "location" ) == "local" ) + inc.location = "local"; + inc.implDecl = "in declaration"; + if ( e.attribute( "impldecl" ) == "in implementation" ) + inc.implDecl = "in implementation"; + inc.header = e.firstChild().toText().data(); + if ( inc.header.right( 5 ) != ".ui.h" ) { + metaIncludes.append( inc ); + } else { + if ( formwindow->formFile() ) + formwindow->formFile()->setCodeFileState( FormFile::Ok ); + } + } else if ( e.tagName() == "comment" ) { + metaInfo.comment = e.firstChild().toText().data(); + } else if ( e.tagName() == "forward" ) { // compatibility with old betas + metaForwards << e.firstChild().toText().data(); + } else if ( e.tagName() == "variable" ) { // compatibility with old betas + MetaDataBase::Variable v; + v.varName = e.firstChild().toText().data(); + v.varAccess = "protected"; + metaVariables << v; + } else if ( e.tagName() == "author" ) { + metaInfo.author = e.firstChild().toText().data(); + } else if ( e.tagName() == "class" ) { + metaInfo.className = e.firstChild().toText().data(); + } else if ( e.tagName() == "pixmapfunction" ) { + if ( formwindow ) { + formwindow->setSavePixmapInline( FALSE ); + formwindow->setSavePixmapInProject( FALSE ); + formwindow->setPixmapLoaderFunction( e.firstChild().toText().data() ); + } + } else if ( e.tagName() == "pixmapinproject" ) { + if ( formwindow ) { + formwindow->setSavePixmapInline( FALSE ); + formwindow->setSavePixmapInProject( TRUE ); + } + } else if ( e.tagName() == "exportmacro" ) { + exportMacro = e.firstChild().toText().data(); + } else if ( e.tagName() == "layoutdefaults" ) { + formwindow->setLayoutDefaultSpacing( e.attribute( "spacing", QString::number( formwindow->layoutDefaultSpacing() ) ).toInt() ); + formwindow->setLayoutDefaultMargin( e.attribute( "margin", QString::number( formwindow->layoutDefaultMargin() ) ).toInt() ); + } else if ( e.tagName() == "layoutfunctions" ) { + formwindow->setSpacingFunction( e.attribute( "spacing" ) ); + formwindow->setMarginFunction( e.attribute( "margin" ) ); + if ( !formwindow->marginFunction().isEmpty() || !formwindow->spacingFunction().isEmpty() ) + formwindow->hasLayoutFunctions( TRUE ); + } + + e = e.nextSibling().toElement(); + } + + if ( !imageCollection.isNull() ) + loadImageCollection( imageCollection ); + if ( !customWidgets.isNull() ) + loadCustomWidgets( customWidgets, this ); + +#if defined (QT_NON_COMMERCIAL) + bool previewMode = MainWindow::self ? MainWindow::self->isPreviewing() : FALSE; + QWidget *w = (QWidget*)createObject( widget, !previewMode ? (QWidget*)formwindow : MainWindow::self ); + if ( !w ) + return FALSE; + if ( previewMode ) + w->reparent( MainWindow::self, Qt::WType_TopLevel, w->pos(), TRUE ); +#else + if ( !createObject( widget, formwindow) ) + return FALSE; +#endif + + if ( !forwards.isNull() ) { + for ( QDomElement n = forwards.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "forward" ) + metaForwards << n.firstChild().toText().data(); + } + + if ( !includes.isNull() ) { + for ( QDomElement n = includes.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "include" ) { + if ( n.tagName() == "include" ) { + MetaDataBase::Include inc; + inc.location = "global"; + if ( n.attribute( "location" ) == "local" ) + inc.location = "local"; + inc.implDecl = "in declaration"; + if ( n.attribute( "impldecl" ) == "in implementation" ) + inc.implDecl = "in implementation"; + inc.header = n.firstChild().toText().data(); + if ( inc.header.right( 5 ) != ".ui.h" ) { + metaIncludes.append( inc ); + } else { + if ( formwindow->formFile() ) + formwindow->formFile()->setCodeFileState( FormFile::Ok ); + } + } + } + } + + if ( !variables.isNull() ) { + for ( QDomElement n = variables.firstChild().toElement(); !n.isNull(); + n = n.nextSibling().toElement() ) { + if ( n.tagName() == "variable" ) { + MetaDataBase::Variable v; + v.varName = n.firstChild().toText().data(); + v.varAccess = n.attribute( "access", "protected" ); + if ( v.varAccess.isEmpty() ) + v.varAccess = "protected"; + metaVariables << v; + } + } + } + if ( !signals.isNull() ) { + for ( QDomElement n = signals.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "signal" ) + metaSignals << n.firstChild().toText().data(); + } + if ( !slots.isNull() ) { + for ( QDomElement n = slots.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "slot" ) { + MetaDataBase::Function function; + function.specifier = n.attribute( "specifier", "virtual" ); + if ( function.specifier.isEmpty() ) + function.specifier = "virtual"; + function.access = n.attribute( "access", "public" ); + if ( function.access.isEmpty() ) + function.access = "public"; + function.language = n.attribute( "language", "C++" ); + function.returnType = n.attribute( "returnType", "void" ); + if ( function.returnType.isEmpty() ) + function.returnType = "void"; + function.type = "slot"; + function.function = n.firstChild().toText().data(); + if ( !MetaDataBase::hasFunction( formwindow, function.function, TRUE ) ) + MetaDataBase::addFunction( formwindow, function.function, function.specifier, + function.access, "slot", function.language, function.returnType ); + else + MetaDataBase::changeFunctionAttributes( formwindow, function.function, function.function, + function.specifier, function.access, + "slot", function.language, + function.returnType ); + } + } + + if ( !functions.isNull() ) { + for ( QDomElement n = functions.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "function" ) { + MetaDataBase::Function function; + function.specifier = n.attribute( "specifier", "virtual" ); + if ( function.specifier.isEmpty() ) + function.specifier = "virtual"; + function.access = n.attribute( "access", "public" ); + if ( function.access.isEmpty() ) + function.access = "public"; + function.type = n.attribute( "type", "function" ); + function.type = "function"; + function.language = n.attribute( "language", "C++" ); + function.returnType = n.attribute( "returnType", "void" ); + if ( function.returnType.isEmpty() ) + function.returnType = "void"; + function.function = n.firstChild().toText().data(); + if ( !MetaDataBase::hasFunction( formwindow, function.function, TRUE ) ) + MetaDataBase::addFunction( formwindow, function.function, function.specifier, + function.access, function.type, function.language, + function.returnType ); + else + MetaDataBase::changeFunctionAttributes( formwindow, function.function, function.function, + function.specifier, function.access, + function.type, function.language, function.returnType ); + } + } + } + + if ( !actions.isNull() ) + loadActions( actions ); + if ( !toolbars.isNull() ) + loadToolBars( toolbars ); + if ( !menubar.isNull() ) + loadMenuBar( menubar ); + + if ( !connections.isNull() ) + loadConnections( connections ); + + if ( !tabOrder.isNull() ) + loadTabOrder( tabOrder ); + + if ( formwindow ) { + MetaDataBase::setIncludes( formwindow, metaIncludes ); + MetaDataBase::setForwards( formwindow, metaForwards ); + MetaDataBase::setVariables( formwindow, metaVariables ); + MetaDataBase::setSignalList( formwindow, metaSignals ); + metaInfo.classNameChanged = metaInfo.className != QString( formwindow->name() ); + MetaDataBase::setMetaInfo( formwindow, metaInfo ); + MetaDataBase::setExportMacro( formwindow->mainContainer(), exportMacro ); + } + + loadExtraSource( formwindow->formFile(), currFileName, langIface, hasFunctions ); + + if ( mainwindow && formwindow ) + mainwindow->insertFormWindow( formwindow ); + + if ( formwindow ) { + formwindow->killAccels( formwindow ); + if ( formwindow->layout() ) + formwindow->layout()->activate(); + if ( hadGeometry ) + formwindow->resize( formwindow->size().expandedTo( formwindow->minimumSize(). + expandedTo( formwindow->minimumSizeHint() ) ) ); + else + formwindow->resize( formwindow->size().expandedTo( formwindow->sizeHint() ) ); + } + + return TRUE; +} + +static bool saveCode( const QString &filename, const QString &code ) +{ + QFile f( filename ); + if ( f.open(IO_WriteOnly | IO_Translate) ) { + QTextStream ts( &f ); + ts << code; + return TRUE; + } + return FALSE; +} + +bool Resource::save( const QString& filename, bool formCodeOnly ) +{ + if ( !formwindow || filename.isEmpty() ) + return FALSE; + if (!langIface) { + QString lang = "Qt Script"; + if ( mainwindow ) + lang = mainwindow->currProject()->language(); + langIface = MetaDataBase::languageInterface( lang ); + if ( langIface ) + langIface->addRef(); + } + if ( formCodeOnly && langIface ) { + if ( saveFormCode(formwindow->formFile(), langIface) ) + return TRUE; + bool breakout = FALSE; + FormFile *ff = formwindow->formFile(); + QString codeFile = ff->project()->makeAbsolute( ff->codeFile() ); + QString filter = langIface->fileFilterList().join(";;"); + while ( !breakout ) { + QString fn = QFileDialog::getSaveFileName( codeFile, filter ); + breakout = fn.isEmpty(); + if ( !breakout ) { + if ( saveCode(fn, ff->code()) ) + return TRUE; + } + } + } + currFileName = filename; + + QFile f( filename ); + if ( !f.open( IO_WriteOnly | IO_Translate ) ) + return FALSE; + bool b = save( &f ); + f.close(); + return b; +} + +bool Resource::save( QIODevice* dev ) +{ + if ( !formwindow ) + return FALSE; + + if ( !langIface ) { + QString lang = "C++"; + if ( mainwindow ) + lang = mainwindow->currProject()->language(); + langIface = MetaDataBase::languageInterface( lang ); + if ( langIface ) + langIface->addRef(); + } + + QTextStream ts( dev ); + ts.setCodec( QTextCodec::codecForName( "UTF-8" ) ); + + ts << "" << endl; + saveMetaInfoBefore( ts, 0 ); + saveObject( formwindow->mainContainer(), 0, ts, 0 ); + if ( ::qt_cast(formwindow->mainContainer()) ) { + saveMenuBar( (QMainWindow*)formwindow->mainContainer(), ts, 0 ); + saveToolBars( (QMainWindow*)formwindow->mainContainer(), ts, 0 ); + } + if ( !MetaDataBase::customWidgets()->isEmpty() && !usedCustomWidgets.isEmpty() ) + saveCustomWidgets( ts, 0 ); + if ( ::qt_cast(formwindow->mainContainer()) ) + saveActions( formwindow->actionList(), ts, 0 ); + if ( !images.isEmpty() ) + saveImageCollection( ts, 0 ); + if ( !MetaDataBase::connections( formwindow ).isEmpty() || + !MetaDataBase::slotList( formwindow ).isEmpty() ) + saveConnections( ts, 0 ); + saveTabOrder( ts, 0 ); + saveMetaInfoAfter( ts, 0 ); + saveIncludeHints( ts, 0 ); + ts << "" << endl; + bool ok = saveFormCode( formwindow->formFile(), langIface ); + images.clear(); + + return ok; +} + +QString Resource::copy() +{ + if ( !formwindow ) + return QString::null; + + copying = TRUE; + QString s; + QTextOStream ts( &s ); + + ts << "" << endl; + QWidgetList widgets = formwindow->selectedWidgets(); + QWidgetList tmp( widgets ); + for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { + QWidget *p = w->parentWidget(); + bool save = TRUE; + while ( p ) { + if ( tmp.findRef( p ) != -1 ) { + save = FALSE; + break; + } + p = p->parentWidget(); + } + if ( save ) + saveObject( w, 0, ts, 0 ); + } + if ( !MetaDataBase::customWidgets()->isEmpty() && !usedCustomWidgets.isEmpty() ) + saveCustomWidgets( ts, 0 ); + if ( !images.isEmpty() ) + saveImageCollection( ts, 0 ); + ts << "" << endl; + + return s; +} + + +void Resource::paste( const QString &cb, QWidget *parent ) +{ + if ( !formwindow ) + return; + mainContainerSet = TRUE; + + pasting = TRUE; + QDomDocument doc; + QString errMsg; + int errLine; + doc.setContent( cb, &errMsg, &errLine ); + + QDomElement firstWidget = doc.firstChild().toElement().firstChild().toElement(); + + QDomElement imageCollection = firstWidget; + images.clear(); + while ( imageCollection.tagName() != "images" && !imageCollection.isNull() ) + imageCollection = imageCollection.nextSibling().toElement(); + + QDomElement customWidgets = firstWidget; + while ( customWidgets.tagName() != "customwidgets" && !customWidgets.isNull() ) + customWidgets = customWidgets.nextSibling().toElement(); + + if ( !imageCollection.isNull() ) + loadImageCollection( imageCollection ); + if ( !customWidgets.isNull() ) + loadCustomWidgets( customWidgets, this ); + + QWidgetList widgets; + formwindow->clearSelection( FALSE ); + formwindow->setPropertyShowingBlocked( TRUE ); + formwindow->clearSelection( FALSE ); + while ( !firstWidget.isNull() ) { + if ( firstWidget.tagName() == "widget" ) { + QWidget *w = (QWidget*)createObject( firstWidget, parent, 0 ); + if ( !w ) + continue; + widgets.append( w ); + int x = w->x() + formwindow->grid().x(); + int y = w->y() + formwindow->grid().y(); + if ( w->x() + w->width() > parent->width() ) + x = QMAX( 0, parent->width() - w->width() ); + if ( w->y() + w->height() > parent->height() ) + y = QMAX( 0, parent->height() - w->height() ); + if ( x != w->x() || y != w->y() ) + w->move( x, y ); + formwindow->selectWidget( w ); + } else if ( firstWidget.tagName() == "spacer" ) { + QWidget *w = createSpacer( firstWidget, parent, 0, firstWidget.tagName() == "vspacer" ? Qt::Vertical : Qt::Horizontal ); + if ( !w ) + continue; + widgets.append( w ); + int x = w->x() + formwindow->grid().x(); + int y = w->y() + formwindow->grid().y(); + if ( w->x() + w->width() > parent->width() ) + x = QMAX( 0, parent->width() - w->width() ); + if ( w->y() + w->height() > parent->height() ) + y = QMAX( 0, parent->height() - w->height() ); + if ( x != w->x() || y != w->y() ) + w->move( x, y ); + formwindow->selectWidget( w ); + } + firstWidget = firstWidget.nextSibling().toElement(); + } + formwindow->setPropertyShowingBlocked( FALSE ); + formwindow->emitShowProperties(); + + PasteCommand *cmd = new PasteCommand( FormWindow::tr( "Paste" ), formwindow, widgets ); + formwindow->commandHistory()->addCommand( cmd ); +} + +void Resource::saveObject( QObject *obj, QDesignerGridLayout* grid, QTextStream &ts, int indent ) +{ + if ( obj && obj->isWidgetType() && ( (QWidget*)obj )->isHidden() ) + return; + QString closeTag; + const char* className = WidgetFactory::classNameOf( obj ); + int classID = WidgetDatabase::idFromClassName( className ); + bool isPlugin = WidgetDatabase::isCustomPluginWidget( classID ); + if ( obj->isWidgetType() ) { + if ( obj->isA("CustomWidget") || isPlugin ) { + usedCustomWidgets << QString( className ); + includeHints << WidgetDatabase::includeFile( classID ); + } + + if ( obj != formwindow && !formwindow->widgets()->find( (QWidget*)obj ) ) + return; // we don't know anything about this thing + + QString attributes; + if ( grid ) { + QDesignerGridLayout::Item item = grid->items[ (QWidget*)obj ]; + attributes += QString(" row=\"") + QString::number(item.row) + "\""; + attributes += QString(" column=\"") + QString::number(item.column) + "\""; + if ( item.rowspan * item.colspan != 1 ) { + attributes += QString(" rowspan=\"") + QString::number(item.rowspan) + "\""; + attributes += QString(" colspan=\"") + QString::number(item.colspan) + "\""; + } + } + + if ( qstrcmp( className, "Spacer" ) == 0 ) { + closeTag = makeIndent( indent ) + "\n"; + ts << makeIndent( indent ) << "" << endl; + ++indent; + } else { + closeTag = makeIndent( indent ) + "\n"; + ts << makeIndent( indent ) << "" << endl; + ++indent; + } + if ( WidgetFactory::hasItems(classID, obj) ) + saveItems( obj, ts, indent ); + saveObjectProperties( obj, ts, indent ); + } else { + // test for other objects we created. Nothing so far. + return; + } + + QDesignerWidgetStack* ws = 0; + + if ( ::qt_cast(obj) ) { + QTabWidget* tw = (QTabWidget*) obj; + QObjectList* tmpl = tw->queryList( "QWidgetStack" ); + QWidgetStack *ws = (QWidgetStack*)tmpl->first(); + QTabBar *tb = ( (QDesignerTabWidget*)obj )->tabBar(); + for ( int i = 0; i < tb->count(); ++i ) { + QTab *t = tb->tabAt( i ); + if ( !t ) + continue; + QWidget *w = ws->widget( t->identifier() ); + if ( !w ) + continue; + if ( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf(w) ) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "" << endl; + ++indent; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( w->name() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( t->text() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "" << endl; + } + delete tmpl; + } else if ( (ws = ::qt_cast(obj)) != 0 ) { + for ( int i = 0; i < ws->count(); ++i ) { + QWidget *w = ws->page( i ); + if ( !w ) + continue; + if ( WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(w)) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "" << endl; + ++indent; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( w->name() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << QString::number(i) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "" << endl; + } + } else if ( ::qt_cast(obj) ) { + QToolBox* tb = (QToolBox*)obj; + for ( int i = 0; i < tb->count(); ++i ) { + QWidget *w = tb->item( i ); + if ( !w ) + continue; + if ( WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(w)) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "" << endl; + ++indent; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( w->name() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + saveEnumProperty( w, "backgroundMode", QVariant::Invalid, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( tb->itemLabel( tb->indexOf(w) ) ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "" << endl; + } + } else if ( ::qt_cast(obj) ) { + QWizard* wiz = (QWizard*)obj; + for ( int i = 0; i < wiz->pageCount(); ++i ) { + QWidget *w = wiz->page( i ); + if ( !w ) + continue; + if ( WidgetDatabase::idFromClassName(WidgetFactory::classNameOf(w)) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "" << endl; + ++indent; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( w->name() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( wiz->title( w ) ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "" << endl; + } + } else if ( ::qt_cast(obj) ) { + saveChildrenOf( ( (QMainWindow*)obj )->centralWidget(), ts, indent ); + } else { + bool saved = FALSE; +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + if ( isPlugin ) { + WidgetInterface *iface = 0; + widgetManager()->queryInterface( className, &iface ); + if ( iface ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + if ( iface2->supportsPages( className ) ) { + QWidgetList containers = iface2->pages( className, (QWidget*)obj ); + if ( !containers.isEmpty() ) { + saved = TRUE; + int i = 0; + for ( QWidget *w = containers.first(); w; w = containers.next(), ++i ) { + if ( WidgetDatabase:: + idFromClassName( WidgetFactory::classNameOf( w ) ) == -1 ) + continue; // we don't know this widget + ts << makeIndent( indent ) << "" << endl; + ++indent; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( w->name() ) + << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" + << entitize( iface2->pageLabel( className, (QWidget*)obj, i ) ) + << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "" << endl; + } + } + } else { + saved = TRUE; + QWidget *w = iface2->containerOfWidget( className, (QWidget*)obj ); + if ( obj != w ) { + ts << makeIndent( indent ) << "" << endl; + ++indent; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( w->name() ) + << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + saveChildrenOf( w, ts, indent ); + --indent; + ts << makeIndent( indent ) << "" << endl; + } + // Create a custom widget and then store it in the database + // so we can save the custom widgets. + MetaDataBase::CustomWidget *cw = new MetaDataBase::CustomWidget; + cw->className = className; + cw->includeFile = WidgetDatabase::includeFile( classID ); + QStrList lst = w->metaObject()->signalNames( TRUE ); + for ( QPtrListIterator it(lst); it.current(); ++it ) + cw->lstSignals.append(it.current()); + + int i; + int total = w->metaObject()->numProperties( TRUE ); + for ( i = 0; i < total; i++ ) { + const QMetaProperty *p = w->metaObject()->property( i, TRUE ); + if ( p->designable(w) ) { + MetaDataBase::Property prop; + prop.property = p->name(); + QString pType = p->type(); + // *sigh* designer types are not normal types + // Handle most cases, the ones it misses are + // probably too difficult to deal with anyway... + if ( pType.startsWith("Q") ) { + pType = pType.right( pType.length() - 1 ); + } else { + pType[0] = pType[0].upper(); + } + prop.type = pType; + cw->lstProperties.append( prop ); + } + } + + total = w->metaObject()->numSlots( TRUE ); + for ( i = 0; i < total; i++ ) { + const QMetaData *md = w->metaObject()->slot( i, TRUE ); + MetaDataBase::Function funky; + // Find out if we have a return type. + if ( md->method->count > 0 ) { + const QUParameter p = md->method->parameters[0]; + if ( p.inOut == QUParameter::InOut ) + funky.returnType = p.type->desc(); + } + + funky.function = md->name; + funky.language = "C++"; + switch ( md->access ) { + case QMetaData::Public: + funky.access = "public"; + break; + case QMetaData::Protected: + funky.access = "protected"; + break; + case QMetaData::Private: + funky.access = "private"; + break; + } + cw->lstSlots.append( funky ); + } + MetaDataBase::addCustomWidget( cw ); + } + iface2->release(); + } + iface->release(); + } + } +#endif // QT_CONTAINER_CUSTOM_WIDGETS + if ( !saved ) + saveChildrenOf( obj, ts, indent ); + } + + indent--; + ts << closeTag; +} + +void Resource::saveItems( QObject *obj, QTextStream &ts, int indent ) +{ + if ( ::qt_cast(obj) || ::qt_cast(obj) ) { + QListBox *lb = 0; + if ( ::qt_cast(obj) ) { + lb = (QListBox*)obj; + } else { + QComboBox *cb = (QComboBox*)obj; + lb = cb->listBox(); + if (!lb) { + QPopupMenu *popup = (QPopupMenu*)cb->child( 0, "QPopupMenu" ); + Q_ASSERT(popup); + for ( int id = 0; id < (int)popup->count(); ++id ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + QStringList text; + text << popup->text(id); + QPtrList pixmaps; + if ( popup->pixmap(id) ) + pixmaps.append( popup->pixmap(id) ); + saveItem( text, pixmaps, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } + } + + if (lb) { + QListBoxItem *i = lb->firstItem(); + for ( ; i; i = i->next() ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + QStringList text; + text << i->text(); + QPtrList pixmaps; + if ( i->pixmap() ) + pixmaps.append( i->pixmap() ); + saveItem( text, pixmaps, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } + + } else if ( ::qt_cast(obj) ) { + QIconView *iv = (QIconView*)obj; + + QIconViewItem *i = iv->firstItem(); + for ( ; i; i = i->nextItem() ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + QStringList text; + text << i->text(); + QPtrList pixmaps; + if ( i->pixmap() ) + pixmaps.append( i->pixmap() ); + saveItem( text, pixmaps, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } else if ( ::qt_cast(obj) ) { + QListView *lv = (QListView*)obj; + int i; + for ( i = 0; i < lv->header()->count(); ++i ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + QStringList l; + l << lv->header()->label( i ); + QPtrList pix; + pix.setAutoDelete( TRUE ); + if ( lv->header()->iconSet( i ) ) + pix.append( new QPixmap( lv->header()->iconSet( i )->pixmap() ) ); + saveItem( l, pix, ts, indent ); + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << mkBool( lv->header()->isClickEnabled( i ) )<< "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << mkBool( lv->header()->isResizeEnabled( i ) ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } + saveItem( lv->firstChild(), ts, indent - 1 ); + } +#if !defined (QT_NO_TABLE) + else if ( ::qt_cast(obj) ) { + QTable *table = (QTable*)obj; + int i; + QMap columnFields = MetaDataBase::columnFields( table ); +# ifndef QT_NO_SQL + bool isDataTable = ::qt_cast(table); +# else + bool isDataTable = false; +# endif + for ( i = 0; i < table->horizontalHeader()->count(); ++i ) { + if ( !table->horizontalHeader()->label( i ).isNull() && + table->horizontalHeader()->label( i ).toInt() != i + 1 || + table->horizontalHeader()->iconSet( i ) || + isDataTable ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + QStringList l; + l << table->horizontalHeader()->label( i ); + QPtrList pix; + pix.setAutoDelete( TRUE ); + if ( table->horizontalHeader()->iconSet( i ) ) + pix.append( new QPixmap( table->horizontalHeader()->iconSet( i )->pixmap() ) ); + saveItem( l, pix, ts, indent ); + if ( isDataTable && !columnFields.isEmpty() ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( *columnFields.find( l[ 0 ] ) ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } + for ( i = 0; i < table->verticalHeader()->count(); ++i ) { + if ( !table->verticalHeader()->label( i ).isNull() && + table->verticalHeader()->label( i ).toInt() != i + 1 || + table->verticalHeader()->iconSet( i ) ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + QStringList l; + l << table->verticalHeader()->label( i ); + QPtrList pix; + pix.setAutoDelete( TRUE ); + if ( table->verticalHeader()->iconSet( i ) ) + pix.append( new QPixmap( table->verticalHeader()->iconSet( i )->pixmap() ) ); + saveItem( l, pix, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } + } +#endif +} + +void Resource::saveItem( QListViewItem *i, QTextStream &ts, int indent ) +{ + QListView *lv = i->listView(); + while ( i ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + + QPtrList pixmaps; + QStringList textes; + for ( int c = 0; c < lv->columns(); ++c ) { + pixmaps.append( i->pixmap( c ) ); + textes << i->text( c ); + } + saveItem( textes, pixmaps, ts, indent ); + + if ( i->firstChild() ) + saveItem( i->firstChild(), ts, indent ); + + indent--; + ts << makeIndent( indent ) << "" << endl; + i = i->nextSibling(); + } +} + +void Resource::savePixmap( const QPixmap &p, QTextStream &ts, int indent, const QString &tagname ) +{ + if ( p.isNull() ) { + ts << makeIndent( indent ) << "<" << tagname << ">" << endl; + return; + } + + if ( formwindow && formwindow->savePixmapInline() ) + ts << makeIndent( indent ) << "<" << tagname << ">" << saveInCollection( p ) << "" << endl; + else if ( formwindow && formwindow->savePixmapInProject() ) + ts << makeIndent( indent ) << "<" << tagname << ">" << MetaDataBase::pixmapKey( formwindow, p.serialNumber() ) + << "" << endl; + else + ts << makeIndent( indent ) << "<" << tagname << ">" << MetaDataBase::pixmapArgument( formwindow, p.serialNumber() ) + << "" << endl; +} + +QPixmap Resource::loadPixmap( const QDomElement &e, const QString &/*tagname*/ ) +{ + QString arg = e.firstChild().toText().data(); + + if ( formwindow && formwindow->savePixmapInline() ) { + QImage img = loadFromCollection( arg ); + QPixmap pix; + pix.convertFromImage( img ); + MetaDataBase::setPixmapArgument( formwindow, pix.serialNumber(), arg ); + return pix; + } else if ( formwindow && formwindow->savePixmapInProject() ) { + QPixmap pix; + if ( mainwindow && mainwindow->currProject() ) { + pix = mainwindow->currProject()->pixmapCollection()->pixmap( arg ); + } else { + pix = QPixmap::fromMimeSource( "designer_image.png" ); + // we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that + pix.convertFromImage( pix.convertToImage() ); + } + + MetaDataBase::setPixmapKey( formwindow, pix.serialNumber(), arg ); + return pix; + } + QPixmap pix = QPixmap::fromMimeSource( "designer_image.png" ); + // we have to force the pixmap to get a new and unique serial number. Unfortunately detatch() doesn't do that + pix.convertFromImage( pix.convertToImage() ); + MetaDataBase::setPixmapArgument( formwindow, pix.serialNumber(), arg ); + return pix; +} + +void Resource::saveItem( const QStringList &text, + const QPtrList &pixmaps, QTextStream &ts, + int indent ) +{ + QStringList::ConstIterator it = text.begin(); + for ( ; it != text.end(); ++it ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( *it ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } + + for ( int i = 0; i < (int)pixmaps.count(); ++i ) { + QPixmap *p = ( (QPtrList)pixmaps ).at( i ); + ts << makeIndent( indent ) << "" << endl; + indent++; + if ( p ) + savePixmap( *p, ts, indent ); + else + savePixmap( QPixmap(), ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } +} + +void Resource::saveChildrenOf( QObject* obj, QTextStream &ts, int indent ) +{ + const QObjectList *l = obj->children(); + if ( !l ) + return; // no children to save + + QString closeTag; + // if the widget has a layout we pretend that all widget's childs are childs of the layout - makes the structure nicer + QLayout *layout = 0; + QDesignerGridLayout* grid = 0; + if ( !::qt_cast(obj) && + WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( obj ) ) ) && + obj->isWidgetType() && + WidgetFactory::layoutType( (QWidget*)obj, layout ) != WidgetFactory::NoLayout ) { + WidgetFactory::LayoutType lay = WidgetFactory::layoutType( (QWidget*)obj, layout ); + switch ( lay ) { + case WidgetFactory::HBox: + closeTag = makeIndent( indent ) + ""; + ts << makeIndent( indent ) << "" << endl; + ++indent; + break; + case WidgetFactory::VBox: + closeTag = makeIndent( indent ) + ""; + ts << makeIndent( indent ) << "" << endl; + ++indent; + break; + case WidgetFactory::Grid: + closeTag = makeIndent( indent ) + ""; + ts << makeIndent( indent ) << "" << endl; + ++indent; + grid = (QDesignerGridLayout*) layout; + break; + default: + break; + } + + // save properties of layout + if ( lay != WidgetFactory::NoLayout ) + saveObjectProperties( layout, ts, indent ); + + } + + QObject *o = 0; + for ( QPtrListIterator it ( *l ); ( o = it.current() ); ++it ) + if ( !QString( o->name() ).startsWith( "qt_dead_widget_" ) ) + saveObject( o, grid, ts, indent ); + if ( !closeTag.isEmpty() ) { + indent--; + ts << closeTag << endl; + } +} + +void Resource::saveObjectProperties( QObject *w, QTextStream &ts, int indent ) +{ + QStringList saved; + QStringList changed; + changed = MetaDataBase::changedProperties( w ); + if ( w->isWidgetType() ) { + if ( ::qt_cast(w) ) { + if ( !changed.contains( "sizeHint" ) ) + changed << "sizeHint"; + if ( !changed.contains( "geometry" ) ) + changed << "geometry"; + } else { + QToolButton *tb = ::qt_cast(w); + if ( tb && !tb->iconSet().isNull() ) { + changed << "iconSet"; + } + } + } else if ( ::qt_cast(w) ) { + if ( MetaDataBase::spacing( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ) > -1 ) + changed << "spacing"; + if ( MetaDataBase::margin( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ) > -1 ) + changed << "margin"; + if ( MetaDataBase::resizeMode( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ) != "Auto" + && !MetaDataBase::resizeMode( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ).isEmpty() ) + changed << "resizeMode"; + } + + if ( w == formwindow->mainContainer() ) { + if ( changed.findIndex( "geometry" ) == -1 ) + changed << "geometry"; + if ( changed.findIndex( "caption" ) == -1 ) + changed << "caption"; + } + + if ( changed.isEmpty() ) + return; + + bool inLayout = w != formwindow->mainContainer() && !copying && w->isWidgetType() && ( (QWidget*)w )->parentWidget() && + WidgetFactory::layoutType( ( (QWidget*)w )->parentWidget() ) != WidgetFactory::NoLayout; + + QStrList lst = w->metaObject()->propertyNames( !::qt_cast(w) ); + for ( QPtrListIterator it( lst ); it.current(); ++it ) { + if ( changed.find( QString::fromLatin1( it.current() ) ) == changed.end() ) + continue; + if ( saved.find( QString::fromLatin1( it.current() ) ) != saved.end() ) + continue; + saved << QString::fromLatin1( it.current() ); + const QMetaProperty* p = w->metaObject()-> + property( w->metaObject()->findProperty( it.current(), TRUE ), TRUE ); + if ( !p || !p->stored( w ) || ( inLayout && qstrcmp( p->name(), "geometry" ) == 0 ) ) + continue; + if ( ::qt_cast(w) && qstrcmp( p->name(), "pixmap" ) == 0 && + ( !( (QLabel*)w )->pixmap() || ( (QLabel*)w )->pixmap()->isNull() ) ) + continue; + if ( ::qt_cast(w) && + ( qstrcmp( p->name(), "itemName" ) == 0 || qstrcmp( p->name(), "itemNumber" ) == 0 || + qstrcmp( p->name(), "itemText" ) == 0 ) ) + continue; + if ( qstrcmp( p->name(), "name" ) == 0 ) + knownNames << w->property( "name" ).toString(); + if ( !p->isSetType() && !p->isEnumType() && !w->property( p->name() ).isValid() ) + continue; + ts << makeIndent( indent ) << "stdSet() ) + ts << " stdset=\"0\""; + ts << ">" << endl; + indent++; + if ( strcmp( it.current(), "resizeMode" ) == 0 && ::qt_cast(w) ) { + saveProperty( w, it.current(), "", QVariant::String, ts, indent ); + } else if ( p->isSetType() ) { + saveSetProperty( w, it.current(), QVariant::nameToType( p->type() ), ts, indent ); + } else if ( p->isEnumType() ) { + saveEnumProperty( w, it.current(), QVariant::nameToType( p->type() ), ts, indent ); + } else { + saveProperty( w, it.current(), w->property( p->name() ), QVariant::nameToType( p->type() ), ts, indent ); + } + indent--; + ts << makeIndent( indent ) << "
    " << endl; + } + + if ( w->isWidgetType() && MetaDataBase::fakeProperties( w ) ) { + QMap* fakeProperties = MetaDataBase::fakeProperties( w ); + for ( QMap::Iterator fake = fakeProperties->begin(); + fake != fakeProperties->end(); ++fake ) { + if ( MetaDataBase::isPropertyChanged( w, fake.key() ) ) { + if ( w->inherits("CustomWidget") ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)w )->customWidget(); + if ( cw && !cw->hasProperty( fake.key().latin1() ) && fake.key() != "toolTip" && fake.key() != "whatsThis" ) + continue; + } + + ts << makeIndent( indent ) << "" << endl; + indent++; + saveProperty( w, fake.key(), *fake, (*fake).type(), ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } + } +} + +void Resource::saveSetProperty( QObject *w, const QString &name, QVariant::Type, QTextStream &ts, int indent ) +{ + const QMetaProperty *p = w->metaObject()->property( w->metaObject()->findProperty( name, TRUE ), TRUE ); + QStrList l( p->valueToKeys( w->property( name ).toInt() ) ); + QString v; + for ( uint i = 0; i < l.count(); ++i ) { + v += l.at( i ); + if ( i < l.count() - 1 ) + v += "|"; + } + ts << makeIndent( indent ) << "" << v << "" << endl; +} + +void Resource::saveEnumProperty( QObject *w, const QString &name, QVariant::Type, QTextStream &ts, int indent ) +{ + const QMetaProperty *p = w->metaObject()->property( w->metaObject()->findProperty( name, TRUE ), TRUE ); + int value = w->property( name ).toInt(); + const char* key = p->valueToKey( value ); + if (key) + ts << makeIndent( indent ) << "" << key << "" << endl; +} + +void Resource::saveProperty( QObject *w, const QString &name, const QVariant &value, QVariant::Type t, QTextStream &ts, int indent ) +{ + if ( name == "hAlign" || name =="vAlign" || name == "wordwrap" || + name == "layoutMargin" || name =="layoutSpacing" ) + return; + int num; + uint unum; + double dob; + QString comment; + if ( w && formwindow->widgets()->find( (QWidget*)w ) || formwindow->actionList().find( (QAction*)w ) ) + comment = MetaDataBase::propertyComment( w, name ); + switch ( t ) { + case QVariant::String: + if ( name == "resizeMode" ) { + QString resmod = MetaDataBase::resizeMode( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ); + if ( !resmod.isNull() && resmod != "Auto" ) { + ts << makeIndent( indent ) << ""; + ts << resmod; + ts << "" << endl; + } + + } else { + ts << makeIndent( indent ) << "" << entitize( value.toString() ) << "" << endl; + if ( !comment.isEmpty() ) + ts << makeIndent( indent ) << "" << entitize( comment ) << "" << endl; + } + break; + case QVariant::CString: + ts << makeIndent( indent ) << "" << entitize( value.toCString() ).latin1() << "" << endl; + break; + case QVariant::Bool: + ts << makeIndent( indent ) << "" << mkBool( value.toBool() ) << "" << endl; + break; + case QVariant::Int: + if ( ::qt_cast(w) ) { + num = -1; + if ( name == "spacing" ) + num = MetaDataBase::spacing( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ); + else if ( name == "margin" ) + num = MetaDataBase::margin( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)w ) ) ); + if ( num != -1 ) + ts << makeIndent( indent ) << "" << QString::number( num ) << "" << endl; + } else { + num = value.toInt(); + ts << makeIndent( indent ) << "" << QString::number( num ) << "" << endl; + } + break; + case QVariant::Double: + dob = value.toDouble(); + ts << makeIndent( indent ) << "" << QString::number( dob ) << "" << endl; + break; + case QVariant::KeySequence: + ts << makeIndent( indent ) << "" + << entitize(platformNeutralKeySequence(value.toKeySequence())) << "" << endl; + break; + case QVariant::UInt: + unum = value.toUInt(); + ts << makeIndent( indent ) << "" << QString::number( unum ) << "" << endl; + break; + case QVariant::Rect: { + QVariant v( value ); + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << QString::number( v.toRect().x() ) << "" << endl; + ts << makeIndent( indent ) << "" << QString::number( v.toRect().y() ) << "" << endl; + ts << makeIndent( indent ) << "" << QString::number( v.toRect().width() ) << "" << endl; + ts << makeIndent( indent ) << "" << QString::number( v.toRect().height() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } break; + case QVariant::Point: { + QVariant v( value ); + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << QString::number( v.toPoint().x() ) << "" << endl; + ts << makeIndent( indent ) << "" << QString::number( v.toPoint().y() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } break; + case QVariant::Size: { + QVariant v( value ); + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << QString::number( v.toSize().width() ) << "" << endl; + ts << makeIndent( indent ) << "" << QString::number( v.toSize().height() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } break; + case QVariant::Color: { + QVariant v( value ); + ts << makeIndent( indent ) << "" << endl; + indent++; + saveColor( ts, indent, v.toColor() ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } break; + case QVariant::Font: { + QVariant v( value ); + ts << makeIndent( indent ) << "" << endl; + QFont f( qApp->font() ); + if ( w && w->isWidgetType() && ((QWidget*)w)->parentWidget() ) + f = ((QWidget*)w)->parentWidget()->font(); + QFont f2( v.toFont() ); + indent++; + if ( f.family() != f2.family() ) + ts << makeIndent( indent ) << "" << f2.family() << "" << endl; + if ( f.pointSize() != f2.pointSize() ) + ts << makeIndent( indent ) << "" << QString::number( f2.pointSize() ) << "" << endl; + if ( f.bold() != f2.bold() ) + ts << makeIndent( indent ) << "" << QString::number( (int)f2.bold() ) << "" << endl; + if ( f.italic() != f2.italic() ) + ts << makeIndent( indent ) << "" << QString::number( (int)f2.italic() ) << "" << endl; + if ( f.underline() != f2.underline() ) + ts << makeIndent( indent ) << "" << QString::number( (int)f2.underline() ) << "" << endl; + if ( f.strikeOut() != f2.strikeOut() ) + ts << makeIndent( indent ) << "" << QString::number( (int)f2.strikeOut() ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } break; + case QVariant::SizePolicy: { + QSizePolicy sp( value.toSizePolicy() ); + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << (int)sp.horData() << "" << endl; + ts << makeIndent( indent ) << "" << (int)sp.verData() << "" << endl; + ts << makeIndent( indent ) << "" << (int)sp.horStretch() << "" << endl; + ts << makeIndent( indent ) << "" << (int)sp.verStretch() << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + break; + } + case QVariant::Pixmap: + savePixmap( value.toPixmap(), ts, indent ); + break; + case QVariant::IconSet: + savePixmap( value.toIconSet().pixmap(), ts, indent, "iconset" ); + break; + case QVariant::Image: + ts << makeIndent( indent ) << "" << saveInCollection( value.toImage() ) << "" << endl; + break; + case QVariant::Palette: { + QPalette p( value.toPalette() ); + ts << makeIndent( indent ) << "" << endl; + indent++; + + ts << makeIndent( indent ) << "" << endl; + indent++; + saveColorGroup( ts, indent, p.active() ); + indent--; + ts << makeIndent( indent ) << "" << endl; + + ts << makeIndent( indent ) << "" << endl; + indent++; + saveColorGroup( ts, indent, p.disabled() ); + indent--; + ts << makeIndent( indent ) << "" << endl; + + ts << makeIndent( indent ) << "" << endl; + indent++; + saveColorGroup( ts, indent, p.inactive() ); + indent--; + ts << makeIndent( indent ) << "" << endl; + + indent--; + ts << makeIndent( indent ) << "" << endl; + } break; + case QVariant::Cursor: + ts << makeIndent( indent ) << "" << value.toCursor().shape() << "" << endl; + break; + case QVariant::StringList: { + QStringList lst = value.toStringList(); + uint i = 0; + ts << makeIndent( indent ) << "" << endl; + indent++; + if ( !lst.isEmpty() ) { + for ( i = 0; i < lst.count(); ++i ) + ts << makeIndent( indent ) << "" << entitize( lst[ i ] ) << "" << endl; + } + indent--; + ts << makeIndent( indent ) << "" << endl; + } break; + case QVariant::Date: { + QDate d = value.toDate(); + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << d.year() << "" << endl; + ts << makeIndent( indent ) << "" << d.month() << "" << endl; + ts << makeIndent( indent ) << "" << d.day() << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + break; + } + case QVariant::Time: { + QTime t = value.toTime(); + ts << makeIndent( indent ) << "" << endl; + break; + } + case QVariant::DateTime: { + QDateTime dt = value.toDateTime(); + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << dt.date().year() << "" << endl; + ts << makeIndent( indent ) << "" << dt.date().month() << "" << endl; + ts << makeIndent( indent ) << "" << dt.date().day() << "" << endl; + ts << makeIndent( indent ) << "" << dt.time().hour() << "" << endl; + ts << makeIndent( indent ) << "" << dt.time().minute() << "" << endl; + ts << makeIndent( indent ) << "" << dt.time().second() << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + break; + } + default: + qWarning( "saving the property %s of type %d not supported yet", name.latin1(), (int)t ); + } +} + +void Resource::saveColorGroup( QTextStream &ts, int indent, const QColorGroup &cg ) +{ + for( int r = 0 ; r < QColorGroup::NColorRoles ; r++ ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + saveColor( ts, indent, cg.color( (QColorGroup::ColorRole)r ) ); + indent--; + ts << makeIndent( indent ) << "" << endl; + QPixmap* pm = cg.brush( (QColorGroup::ColorRole)r ).pixmap(); + if ( pm && !pm->isNull() ) + savePixmap( *pm, ts, indent ); + } +} + +void Resource::saveColor( QTextStream &ts, int indent, const QColor &c ) +{ + ts << makeIndent( indent ) << "" << QString::number( c.red() ) << "" << endl; + ts << makeIndent( indent ) << "" << QString::number( c.green() ) << "" << endl; + ts << makeIndent( indent ) << "" << QString::number( c.blue() ) << "" << endl; +} + +QObject *Resource::createObject( const QDomElement &e, QWidget *parent, QLayout* layout ) +{ + lastItem = 0; + QDomElement n = e.firstChild().toElement(); + QWidget *w = 0; // the widget that got created + QObject *obj = 0; // gets the properties + + int row = e.attribute( "row" ).toInt(); + int col = e.attribute( "column" ).toInt(); + int rowspan = e.attribute( "rowspan" ).toInt(); + int colspan = e.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + + QString className = e.attribute( "class", "QWidget" ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + QString parentClassName = WidgetFactory::classNameOf( parent ); + bool isPlugin = + WidgetDatabase::isCustomPluginWidget( WidgetDatabase::idFromClassName( parentClassName ) ); + if ( isPlugin ) + qWarning( "####### loading custom container widgets without page support not implemented!" ); + // ### TODO loading for custom container widgets without pages +#endif + if ( !className.isNull() ) { + obj = WidgetFactory::create( WidgetDatabase::idFromClassName( className ), parent, 0, FALSE ); + if ( !obj ) { + QMessageBox::critical( MainWindow::self, MainWindow::tr( "Loading File" ), + MainWindow::tr( "Error loading %1.\n" + "The widget %2 couldn't be created.\n" + "Information may be lost if this form is saved." ). + arg( currFileName ).arg( className ) ); + return 0; + } + if ( !mainContainerSet ) { + if ( formwindow ) + formwindow->setMainContainer( (QWidget*)obj ); + mainContainerSet = TRUE; + } + w = (QWidget*)obj; + if ( ::qt_cast(w) ) + w = ( (QMainWindow*)w )->centralWidget(); + if ( layout ) { + switch ( WidgetFactory::layoutType( layout ) ) { + case WidgetFactory::HBox: + ( (QHBoxLayout*)layout )->addWidget( w ); + break; + case WidgetFactory::VBox: + ( (QVBoxLayout*)layout )->addWidget( w ); + break; + case WidgetFactory::Grid: + ( (QDesignerGridLayout*)layout )->addMultiCellWidget( w, row, row + rowspan - 1, + col, col + colspan - 1 ); + break; + default: + break; + } + } + + if ( !toplevel ) + toplevel = w; + layout = 0; + + if ( w && formwindow ) { + if ( !parent || + ( !::qt_cast(parent) && + !::qt_cast(parent) && + !::qt_cast(parent) && + !::qt_cast(parent) +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + && !isPlugin +#endif + ) ) + formwindow->insertWidget( w, pasting ); + else if ( parent && + ( ::qt_cast(parent) || + ::qt_cast(parent) || + ::qt_cast(parent) || + ::qt_cast(parent) +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + || isPlugin +#endif + ) ) + MetaDataBase::addEntry( w ); + } + } + + QDomElement sizePolicyElement; + QObject *sizePolicyObject = 0; + + while ( !n.isNull() ) { + if ( n.tagName() == "spacer" ) { + createSpacer( n, w, layout, Qt::Horizontal ); + } else if ( n.tagName() == "widget" ) { + createObject( n, w, layout ); + } else if ( n.tagName() == "hbox" ) { + layout = WidgetFactory::createLayout( w, layout, WidgetFactory::HBox ); + obj = layout; + n = n.firstChild().toElement(); + continue; + } else if ( n.tagName() == "grid" ) { + layout = WidgetFactory::createLayout( w, layout, WidgetFactory::Grid ); + obj = layout; + n = n.firstChild().toElement(); + continue; + } else if ( n.tagName() == "vbox" ) { + layout = WidgetFactory::createLayout( w, layout, WidgetFactory::VBox ); + obj = layout; + n = n.firstChild().toElement(); + continue; + } else if ( n.tagName() == "property" && obj ) { + if ( n.attribute( "name" ) == "sizePolicy" ) { + // ### Evil hack ### Delay setting sizePolicy so it won't be overridden by other properties. + sizePolicyElement = n; + sizePolicyObject = obj; + } else { + setObjectProperty( obj, n.attribute( "name" ), n.firstChild().toElement() ); + } + } else if ( n.tagName() == "attribute" && w ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( ::qt_cast(parent) ) { + if ( attrib == "title" ) + ( (QTabWidget*)parent )->insertTab( w, v.toString() ); + } else if ( ::qt_cast(parent) ) { + if ( attrib == "id" ) + ( (QDesignerWidgetStack*)parent )->insertPage( w, v.toInt() ); + } else if ( ::qt_cast(parent) ) { + if ( attrib == "label" ) + ( (QToolBox*)parent )->addItem( w, v.toString() ); + } else if ( ::qt_cast(parent) ) { + if ( attrib == "title" ) + ( (QWizard*)parent )->addPage( w, v.toString() ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } else if ( isPlugin ) { + if ( attrib == "label" ) { + WidgetInterface *iface = 0; + widgetManager()->queryInterface( parentClassName, &iface ); + if ( iface ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + iface2->insertPage( parentClassName, + (QWidget*)parent, v.toString(), -1, w ); + iface2->release(); + } + iface->release(); + } + } +#endif // QT_CONTAINER_CUSTOM_WIDGETS + } + } else if ( n.tagName() == "item" ) { + createItem( n, w ); + } else if ( n.tagName() == "column" || n.tagName() =="row" ) { + createColumn( n, w ); + } + + n = n.nextSibling().toElement(); + } + + // ### Evil hack ### See description above. + if ( !sizePolicyElement.isNull() ) { + setObjectProperty( sizePolicyObject, + sizePolicyElement.attribute( "name" ), + sizePolicyElement.firstChild().toElement() ); + } + + if ( w->isWidgetType() ) + widgets.insert( w->name(), w ); + + return w; +} + +void Resource::createColumn( const QDomElement &e, QWidget *widget ) +{ + if ( !widget ) + return; + + if ( ::qt_cast(widget) && e.tagName() == "column" ) { + QListView *lv = (QListView*)widget; + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + bool clickable = TRUE, resizable = TRUE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + txt = v.toString(); + else if ( attrib == "pixmap" ) { + pix = loadPixmap( n.firstChild().toElement().toElement() ); + hasPixmap = !pix.isNull(); + } else if ( attrib == "clickable" ) + clickable = v.toBool(); + else if ( attrib == "resizable" ) + resizable = v.toBool(); + } + n = n.nextSibling().toElement(); + } + lv->addColumn( txt ); + int i = lv->header()->count() - 1; + if ( hasPixmap ) { + lv->header()->setLabel( i, pix, txt ); + } + if ( !clickable ) + lv->header()->setClickEnabled( clickable, i ); + if ( !resizable ) + lv->header()->setResizeEnabled( resizable, i ); + } +#ifndef QT_NO_TABLE + else if ( ::qt_cast(widget) ) { + QTable *table = (QTable*)widget; + bool isRow; + if ( ( isRow = e.tagName() == "row" ) ) + table->setNumRows( table->numRows() + 1 ); + else + table->setNumCols( table->numCols() + 1 ); + + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + QString field; + QMap fieldMap = MetaDataBase::columnFields( table ); + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + txt = v.toString(); + else if ( attrib == "pixmap" ) { + hasPixmap = !n.firstChild().firstChild().toText().data().isEmpty(); + if ( hasPixmap ) + pix = loadPixmap( n.firstChild().toElement() ); + } else if ( attrib == "field" ) + field = v.toString(); + } + n = n.nextSibling().toElement(); + } + + int i = isRow ? table->numRows() - 1 : table->numCols() - 1; + QHeader *h = !isRow ? table->horizontalHeader() : table->verticalHeader(); + if ( hasPixmap ) + h->setLabel( i, pix, txt ); + else + h->setLabel( i, txt ); + if ( !isRow && !field.isEmpty() ) + fieldMap.insert( txt, field ); + MetaDataBase::setColumnFields( table, fieldMap ); + } +#endif +} + +void Resource::loadItem( const QDomElement &e, QPixmap &pix, QString &txt, bool &hasPixmap ) +{ + QDomElement n = e; + hasPixmap = FALSE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + txt = v.toString(); + else if ( attrib == "pixmap" ) { + pix = loadPixmap( n.firstChild().toElement() ); + hasPixmap = !pix.isNull(); + } + } + n = n.nextSibling().toElement(); + } +} + +void Resource::createItem( const QDomElement &e, QWidget *widget, QListViewItem *i ) +{ + if ( !widget || !WidgetFactory::hasItems( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( widget ) ), widget ) ) + return; + + if ( ::qt_cast(widget) || ::qt_cast(widget) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + loadItem( n, pix, txt, hasPixmap ); + QListBox *lb = 0; + if ( ::qt_cast(widget) ) { + lb = (QListBox*)widget; + } else { + QComboBox *cb = (QComboBox*)widget; + lb = cb->listBox(); + if (!lb) { + lb = new QListBox(cb); + cb->setListBox(lb); + } + } + if ( hasPixmap ) { + new QListBoxPixmap( lb, pix, txt ); + } else { + new QListBoxText( lb, txt ); + } + } else if ( ::qt_cast(widget) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + loadItem( n, pix, txt, hasPixmap ); + QIconView *iv = (QIconView*)widget; + if ( hasPixmap ) + new QIconViewItem( iv, txt, pix ); + else + new QIconViewItem( iv, txt ); + } else if ( ::qt_cast(widget) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + QValueList pixmaps; + QStringList textes; + QListViewItem *item = 0; + QListView *lv = (QListView*)widget; + if ( i ) + item = new QListViewItem( i, lastItem ); + else + item = new QListViewItem( lv, lastItem ); + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + textes << v.toString(); + else if ( attrib == "pixmap" ) { + QString s = v.toString(); + if ( s.isEmpty() ) { + pixmaps << QPixmap(); + } else { + pix = loadPixmap( n.firstChild().toElement() ); + pixmaps << pix; + } + } + } else if ( n.tagName() == "item" ) { + item->setOpen( TRUE ); + createItem( n, widget, item ); + } + + n = n.nextSibling().toElement(); + } + + for ( int i = 0; i < lv->columns(); ++i ) { + item->setText( i, textes[ i ] ); + item->setPixmap( i, pixmaps[ i ] ); + } + lastItem = item; + } +} + +QWidget *Resource::createSpacer( const QDomElement &e, QWidget *parent, QLayout *layout, Qt::Orientation o ) +{ + QDomElement n = e.firstChild().toElement(); + int row = e.attribute( "row" ).toInt(); + int col = e.attribute( "column" ).toInt(); + int rowspan = e.attribute( "rowspan" ).toInt(); + int colspan = e.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + + Spacer *spacer = (Spacer*) WidgetFactory::create( WidgetDatabase::idFromClassName("Spacer"), + parent, "spacer", FALSE); + spacer->setOrientation( o ); + spacer->setInteraciveMode( FALSE ); + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) + setObjectProperty( spacer, n.attribute( "name" ), n.firstChild().toElement() ); + n = n.nextSibling().toElement(); + } + spacer->setInteraciveMode( TRUE ); + if ( formwindow ) + formwindow->insertWidget( spacer, pasting ); + if ( layout ) { + if ( ::qt_cast(layout) ) + ( (QBoxLayout*)layout )->addWidget( spacer, 0, spacer->alignment() ); + else + ( (QDesignerGridLayout*)layout )->addMultiCellWidget( spacer, row, row + rowspan - 1, col, col + colspan - 1, + spacer->alignment() ); + } + return spacer; +} + +/*! + Attention: this function has to be in sync with Uic::setObjectProperty(). If you change one, change both. +*/ +void Resource::setObjectProperty( QObject* obj, const QString &prop, const QDomElement &e ) +{ + const QMetaProperty *p = obj->metaObject()->property( obj->metaObject()->findProperty( prop, TRUE ), TRUE ); + + if ( !::qt_cast(obj) ) {// no layouts in metadatabase... (RS) + if ( obj->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)obj )->customWidget(); + if ( cw && !cw->hasProperty( prop.latin1() ) && !p && prop != "toolTip" && prop != "whatsThis" ) + return; + } + MetaDataBase::setPropertyChanged( obj, prop, TRUE ); + } + + QVariant defVarient; + if ( e.tagName() == "font" ) { + QFont f( qApp->font() ); + if ( obj->isWidgetType() && ( (QWidget*)obj )->parentWidget() ) + f = ( (QWidget*)obj )->parentWidget()->font(); + defVarient = QVariant( f ); + } + + QString comment; + QVariant v( DomTool::elementToVariant( e, defVarient, comment ) ); + + if ( !comment.isEmpty() ) { + MetaDataBase::addEntry( obj ); + MetaDataBase::setPropertyComment( obj, prop, comment ); + } + + if ( e.tagName() == "pixmap" ) { + QPixmap pix = loadPixmap( e ); + if ( pix.isNull() ) + return; + v = QVariant( pix ); + } else if ( e.tagName() == "iconset" ) { + QPixmap pix = loadPixmap( e, "iconset" ); + if ( pix.isNull() ) + return; + v = QVariant( QIconSet( pix ) ); + } else if ( e.tagName() == "image" ) { + v = QVariant( loadFromCollection( v.toString() ) ); + } + + if ( !p ) { + MetaDataBase::setFakeProperty( obj, prop, v ); + if ( obj->isWidgetType() ) { + if ( prop == "database" && obj != toplevel ) { + QStringList lst = MetaDataBase::fakeProperty( obj, "database" ).toStringList(); + if ( lst.count() > 2 ) + dbControls.insert( obj->name(), lst[ 2 ] ); + else if ( lst.count() == 2 ) + dbTables.insert( obj->name(), lst ); + } + return; + } + } + + if ( e.tagName() == "palette" ) { + QDomElement n = e.firstChild().toElement(); + QPalette p; + while ( !n.isNull() ) { + QColorGroup cg; + if ( n.tagName() == "active" ) { + cg = loadColorGroup( n ); + p.setActive( cg ); + } else if ( n.tagName() == "inactive" ) { + cg = loadColorGroup( n ); + p.setInactive( cg ); + } else if ( n.tagName() == "disabled" ) { + cg = loadColorGroup( n ); + p.setDisabled( cg ); + } + n = n.nextSibling().toElement(); + } + v = QPalette( p ); + } else if ( e.tagName() == "enum" && p && p->isEnumType() && prop != "resizeMode" ) { + QString key( v.toString() ); + int vi = p->keyToValue( key ); + if ( vi == -1 ) + return; // ignore invalid properties + v = QVariant( vi ); + } else if ( e.tagName() == "set" && p && p->isSetType() ) { + QString keys( v.toString() ); + QStringList lst = QStringList::split( '|', keys ); + QStrList l; + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) + l.append( *it ); + v = QVariant( p->keysToValue( l ) ); + } + + if ( prop == "caption" ) { + QCString s1 = v.toCString(); + QString s2 = v.toString(); + if ( !s2.isEmpty() ) + formwindow->setCaption( s2 ); + else if ( !s1.isEmpty() ) + formwindow->setCaption( s1 ); + } + if ( prop == "icon" ) { + formwindow->setIcon( v.toPixmap() ); + QString pmk = MetaDataBase::pixmapKey( formwindow, v.toPixmap().serialNumber() ); + MetaDataBase::setPixmapKey( formwindow, + formwindow->icon()->serialNumber(), pmk ); + } + + if ( prop == "geometry" ) { + if ( obj == toplevel ) { + hadGeometry = TRUE; + toplevel->resize( v.toRect().size() ); + return; + } else if ( obj == formwindow->mainContainer() ) { + hadGeometry = TRUE; + formwindow->resize( v.toRect().size() ); + return; + } + } + + if ( ::qt_cast(obj) ) { + if ( prop == "spacing" ) { + MetaDataBase::setSpacing( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)obj ) ), v.toInt() ); + return; + } else if ( prop == "margin" ) { + MetaDataBase::setMargin( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)obj ) ), v.toInt() ); + return; + } else if ( e.tagName() == "enum" && prop == "resizeMode" ) { + MetaDataBase::setResizeMode( WidgetFactory::containerOfWidget( WidgetFactory::layoutParent( (QLayout*)obj ) ), v.toString() ); + return; + } + } + + if ( prop == "name" ) { + if ( pasting ) { + QString s = v.toString(); + formwindow->unify( (QWidget*)obj, s, TRUE ); + obj->setName( s ); + return; + } else if ( formwindow && obj == formwindow->mainContainer() ) { + formwindow->setName( v.toCString() ); + } + } + + if ( prop == "sizePolicy" ) { + QSizePolicy sp = v.toSizePolicy(); + sp.setHeightForWidth( ( (QWidget*)obj )->sizePolicy().hasHeightForWidth() ); + } + + if ( prop == "cursor" ) + MetaDataBase::setCursor( (QWidget*)obj, v.toCursor() ); + + obj->setProperty( prop, v ); +} + + +QString Resource::saveInCollection( const QImage &img ) +{ + QString imgName = "none"; + QValueList::Iterator it = images.begin(); + for ( ; it != images.end(); ++it ) { + if ( img == ( *it ).img ) { + imgName = ( *it ).name; + break; + } + } + + if ( imgName == "none" ) { + Image i; + imgName = "image" + QString::number( images.count() ); + i.name = imgName; + i.img = img; + images.append( i ); + } + return imgName; +} + +void Resource::saveImageData( const QImage &img, QTextStream &ts, int indent ) +{ + QByteArray ba; + QBuffer buf( ba ); + buf.open( IO_WriteOnly | IO_Translate ); + QString format; + bool compress = FALSE; + if (img.hasAlphaBuffer()) { + format = "PNG"; + } else { + format = img.depth() > 1 ? "XPM" : "XBM"; + compress = TRUE; + } + QImageIO iio( &buf, format ); + iio.setImage( img ); + iio.write(); + buf.close(); + QByteArray bazip = ba; + int i = 0; + if (compress) { + bazip = qCompress( ba ); + format += ".GZ"; + // The first 4 bytes in qCompress() are the length of the unzipped + // format. The XPM.GZ format does not use these. + i = 4; + } + ulong len = bazip.size(); + ts << makeIndent( indent ) << ""; + static const char hexchars[] = "0123456789abcdef"; + for (; i < (int)len; ++i ) { + uchar s = (uchar) bazip[i]; + ts << hexchars[s >> 4]; + ts << hexchars[s & 0x0f]; + } + ts << "" << endl; +} + +void Resource::saveImageCollection( QTextStream &ts, int indent ) +{ + ts << makeIndent( indent ) << "" << endl; + indent++; + + QValueList::Iterator it = images.begin(); + for ( ; it != images.end(); ++it ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + saveImageData( (*it).img, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } + + indent--; + ts << makeIndent( indent ) << "" << endl; +} + +static QImage loadImageData( QDomElement &n2 ) +{ + QImage img; + QString data = n2.firstChild().toText().data(); + const int lengthOffset = 4; + int baSize = data.length() / 2 + lengthOffset; + uchar *ba = new uchar[ baSize ]; + for ( int i = lengthOffset; i < baSize; ++i ) { + char h = data[ 2 * (i-lengthOffset) ].latin1(); + char l = data[ 2 * (i-lengthOffset) + 1 ].latin1(); + uchar r = 0; + if ( h <= '9' ) + r += h - '0'; + else + r += h - 'a' + 10; + r = r << 4; + if ( l <= '9' ) + r += l - '0'; + else + r += l - 'a' + 10; + ba[ i ] = r; + } + QString format = n2.attribute( "format", "PNG" ); + if ( format == "XPM.GZ" || format == "XBM.GZ" ) { + ulong len = n2.attribute( "length" ).toULong(); + if ( len < data.length() * 5 ) + len = data.length() * 5; + // qUncompress() expects the first 4 bytes to be the expected length of + // the uncompressed data + ba[0] = ( len & 0xff000000 ) >> 24; + ba[1] = ( len & 0x00ff0000 ) >> 16; + ba[2] = ( len & 0x0000ff00 ) >> 8; + ba[3] = ( len & 0x000000ff ); + QByteArray baunzip = qUncompress( ba, baSize ); + img.loadFromData( (const uchar*)baunzip.data(), baunzip.size(), format.left(format.find('.')) ); + } else { + img.loadFromData( (const uchar*)ba+lengthOffset, baSize-lengthOffset, format ); + } + delete [] ba; + return img; +} + +void Resource::loadImageCollection( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "image" ) { + Image img; + img.name = n.attribute( "name" ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "data" ) + img.img = loadImageData( n2 ); + n2 = n2.nextSibling().toElement(); + } + images.append( img ); + n = n.nextSibling().toElement(); + } + } +} + +QImage Resource::loadFromCollection( const QString &name ) +{ + QValueList::Iterator it = images.begin(); + for ( ; it != images.end(); ++it ) { + if ( ( *it ).name == name ) + return ( *it ).img; + } + return QImage(); +} + +void Resource::saveConnections( QTextStream &ts, int indent ) +{ + QValueList connections = MetaDataBase::connections( formwindow ); + if ( connections.isEmpty() ) + return; + ts << makeIndent( indent ) << "" << endl; + indent++; + QValueList::Iterator it = connections.begin(); + for ( ; it != connections.end(); ++it ) { + MetaDataBase::Connection conn = *it; + if ( ( knownNames.findIndex( QString( conn.sender->name() ) ) == -1 && + qstrcmp( conn.sender->name(), "this" ) != 0 ) || + ( knownNames.findIndex( QString( conn.receiver->name() ) ) == -1 && + qstrcmp( conn.receiver->name(), "this" ) != 0 ) ) + continue; + if ( formwindow->isMainContainer( (QWidget*)(*it).receiver ) && + !MetaDataBase::hasSlot( formwindow, MetaDataBase::normalizeFunction( (*it).slot ).latin1() ) ) + continue; + + if ( conn.sender->inherits( "CustomWidget" ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)conn.sender )->customWidget(); + if ( cw && !cw->hasSignal( conn.signal ) ) + continue; + } + + if ( conn.receiver->inherits( "CustomWidget" ) && !formwindow->isMainContainer( conn.receiver ) ) { + MetaDataBase::CustomWidget *cw = ( (CustomWidget*)conn.receiver )->customWidget(); + if ( cw && !cw->hasSlot( MetaDataBase::normalizeFunction( conn.slot ).latin1() ) ) + continue; + } + + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << entitize( conn.sender->name() ) << "" << endl; + ts << makeIndent( indent ) << "" << entitize( conn.signal ) << "" << endl; + ts << makeIndent( indent ) << "" << entitize( conn.receiver->name() ) << "" << endl; + ts << makeIndent( indent ) << "" << entitize( MetaDataBase::normalizeFunction( conn.slot ) ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } + + QString lang = formwindow->project()->language(); + indent--; + ts << makeIndent( indent ) << "" << endl; +} + +void Resource::loadConnections( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "connection" ) { + QString lang = n.attribute( "language", "C++" ); + QDomElement n2 = n.firstChild().toElement(); + MetaDataBase::Connection conn; + while ( !n2.isNull() ) { + if ( n2.tagName() == "sender" ) { + conn.sender = 0; + QString name = n2.firstChild().toText().data(); + if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) { + conn.sender = toplevel; + } else { + if ( name == "this" ) + name = toplevel->name(); + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) + conn.sender = l->first(); + delete l; + l = 0; + } + if ( !conn.sender ) + conn.sender = formwindow->findAction( name ); + } + } else if ( n2.tagName() == "signal" ) { + conn.signal = n2.firstChild().toText().data(); + } else if ( n2.tagName() == "receiver" ) { + conn.receiver = 0; + QString name = n2.firstChild().toText().data(); + if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) { + conn.receiver = toplevel; + } else { + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) + conn.receiver = l->first(); + delete l; + l = 0; + } + if ( !conn.receiver ) + conn.receiver = formwindow->findAction( name ); + } + } else if ( n2.tagName() == "slot" ) { + conn.slot = n2.firstChild().toText().data(); + } + n2 = n2.nextSibling().toElement(); + } + if ( formwindow ) { + if ( conn.sender == formwindow ) + conn.sender = formwindow->mainContainer(); + if ( conn.receiver == formwindow ) + conn.receiver = formwindow->mainContainer(); + } + if ( conn.sender && conn.receiver ) { + if ( lang == "C++" ) { + MetaDataBase::addConnection( formwindow ? formwindow : toplevel, + conn.sender, conn.signal, conn.receiver, conn.slot ); + } + } + } else if ( n.tagName() == "slot" ) { // compatibility with 2.x + MetaDataBase::Function slot; + slot.specifier = n.attribute( "specifier", "virtual" ); + if ( slot.specifier.isEmpty() ) + slot.specifier = "virtual"; + slot.access = n.attribute( "access", "public" ); + if ( slot.access.isEmpty() ) + slot.access = "public"; + slot.language = n.attribute( "language", "C++" ); + slot.returnType = n.attribute( "returnType", "void" ); + if ( slot.returnType.isEmpty() ) + slot.returnType = "void"; + slot.function = n.firstChild().toText().data(); + if ( !MetaDataBase::hasFunction( formwindow, slot.function, TRUE ) ) + MetaDataBase::addFunction( formwindow, slot.function, slot.specifier, + slot.access, "slot", slot.language, slot.returnType ); + else + MetaDataBase::changeFunctionAttributes( formwindow, slot.function, slot.function, + slot.specifier, slot.access, + "slot", slot.language, slot.returnType ); + } + n = n.nextSibling().toElement(); + } +} + +void Resource::saveCustomWidgets( QTextStream &ts, int indent ) +{ + ts << makeIndent( indent ) << "" << endl; + indent++; + + QPtrList *lst = MetaDataBase::customWidgets(); + for ( MetaDataBase::CustomWidget *w = lst->first(); w; w = lst->next() ) { + if ( usedCustomWidgets.findIndex( w->className ) == -1 ) + continue; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << w->className << "" << endl; + ts << makeIndent( indent ) << "
    includePolicy == MetaDataBase::CustomWidget::Local ? "local" : "global" ) + << "\">" << w->includeFile << "
    " << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << w->sizeHint.width() << "" << endl; + ts << makeIndent( indent ) << "" << w->sizeHint.height() << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << makeIndent( indent ) << "" << (int)w->isContainer << "" << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << (int)w->sizePolicy.horData() << "" << endl; + ts << makeIndent( indent ) << "" << (int)w->sizePolicy.verData() << "" << endl; + ts << makeIndent( indent ) << "" << (int)w->sizePolicy.horStretch() << "" << endl; + ts << makeIndent( indent ) << "" << (int)w->sizePolicy.verStretch() << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << makeIndent( indent ) << "" << saveInCollection( w->pixmap->convertToImage() ) << "" << endl; + if ( !w->lstSignals.isEmpty() ) { + for ( QValueList::Iterator it = w->lstSignals.begin(); it != w->lstSignals.end(); ++it ) + ts << makeIndent( indent ) << "" << entitize( *it ) << "" << endl; + } + if ( !w->lstSlots.isEmpty() ) { + for ( QValueList::Iterator it = w->lstSlots.begin(); it != w->lstSlots.end(); ++it ) + ts << makeIndent( indent ) << "" << entitize( (*it).function ) << "" << endl; + } + if ( !w->lstProperties.isEmpty() ) { + for ( QValueList::Iterator it = w->lstProperties.begin(); it != w->lstProperties.end(); ++it ) + ts << makeIndent( indent ) << "" << entitize( (*it).property ) << "" << endl; + } + indent--; + ts << makeIndent( indent ) << "
    " << endl; + } + + + indent--; + ts << makeIndent( indent ) << "
    " << endl; +} + +void Resource::loadCustomWidgets( const QDomElement &e, Resource *r ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "customwidget" ) { + QDomElement n2 = n.firstChild().toElement(); + MetaDataBase::CustomWidget *w = new MetaDataBase::CustomWidget; + while ( !n2.isNull() ) { + if ( n2.tagName() == "class" ) { + w->className = n2.firstChild().toText().data(); + } else if ( n2.tagName() == "header" ) { + w->includeFile = n2.firstChild().toText().data(); + QString s = n2.attribute( "location" ); + if ( s != "local" ) + w->includePolicy = MetaDataBase::CustomWidget::Global; + else + w->includePolicy = MetaDataBase::CustomWidget::Local; + } else if ( n2.tagName() == "sizehint" ) { + QDomElement n3 = n2.firstChild().toElement(); + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w->sizeHint.setWidth( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "height" ) + w->sizeHint.setHeight( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + } else if ( n2.tagName() == "sizepolicy" ) { + QDomElement n3 = n2.firstChild().toElement(); + while ( !n3.isNull() ) { + if ( n3.tagName() == "hordata" ) + w->sizePolicy.setHorData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verdata" ) + w->sizePolicy.setVerData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + w->sizePolicy.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + w->sizePolicy.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + } else if ( n2.tagName() == "pixmap" ) { + QPixmap pix; + if ( r ) { + pix = r->loadPixmap( n2 ); + } else { + QDomElement n3 = n2.firstChild().toElement(); + QImage img; + while ( !n3.isNull() ) { + if ( n3.tagName() == "data" ) { + img = loadImageData( n3 ); + } + n3 = n3.nextSibling().toElement(); + } + pix.convertFromImage( img ); + } + w->pixmap = new QPixmap( pix ); + } else if ( n2.tagName() == "signal" ) { + w->lstSignals.append( n2.firstChild().toText().data().latin1() ); + } else if ( n2.tagName() == "container" ) { + w->isContainer = (bool)n2.firstChild().toText().data().toInt(); + } else if ( n2.tagName() == "slot" ) { + MetaDataBase::Function function; + function.function = n2.firstChild().toText().data().latin1(); + function.access = n2.attribute( "access" ); + function.type = "slot"; + w->lstSlots.append( function ); + } else if ( n2.tagName() == "property" ) { + MetaDataBase::Property property; + property.property = n2.firstChild().toText().data().latin1(); + property.type = n2.attribute( "type" ); + w->lstProperties.append( property ); + } + n2 = n2.nextSibling().toElement(); + } + MetaDataBase::addCustomWidget( w ); + } + n = n.nextSibling().toElement(); + } +} + +void Resource::saveTabOrder( QTextStream &ts, int indent ) +{ + QWidgetList l = MetaDataBase::tabOrder( toplevel ); + if ( l.isEmpty() ) + return; + + ts << makeIndent( indent ) << "" << endl; + indent++; + + for ( QWidget *w = l.first(); w; w = l.next() ) { + if ( w->testWState( Qt::WState_ForceHide ) || knownNames.findIndex( w->name() ) == -1 ) + continue; + ts << makeIndent( indent ) << "" << w->name() << "" << endl; + } + + indent--; + ts << makeIndent( indent ) << "" << endl; +} + +void Resource::loadTabOrder( const QDomElement &e ) +{ + QWidget *last = 0; + QDomElement n = e.firstChild().toElement(); + QWidgetList widgets; + while ( !n.isNull() ) { + if ( n.tagName() == "tabstop" ) { + QString name = n.firstChild().toText().data(); + if ( name.isEmpty() ) + continue; + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) { + QWidget *w = (QWidget*)l->first(); + widgets.append( w ); + if ( last ) + toplevel->setTabOrder( last, w ); + last = w; + } + delete l; + } + } + n = n.nextSibling().toElement(); + } + + if ( !widgets.isEmpty() ) + MetaDataBase::setTabOrder( toplevel, widgets ); +} + +void Resource::saveMetaInfoBefore( QTextStream &ts, int indent ) +{ + MetaDataBase::MetaInfo info = MetaDataBase::metaInfo( formwindow ); + QString cn; + if ( info.classNameChanged && !info.className.isEmpty() ) + cn = info.className; + else + cn = formwindow->name(); + ts << makeIndent( indent ) << "" << entitize( cn ) << "" << endl; + if ( !info.comment.isEmpty() ) + ts << makeIndent( indent ) << "" << entitize( info.comment ) << "" << endl; + if ( !info.author.isEmpty() ) + ts << makeIndent( indent ) << "" << entitize( info.author ) << "" << endl; +} + +void Resource::saveMetaInfoAfter( QTextStream &ts, int indent ) +{ + MetaDataBase::MetaInfo info = MetaDataBase::metaInfo( formwindow ); + if ( !langIface || formwindow->project()->isCpp() ) { + QValueList includes = MetaDataBase::includes( formwindow ); + QString extensionInclude; + bool needExtensionInclude = FALSE; + if ( langIface && + formwindow->formFile()->hasFormCode() && + formwindow->formFile()->codeFileState() != FormFile::Deleted ) { + extensionInclude = QFileInfo( currFileName ).fileName() + langIface->formCodeExtension(); + needExtensionInclude = TRUE; + } + if ( !includes.isEmpty() || needExtensionInclude ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + + for ( QValueList::Iterator it = includes.begin(); it != includes.end(); ++it ) { + ts << makeIndent( indent ) << "" << (*it).header << "" << endl; + if ( needExtensionInclude ) + needExtensionInclude = (*it).header != extensionInclude; + } + + if ( needExtensionInclude ) + ts << makeIndent( indent ) << "" + << extensionInclude << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } + + QStringList forwards = MetaDataBase::forwards( formwindow ); + if ( !forwards.isEmpty() ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + for ( QStringList::Iterator it2 = forwards.begin(); it2 != forwards.end(); ++it2 ) + ts << makeIndent( indent ) << "" << entitize( *it2 ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } + QValueList varLst = MetaDataBase::variables( formwindow ); + if ( !varLst.isEmpty() ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + + QValueList::Iterator it = varLst.begin(); + for ( ; it != varLst.end(); ++it ) { + ts << makeIndent( indent ) << "" << entitize( (*it).varName ) << "
    " << endl; + } + indent--; + ts << makeIndent( indent ) << "" << endl; + } + QStringList sigs = MetaDataBase::signalList( formwindow ); + if ( !sigs.isEmpty() ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + for ( QStringList::Iterator it3 = sigs.begin(); it3 != sigs.end(); ++it3 ) + ts << makeIndent( indent ) << "" << entitize( *it3 ) << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + } + + QValueList slotList = MetaDataBase::slotList( formwindow ); + if ( !slotList.isEmpty() ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + QString lang = formwindow->project()->language(); + QValueList::Iterator it = slotList.begin(); + for ( ; it != slotList.end(); ++it ) { + MetaDataBase::Function function = *it; + ts << makeIndent( indent ) << "" << entitize( function.function ) << "" << endl; + } + indent--; + ts << makeIndent( indent ) << "" << endl; + } + + QValueList functionList = MetaDataBase::functionList( formwindow, TRUE ); + if ( !functionList.isEmpty() ) { + ts << makeIndent( indent ) << "" << endl; + indent++; + QString lang = formwindow->project()->language(); + QValueList::Iterator it = functionList.begin(); + for ( ; it != functionList.end(); ++it ) { + MetaDataBase::Function function = *it; + ts << makeIndent( indent ) << "" << entitize( function.function ) << "
    " << endl; + } + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } + + if ( formwindow && formwindow->savePixmapInline() ) + ; + else if ( formwindow && formwindow->savePixmapInProject() ) + ts << makeIndent( indent ) << "" << endl; + else + ts << makeIndent( indent ) << "" << formwindow->pixmapLoaderFunction() << "" << endl; + if ( !( exportMacro = MetaDataBase::exportMacro( formwindow->mainContainer() ) ).isEmpty() ) + ts << makeIndent( indent ) << "" << exportMacro << "" << endl; + if ( formwindow ) { + ts << makeIndent( indent ) << "layoutDefaultSpacing() + << "\" margin=\"" << formwindow->layoutDefaultMargin() << "\"/>" << endl; + if ( formwindow->hasLayoutFunctions() ) { + QString s = ""; + QString m = ""; + if ( !formwindow->spacingFunction().isEmpty() ) + s = QString( " spacing=\"%1\"" ).arg( formwindow->spacingFunction() ); + if ( !formwindow->marginFunction().isEmpty() ) + m = QString( " margin=\"%1\"" ).arg( formwindow->marginFunction() ); + ts << makeIndent( indent ) << "" << endl; + } + } +} + +void Resource::saveIncludeHints( QTextStream &ts, int indent ) +{ + if ( includeHints.isEmpty() ) + return; + ts << makeIndent( indent ) << "" << endl; + indent++; + for ( QStringList::Iterator it = includeHints.begin(); it != includeHints.end(); ++it ) + ts << makeIndent( indent ) << "" << *it << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; +} + +QColorGroup Resource::loadColorGroup( const QDomElement &e ) +{ + QColorGroup cg; + int r = -1; + QDomElement n = e.firstChild().toElement(); + QColor col; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + cg.setColor( (QColorGroup::ColorRole)r, (col = DomTool::readColor( n ) ) ); + } else if ( n.tagName() == "pixmap" ) { + QPixmap pix = loadPixmap( n ); + cg.setBrush( (QColorGroup::ColorRole)r, QBrush( col, pix ) ); + } + n = n.nextSibling().toElement(); + } + return cg; +} + +void Resource::saveChildActions( QAction *a, QTextStream &ts, int indent ) +{ + if ( !a->children() ) + return; + QObjectListIt it( *a->children() ); + while ( it.current() ) { + QObject *o = it.current(); + ++it; + if ( !::qt_cast(o) ) + continue; + QAction *ac = (QAction*)o; + bool isGroup = ::qt_cast(ac); + if ( isGroup ) + ts << makeIndent( indent ) << "" << endl; + else + ts << makeIndent( indent ) << "" << endl; + indent++; + saveObjectProperties( ac, ts, indent ); + indent--; + if ( isGroup ) { + indent++; + saveChildActions( ac, ts, indent ); + indent--; + } + if ( isGroup ) + ts << makeIndent( indent ) << "" << endl; + else + ts << makeIndent( indent ) << "" << endl; + } +} + +void Resource::saveActions( const QPtrList &actions, QTextStream &ts, int indent ) +{ + if ( actions.isEmpty() ) + return; + ts << makeIndent( indent ) << "" << endl; + indent++; + QPtrListIterator it( actions ); + while ( it.current() ) { + QAction *a = it.current(); + bool isGroup = ::qt_cast(a); + if ( isGroup ) + ts << makeIndent( indent ) << "" << endl; + else + ts << makeIndent( indent ) << "" << endl; + indent++; + saveObjectProperties( a, ts, indent ); + indent--; + if ( isGroup ) { + indent++; + saveChildActions( a, ts, indent ); + indent--; + } + if ( isGroup ) + ts << makeIndent( indent ) << "" << endl; + else + ts << makeIndent( indent ) << "" << endl; + ++it; + } + indent--; + ts << makeIndent( indent ) << "" << endl; +} + +void Resource::loadChildAction( QObject *parent, const QDomElement &e ) +{ + QDomElement n = e; + QAction *a = 0; + if ( n.tagName() == "action" ) { + a = new QDesignerAction( parent ); + MetaDataBase::addEntry( a ); + QDomElement n2 = n.firstChild().toElement(); + bool hasMenuText = FALSE; + while ( !n2.isNull() ) { + if ( n2.tagName() == "property" ) { + QDomElement n3(n2); // don't modify n2 + QString prop = n3.attribute( "name" ); + if (prop == "menuText") + hasMenuText = TRUE; + QDomElement value(n3.firstChild().toElement()); + setObjectProperty( a, prop, value ); + if (!hasMenuText && uiFileVersion < "3.3" && prop == "text") + setObjectProperty( a, "menuText", value ); + } + n2 = n2.nextSibling().toElement(); + } + if ( !::qt_cast(parent) ) + formwindow->actionList().append( a ); + } else if ( n.tagName() == "actiongroup" ) { + a = new QDesignerActionGroup( parent ); + MetaDataBase::addEntry( a ); + QDomElement n2 = n.firstChild().toElement(); + bool hasMenuText = FALSE; + while ( !n2.isNull() ) { + if ( n2.tagName() == "property" ) { + QDomElement n3(n2); // don't modify n2 + QString prop = n3.attribute( "name" ); + if (prop == "menuText") + hasMenuText = TRUE; + QDomElement value = n3.firstChild().toElement(); + setObjectProperty( a, prop, value ); + if (!hasMenuText && uiFileVersion < "3.3" && prop == "text") + setObjectProperty( a, "menuText", value ); + } else if ( n2.tagName() == "action" || + n2.tagName() == "actiongroup" ) { + loadChildAction( a, n2 ); + } + n2 = n2.nextSibling().toElement(); + } + if ( !::qt_cast(parent) ) + formwindow->actionList().append( a ); + } +} + +void Resource::loadActions( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "action" ) { + loadChildAction( formwindow, n ); + } else if ( n.tagName() == "actiongroup" ) { + loadChildAction( formwindow, n ); + } + n = n.nextSibling().toElement(); + } +} + +void Resource::saveToolBars( QMainWindow *mw, QTextStream &ts, int indent ) +{ + ts << makeIndent( indent ) << "" << endl; + indent++; + + QPtrList tbList; + for ( int i = 0; i <= (int)Qt::DockMinimized; ++i ) { + tbList = mw->toolBars( (Qt::Dock)i ); + if ( tbList.isEmpty() ) + continue; + for ( QToolBar *tb = tbList.first(); tb; tb = tbList.next() ) { + if ( tb->isHidden() ) + continue; + ts << makeIndent( indent ) << "" << endl; + indent++; + saveObjectProperties( tb, ts, indent ); + QPtrList actionList = ( (QDesignerToolBar*)tb )->insertedActions(); + for ( QAction *a = actionList.first(); a; a = actionList.next() ) { + if ( ::qt_cast(a) ) { + ts << makeIndent( indent ) << "" << endl; + } else { + if ( ::qt_cast(a) && !( (QDesignerAction*)a )->supportsMenu() ) { + QWidget *w = ( (QDesignerAction*)a )->widget(); + ts << makeIndent( indent ) << "" << endl; + indent++; + const char *className = WidgetFactory::classNameOf( w ); + if ( w->isA( "CustomWidget" ) ) + usedCustomWidgets << QString( className ); + if ( WidgetFactory::hasItems( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ), w ) ) + saveItems( w, ts, indent ); + saveObjectProperties( w, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } else { + ts << makeIndent( indent ) << "name() << "\"/>" << endl; + } + } + } + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } + indent--; + ts << makeIndent( indent ) << "" << endl; +} + +void Resource::saveMenuBar( QMainWindow *mw, QTextStream &ts, int indent ) +{ + MenuBarEditor *mb = (MenuBarEditor *)mw->child( 0, "MenuBarEditor" ); + if ( !mb ) + return; + ts << makeIndent( indent ) << "" << endl; + indent++; + MetaDataBase::setPropertyChanged( mb, "name", TRUE ); // FIXME: remove + saveObjectProperties( mb, ts, indent ); + + for ( int i = 0; i < (int)mb->count(); ++i ) { + MenuBarEditorItem *m = mb->item( i ); + if ( !m ) + continue; + if ( m->isSeparator() ) { + ts << makeIndent( indent ) << "" << endl; + } else { + ts << makeIndent( indent ) << "menuText() ) + << "\" name=\"" << entitize( m->menu()->name() ) << "\">" << endl; + indent++; + savePopupMenu( m->menu(), mw, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } + indent--; + ts << makeIndent( indent ) << "" << endl; +} + +void Resource::savePopupMenu( PopupMenuEditor *pm, QMainWindow *mw, QTextStream &ts, int indent ) +{ + for ( PopupMenuEditorItem *i = pm->items()->first(); i; i = pm->items()->next() ) { + QAction *a = i->action(); + if ( ::qt_cast(a) ) + ts << makeIndent( indent ) << "" << endl; + else if ( ::qt_cast(a) ) + ts << makeIndent( indent ) << "name() << "\"/>" << endl; + else if ( ::qt_cast(a) ) + ts << makeIndent( indent ) << "name() << "\"/>" << endl; + PopupMenuEditor *s = i->subMenu(); + if ( s && s->count() ) { + QString n = s->name(); + ts << makeIndent( indent ) << "menuText() ) + << "\" name=\"" << entitize( n ) + << "\" accel=\"" << entitize( a->accel() ) + << "\">" << endl; + indent++; + savePopupMenu( s, mw, ts, indent ); + indent--; + ts << makeIndent( indent ) << "" << endl; + } + } +} + +void Resource::loadToolBars( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + QMainWindow *mw = ( (QMainWindow*)formwindow->mainContainer() ); + QDesignerToolBar *tb = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "toolbar" ) { + Qt::Dock dock = (Qt::Dock)n.attribute( "dock" ).toInt(); + tb = new QDesignerToolBar( mw, dock ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "action" ) { + QAction *a = formwindow->findAction( n2.attribute( "name" ) ); + if ( a ) { + a->addTo( tb ); + tb->addAction( a ); + } + } else if ( n2.tagName() == "separator" ) { + QAction *a = new QSeparatorAction( 0 ); + a->addTo( tb ); + tb->addAction( a ); + } else if ( n2.tagName() == "widget" ) { + QWidget *w = (QWidget*)createObject( n2, tb ); + QDesignerAction *a = new QDesignerAction( w, tb ); + a->addTo( tb ); + tb->addAction( a ); + tb->installEventFilters( w ); + } else if ( n2.tagName() == "property" ) { + setObjectProperty( tb, n2.attribute( "name" ), n2.firstChild().toElement() ); + } + n2 = n2.nextSibling().toElement(); + } + } + n = n.nextSibling().toElement(); + } +} + +void Resource::loadMenuBar( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + QMainWindow *mw = (QMainWindow*)formwindow->mainContainer(); + MenuBarEditor *mb = new MenuBarEditor( formwindow, mw ); + MetaDataBase::addEntry( mb ); + while ( !n.isNull() ) { + if ( n.tagName() == "item" ) { + PopupMenuEditor * popup = new PopupMenuEditor( formwindow, mw ); + loadPopupMenu( popup, n ); + popup->setName( n.attribute( "name" ) ); + mb->insertItem( n.attribute( "text" ), popup ); + MetaDataBase::addEntry( popup ); + } else if ( n.tagName() == "property" ) { + setObjectProperty( mb, n.attribute( "name" ), n.firstChild().toElement() ); + } else if ( n.tagName() == "separator" ) { + mb->insertSeparator(); + } + n = n.nextSibling().toElement(); + } +} + +void Resource::loadPopupMenu( PopupMenuEditor *p, const QDomElement &e ) +{ + MetaDataBase::addEntry( p ); + QDomElement n = e.firstChild().toElement(); + QAction *a = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup") { + a = formwindow->findAction( n.attribute( "name" ) ); + if ( a ) + p->insert( a ); + } + if ( n.tagName() == "item" ) { + PopupMenuEditorItem *i = p->at( p->find( a ) ); + if ( i ) { + QString name = n.attribute( "name" ); + formwindow->unify( i, name, TRUE ); + i->setName( name ); + MetaDataBase::addEntry( i ); + loadPopupMenu( i->subMenu(), n ); + } + } else if ( n.tagName() == "separator" ) { + a = new QSeparatorAction( 0 ); + p->insert( a ); + } + n = n.nextSibling().toElement(); + } +} + +bool Resource::saveFormCode( FormFile *formfile, LanguageInterface * /*langIface*/ ) +{ + QString lang = formfile->project()->language(); + if ( formfile->hasTempFileName() || + formfile->code().isEmpty() || + !formfile->hasFormCode() || + !formfile->isModified(FormFile::WFormCode) ) + return TRUE; // There is no code to be saved. + return saveCode( formfile->project()->makeAbsolute(formfile->codeFile()), + formfile->code() ); +} + +void Resource::loadExtraSource( FormFile *formfile, const QString &currFileName, + LanguageInterface *langIface, bool hasFunctions ) +{ + QString lang = "Qt Script"; + if ( MainWindow::self ) + lang = MainWindow::self->currProject()->language(); + LanguageInterface *iface = langIface; + if ( hasFunctions || !iface ) + return; + QValueList functions; + QStringList forwards; + QStringList includesImpl; + QStringList includesDecl; + QStringList vars; + QValueList connections; + + iface->loadFormCode( formfile->formName(), + currFileName + iface->formCodeExtension(), + functions, + vars, + connections ); + + QFile f( formfile->project()->makeAbsolute( formfile->codeFile() ) ); + QString code; + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + code = ts.read(); + } + formfile->setCode( code ); + + if ( !MainWindow::self || !MainWindow::self->currProject()->isCpp() ) + MetaDataBase::setupConnections( formfile, connections ); + + for ( QValueList::Iterator fit = functions.begin(); + fit != functions.end(); ++fit ) { + + if ( MetaDataBase::hasFunction( formfile->formWindow() ? + (QObject*)formfile->formWindow() : + (QObject*)formfile, + (*fit).name.latin1() ) ) { + QString access = (*fit).access; + if ( !MainWindow::self || !MainWindow::self->currProject()->isCpp() ) + MetaDataBase::changeFunction( formfile->formWindow() ? + (QObject*)formfile->formWindow() : + (QObject*)formfile, + (*fit).name, + (*fit).name, + QString::null ); + } else { + QString access = (*fit).access; + if ( access.isEmpty() ) + access = "protected"; + QString type = "function"; + if ( (*fit).returnType == "void" ) + type = "slot"; + MetaDataBase::addFunction( formfile->formWindow() ? + (QObject*)formfile->formWindow() : + (QObject*)formfile, + (*fit).name.latin1(), "virtual", (*fit).access, + type, lang, (*fit).returnType ); + } + } +} diff --git a/tools/designer/designer/resource.h b/tools/designer/designer/resource.h new file mode 100644 index 0000000..f7f4cea --- /dev/null +++ b/tools/designer/designer/resource.h @@ -0,0 +1,172 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef RESOURCE_H +#define RESOURCE_H + +#include +#include +#include +#include +#include +#include "actiondnd.h" + +#include "metadatabase.h" + +class QWidget; +class QObject; +class QLayout; +class QStyle; +class QPalette; +class FormWindow; +class MainWindow; +class QDomElement; +class QDesignerGridLayout; +class QListViewItem; +class QMainWindow; +struct LanguageInterface; +class FormFile; +class Project; +class PopupMenuEditor; + +class Resource +{ +public: + struct Image { + QImage img; + QString name; + bool operator==( const Image &i ) const { + return ( i.name == name && + i.img == img ); + } + }; + + Resource(); + Resource( MainWindow* mw ); + ~Resource(); + + void setWidget( FormWindow *w ); + QWidget *widget() const; + + bool load( FormFile *ff, Project *defProject = 0 ); + bool load( FormFile *ff, QIODevice*, Project *defProject = 0 ); + QString copy(); + + bool save( const QString& filename, bool formCodeOnly = FALSE); + bool save( QIODevice* ); + void paste( const QString &cb, QWidget *parent ); + + static void saveImageData( const QImage &img, QTextStream &ts, int indent ); + static void loadCustomWidgets( const QDomElement &e, Resource *r ); + static void loadExtraSource( FormFile *formfile, const QString &currFileName, + LanguageInterface *langIface, bool hasFunctions ); + static bool saveFormCode( FormFile *formfile, LanguageInterface *langIface ); + +private: + void saveObject( QObject *obj, QDesignerGridLayout* grid, QTextStream &ts, int indent ); + void saveChildrenOf( QObject* obj, QTextStream &ts, int indent ); + void saveObjectProperties( QObject *w, QTextStream &ts, int indent ); + void saveSetProperty( QObject *w, const QString &name, QVariant::Type t, QTextStream &ts, int indent ); + void saveEnumProperty( QObject *w, const QString &name, QVariant::Type t, QTextStream &ts, int indent ); + void saveProperty( QObject *w, const QString &name, const QVariant &value, QVariant::Type t, QTextStream &ts, int indent ); + void saveProperty( const QVariant &value, QTextStream &ts, int indent ); + void saveItems( QObject *obj, QTextStream &ts, int indent ); + void saveItem( const QStringList &text, const QPtrList &pixmaps, QTextStream &ts, int indent ); + void saveItem( QListViewItem *i, QTextStream &ts, int indent ); + void saveConnections( QTextStream &ts, int indent ); + void saveCustomWidgets( QTextStream &ts, int indent ); + void saveTabOrder( QTextStream &ts, int indent ); + void saveColorGroup( QTextStream &ts, int indent, const QColorGroup &cg ); + void saveColor( QTextStream &ts, int indent, const QColor &c ); + void saveMetaInfoBefore( QTextStream &ts, int indent ); + void saveMetaInfoAfter( QTextStream &ts, int indent ); + void saveIncludeHints( QTextStream &ts, int indent ); + void savePixmap( const QPixmap &p, QTextStream &ts, int indent, const QString &tagname = "pixmap" ); + void saveActions( const QPtrList &actions, QTextStream &ts, int indent ); + void saveChildActions( QAction *a, QTextStream &ts, int indent ); + void saveToolBars( QMainWindow *mw, QTextStream &ts, int indent ); + void saveMenuBar( QMainWindow *mw, QTextStream &ts, int indent ); + void savePopupMenu( PopupMenuEditor *pm, QMainWindow *mw, QTextStream &ts, int indent ); + + QObject *createObject( const QDomElement &e, QWidget *parent, QLayout* layout = 0 ); + QWidget *createSpacer( const QDomElement &e, QWidget *parent, QLayout *layout, Qt::Orientation o ); + void createItem( const QDomElement &e, QWidget *widget, QListViewItem *i = 0 ); + void createColumn( const QDomElement &e, QWidget *widget ); + void setObjectProperty( QObject* widget, const QString &prop, const QDomElement &e); + QString saveInCollection( const QImage &img ); + QString saveInCollection( const QPixmap &pix ) { return saveInCollection( pix.convertToImage() ); } + QImage loadFromCollection( const QString &name ); + void saveImageCollection( QTextStream &ts, int indent ); + void loadImageCollection( const QDomElement &e ); + void loadConnections( const QDomElement &e ); + void loadTabOrder( const QDomElement &e ); + void loadItem( const QDomElement &n, QPixmap &pix, QString &txt, bool &hasPixmap ); + void loadActions( const QDomElement &n ); + void loadChildAction( QObject *parent, const QDomElement &e ); + void loadToolBars( const QDomElement &n ); + void loadMenuBar( const QDomElement &n ); + void loadPopupMenu( PopupMenuEditor *pm, const QDomElement &e ); + QColorGroup loadColorGroup( const QDomElement &e ); + QPixmap loadPixmap( const QDomElement &e, const QString &tagname = "pixmap" ); + +private: + MainWindow *mainwindow; + FormWindow *formwindow; + QWidget* toplevel; + QValueList images; + bool copying, pasting; + bool mainContainerSet; + QStringList knownNames; + QStringList usedCustomWidgets; + QListViewItem *lastItem; + + QValueList metaIncludes; + QValueList metaVariables; + QStringList metaForwards; + QStringList metaSignals; + MetaDataBase::MetaInfo metaInfo; + QMap dbControls; + QMap dbTables; + QMap widgets; + QString exportMacro; + bool hadGeometry; + QMap > langConnections; + QString currFileName; + LanguageInterface *langIface; + bool hasFunctions; + QStringList includeHints; + + QString uiFileVersion; +}; + +#endif diff --git a/tools/designer/designer/richtextfontdialog.ui b/tools/designer/designer/richtextfontdialog.ui new file mode 100644 index 0000000..ca340c2 --- /dev/null +++ b/tools/designer/designer/richtextfontdialog.ui @@ -0,0 +1,354 @@ + +RichTextFontDialog +********************************************************************* +** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + RichTextFontDialog + + + + 0 + 0 + 255 + 158 + + + + Font Properties + + + true + + + + unnamed + + + 11 + + + 6 + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + + default + + + + fontCombo + + + + + TextLabel1_2 + + + &Font: + + + fontCombo + + + + + TextLabel2 + + + Rel. &Size: + + + fontSizeCombo + + + + + Spacer13 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + TextLabel1 + + + C&olor: + + + colorButton + + + + + + 0 + + + + + -4 + + + + + -3 + + + + + -2 + + + + + -1 + + + + + +1 + + + + + +2 + + + + + +3 + + + + + +4 + + + + fontSizeCombo + + + true + + + AtTop + + + + + colorButton + + + + 0 + 0 + 0 + 0 + + + + + 40 + 20 + + + + + 0 + 0 + 0 + + + + TabFocus + + + + + + + + + + Spacer14 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + Line1 + + + HLine + + + Sunken + + + Horizontal + + + + + Layout15 + + + + unnamed + + + 0 + + + 6 + + + + Spacer12 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okButton + + + &OK + + + + + cancelButton + + + &Cancel + + + + + + + + + colorButton + clicked() + RichTextFontDialog + selectColor() + + + okButton + clicked() + RichTextFontDialog + accept() + + + cancelButton + clicked() + RichTextFontDialog + reject() + + + + fontCombo + fontSizeCombo + colorButton + okButton + cancelButton + + + richtextfontdialog.ui.h + + + QString font + QColor color + QString size + + + init() + selectColor() + accept() + reject() + getSize() + getColor() + getFont() + + + diff --git a/tools/designer/designer/richtextfontdialog.ui.h b/tools/designer/designer/richtextfontdialog.ui.h new file mode 100644 index 0000000..8a3dd4c --- /dev/null +++ b/tools/designer/designer/richtextfontdialog.ui.h @@ -0,0 +1,49 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ +#include +#include + +void RichTextFontDialog::init() +{ + QFontDatabase *db = new QFontDatabase(); + fontCombo->insertStringList( db->families() ); +} + +void RichTextFontDialog::selectColor() +{ + color = QColorDialog::getColor( "", this ); + if( color.isValid() ) + colorButton->setPaletteBackgroundColor( color ); +} + +void RichTextFontDialog::accept() +{ + size = fontSizeCombo->currentText(); + font = fontCombo->currentText(); + done( Accepted ); +} + +void RichTextFontDialog::reject() +{ + done( Rejected ); +} + +QString RichTextFontDialog::getSize() +{ + return size; +} + +QString RichTextFontDialog::getColor() +{ + return color.name(); +} + +QString RichTextFontDialog::getFont() +{ + return font; +} diff --git a/tools/designer/designer/sizehandle.cpp b/tools/designer/designer/sizehandle.cpp new file mode 100644 index 0000000..f3134d8 --- /dev/null +++ b/tools/designer/designer/sizehandle.cpp @@ -0,0 +1,394 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include // HP-UX compiler needs this here + +#include "sizehandle.h" +#include "formwindow.h" +#include "widgetfactory.h" + +#include +#include +#include + +SizeHandle::SizeHandle( FormWindow *parent, Direction d, WidgetSelection *s ) + : QWidget( parent ) +{ + active = TRUE; + setBackgroundMode( active ? PaletteText : PaletteDark ); + setFixedSize( 6, 6 ); + widget = 0; + dir =d ; + setMouseTracking( FALSE ); + formWindow = parent; + sel = s; + updateCursor(); +} + +void SizeHandle::updateCursor() +{ + if ( !active ) { + setCursor( arrowCursor ); + return; + } + + switch ( dir ) { + case LeftTop: + setCursor( sizeFDiagCursor ); + break; + case Top: + setCursor( sizeVerCursor ); + break; + case RightTop: + setCursor( sizeBDiagCursor ); + break; + case Right: + setCursor( sizeHorCursor ); + break; + case RightBottom: + setCursor( sizeFDiagCursor ); + break; + case Bottom: + setCursor( sizeVerCursor ); + break; + case LeftBottom: + setCursor( sizeBDiagCursor ); + break; + case Left: + setCursor( sizeHorCursor ); + break; + } +} + +void SizeHandle::setActive( bool a ) +{ + active = a; + setBackgroundMode( active ? PaletteText : PaletteDark ); + updateCursor(); +} + +void SizeHandle::setWidget( QWidget *w ) +{ + widget = w; +} + +void SizeHandle::paintEvent( QPaintEvent * ) +{ + if ( ( (FormWindow*)parentWidget() )->currentWidget() != widget ) + return; + QPainter p( this ); + p.setPen( blue ); + p.drawRect( 0, 0, width(), height() ); +} + +void SizeHandle::mousePressEvent( QMouseEvent *e ) +{ + if ( !widget || e->button() != LeftButton || !active ) + return; + oldPressPos = e->pos(); + geom = origGeom = QRect( widget->pos(), widget->size() ); +} + +void SizeHandle::mouseMoveEvent( QMouseEvent *e ) +{ + if ( !widget || ( e->state() & LeftButton ) != LeftButton || !active ) + return; + QPoint rp = mapFromGlobal( e->globalPos() ); + QPoint d = oldPressPos - rp; + oldPressPos = rp; + QPoint checkPos = widget->parentWidget()->mapFromGlobal( e->globalPos() ); + QRect pr = widget->parentWidget()->rect(); + + // ##### move code around a bit to reduce duplicated code here + switch ( dir ) { + case LeftTop: { + if ( checkPos.x() > pr.width() - 2 * width() || checkPos.y() > pr.height() - 2 * height() ) + return; + int w = geom.width() + d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + int h = geom.height() + d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + int dx = widget->width() - w; + int dy = widget->height() - h; + trySetGeometry( widget, widget->x() + dx, widget->y() + dy, w, h ); + } break; + case Top: { + if ( checkPos.y() > pr.height() - 2 * height() ) + return; + int h = geom.height() + d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + int dy = widget->height() - h; + trySetGeometry( widget, widget->x(), widget->y() + dy, widget->width(), h ); + } break; + case RightTop: { + if ( checkPos.x() < 2 * width() || checkPos.y() > pr.height() - 2 * height() ) + return; + int h = geom.height() + d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + int dy = widget->height() - h; + int w = geom.width() - d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + trySetGeometry( widget, widget->x(), widget->y() + dy, w, h ); + } break; + case Right: { + if ( checkPos.x() < 2 * width() ) + return; + int w = geom.width() - d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + tryResize( widget, w, widget->height() ); + } break; + case RightBottom: { + if ( checkPos.x() < 2 * width() || checkPos.y() < 2 * height() ) + return; + int w = geom.width() - d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + int h = geom.height() - d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + tryResize( widget, w, h ); + } break; + case Bottom: { + if ( checkPos.y() < 2 * height() ) + return; + int h = geom.height() - d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + tryResize( widget, widget->width(), h ); + } break; + case LeftBottom: { + if ( checkPos.x() > pr.width() - 2 * width() || checkPos.y() < 2 * height() ) + return; + int w = geom.width() + d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + int dx = widget->width() - w; + int h = geom.height() - d.y(); + geom.setHeight( h ); + h = ( h / formWindow->grid().y() ) * formWindow->grid().y(); + trySetGeometry( widget, widget->x() + dx, widget->y(), w, h ); + } break; + case Left: { + if ( checkPos.x() > pr.width() - 2 * width() ) + return; + int w = geom.width() + d.x(); + geom.setWidth( w ); + w = ( w / formWindow->grid().x() ) * formWindow->grid().x(); + int dx = widget->width() - w; + trySetGeometry( widget, widget->x() + dx, widget->y(), w, widget->height() ); + } break; + } + + QPoint p = pos(); + sel->updateGeometry(); + oldPressPos += ( p - pos() ); + + formWindow->sizePreview()->setText( tr( "%1/%2" ).arg( widget->width() ).arg( widget->height() ) ); + formWindow->sizePreview()->adjustSize(); + QRect lg( formWindow->mapFromGlobal( e->globalPos() ) + QPoint( 16, 16 ), + formWindow->sizePreview()->size() ); + formWindow->checkPreviewGeometry( lg ); + formWindow->sizePreview()->setGeometry( lg ); + formWindow->sizePreview()->show(); + formWindow->sizePreview()->raise(); + if ( WidgetFactory::layoutType( widget ) != WidgetFactory::NoLayout ) + formWindow->updateChildSelections( widget ); +} + +void SizeHandle::mouseReleaseEvent( QMouseEvent *e ) +{ + if ( e->button() != LeftButton || !active ) + return; + + formWindow->sizePreview()->hide(); + if ( geom != widget->geometry() ) + formWindow->commandHistory()->addCommand( new ResizeCommand( tr( "Resize" ), + formWindow, + widget, origGeom, + widget->geometry() ) ); + formWindow->emitUpdateProperties( widget ); +} + +void SizeHandle::trySetGeometry( QWidget *w, int x, int y, int width, int height ) +{ + int minw = QMAX( w->minimumSizeHint().width(), w->minimumSize().width() ); + minw = QMAX( minw, 2 * formWindow->grid().x() ); + int minh = QMAX( w->minimumSizeHint().height(), w->minimumSize().height() ); + minh = QMAX( minh, 2 * formWindow->grid().y() ); + if ( QMAX( minw, width ) > w->maximumWidth() || + QMAX( minh, height ) > w->maximumHeight() ) + return; + if ( width < minw && x != w->x() ) + x -= minw - width; + if ( height < minh && y != w->y() ) + y -= minh - height; + w->setGeometry( x, y, QMAX( minw, width ), QMAX( minh, height ) ); +} + +void SizeHandle::tryResize( QWidget *w, int width, int height ) +{ + int minw = QMAX( w->minimumSizeHint().width(), w->minimumSize().width() ); + minw = QMAX( minw, 16 ); + int minh = QMAX( w->minimumSizeHint().height(), w->minimumSize().height() ); + minh = QMAX( minh, 16 ); + w->resize( QMAX( minw, width ), QMAX( minh, height ) ); +} + +// ------------------------------------------------------------------------ + +WidgetSelection::WidgetSelection( FormWindow *parent, QPtrDict *selDict ) + : selectionDict( selDict ) +{ + formWindow = parent; + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + handles.insert( i, new SizeHandle( formWindow, (SizeHandle::Direction)i, this ) ); + } + hide(); +} + +void WidgetSelection::setWidget( QWidget *w, bool updateDict ) +{ + if ( !w ) { + hide(); + if ( updateDict ) + selectionDict->remove( wid ); + wid = 0; + return; + } + + wid = w; + bool active = !wid->parentWidget() || WidgetFactory::layoutType( wid->parentWidget() ) == WidgetFactory::NoLayout; + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *h = handles[ i ]; + if ( h ) { + h->setWidget( wid ); + h->setActive( active ); + } + } + updateGeometry(); + show(); + if ( updateDict ) + selectionDict->insert( w, this ); +} + +bool WidgetSelection::isUsed() const +{ + return wid != 0; +} + +void WidgetSelection::updateGeometry() +{ + if ( !wid || !wid->parentWidget() ) + return; + + QPoint p = wid->parentWidget()->mapToGlobal( wid->pos() ); + p = formWindow->mapFromGlobal( p ); + QRect r( p, wid->size() ); + + int w = 6; + int h = 6; + + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *hndl = handles[ i ]; + if ( !hndl ) + continue; + switch ( i ) { + case SizeHandle::LeftTop: + hndl->move( r.x() - w / 2, r.y() - h / 2 ); + break; + case SizeHandle::Top: + hndl->move( r.x() + r.width() / 2 - w / 2, r.y() - h / 2 ); + break; + case SizeHandle::RightTop: + hndl->move( r.x() + r.width() - w / 2, r.y() - h / 2 ); + break; + case SizeHandle::Right: + hndl->move( r.x() + r.width() - w / 2, r.y() + r.height() / 2 - h / 2 ); + break; + case SizeHandle::RightBottom: + hndl->move( r.x() + r.width() - w / 2, r.y() + r.height() - h / 2 ); + break; + case SizeHandle::Bottom: + hndl->move( r.x() + r.width() / 2 - w / 2, r.y() + r.height() - h / 2 ); + break; + case SizeHandle::LeftBottom: + hndl->move( r.x() - w / 2, r.y() + r.height() - h / 2 ); + break; + case SizeHandle::Left: + hndl->move( r.x() - w / 2, r.y() + r.height() / 2 - h / 2 ); + break; + default: + break; + } + } +} + +void WidgetSelection::hide() +{ + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *h = handles[ i ]; + if ( h ) + h->hide(); + } +} + +void WidgetSelection::show() +{ + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *h = handles[ i ]; + if ( h ) { + h->show(); + h->raise(); + } + } +} + +void WidgetSelection::update() +{ + for ( int i = SizeHandle::LeftTop; i <= SizeHandle::Left; ++i ) { + SizeHandle *h = handles[ i ]; + if ( h ) + h->update(); + } +} + +QWidget *WidgetSelection::widget() const +{ + return wid; +} diff --git a/tools/designer/designer/sizehandle.h b/tools/designer/designer/sizehandle.h new file mode 100644 index 0000000..dcf35b2 --- /dev/null +++ b/tools/designer/designer/sizehandle.h @@ -0,0 +1,104 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SIZEHANDLE_H +#define SIZEHANDLE_H + +#include +#include +#include + +class QMouseEvent; +class FormWindow; +class WidgetSelection; +class QPaintEvent; + +class SizeHandle : public QWidget +{ + Q_OBJECT + +public: + enum Direction { LeftTop, Top, RightTop, Right, RightBottom, Bottom, LeftBottom, Left }; + + SizeHandle( FormWindow *parent, Direction d, WidgetSelection *s ); + void setWidget( QWidget *w ); + void setActive( bool a ); + void updateCursor(); + + void setEnabled( bool ) {} + +protected: + void paintEvent( QPaintEvent *e ); + void mousePressEvent( QMouseEvent *e ); + void mouseMoveEvent( QMouseEvent *e ); + void mouseReleaseEvent( QMouseEvent *e ); + +private: + void trySetGeometry( QWidget *w, int x, int y, int width, int height ); + void tryResize( QWidget *w, int width, int height ); + +private: + QWidget *widget; + Direction dir; + QPoint oldPressPos; + FormWindow *formWindow; + WidgetSelection *sel; + QRect geom, origGeom; + bool active; + +}; + +class WidgetSelection +{ +public: + WidgetSelection( FormWindow *parent, QPtrDict *selDict ); + + void setWidget( QWidget *w, bool updateDict = TRUE ); + bool isUsed() const; + + void updateGeometry(); + void hide(); + void show(); + void update(); + + QWidget *widget() const; + +protected: + QIntDict handles; + QWidget *wid; + FormWindow *formWindow; + QPtrDict *selectionDict; + +}; + +#endif diff --git a/tools/designer/designer/sourceeditor.cpp b/tools/designer/designer/sourceeditor.cpp new file mode 100644 index 0000000..3a063df --- /dev/null +++ b/tools/designer/designer/sourceeditor.cpp @@ -0,0 +1,325 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "sourceeditor.h" + +#include "formwindow.h" +#include "metadatabase.h" +#include "project.h" +#include "mainwindow.h" +#include "../interfaces/languageinterface.h" +#include +#include "project.h" +#include "sourcefile.h" +#include "hierarchyview.h" +#include +#include + +SourceEditor::SourceEditor( QWidget *parent, EditorInterface *iface, LanguageInterface *liface ) + : QVBox( parent, 0, WDestructiveClose ), iFace( iface ), lIface( liface ), obj( 0 ), pro( 0 ) +{ + iFace->addRef(); + lIface->addRef(); + editor = iFace->editor( MainWindow::self->areEditorsReadOnly(), + this, MainWindow::self->designerInterface() ); + iFace->onBreakPointChange( MainWindow::self, SLOT( breakPointsChanged() ) ); + resize( 600, 400 ); + setIcon( QPixmap::fromMimeSource( "designer_filenew.png" ) ); +} + +SourceEditor::~SourceEditor() +{ + saveBreakPoints(); + editor = 0; + if ( formWindow() ) { + formWindow()->formFile()->setCodeEdited( FALSE ); + formWindow()->formFile()->setEditor( 0 ); + } else if ( sourceFile() ) { + sourceFile()->setEditor( 0 ); + if ( MainWindow::self->objectHierarchy()->sourceEditor() == this ) + MainWindow::self->objectHierarchy()->setFormWindow( 0, 0 ); + } + iFace->release(); + lIface->release(); + MainWindow::self->editorClosed( this ); +} + +void SourceEditor::setObject( QObject *o, Project *p ) +{ + if ( sourceFile() ) + sourceFile()->setEditor( 0 ); + if ( formWindow() ) { + formWindow()->formFile()->setCodeEdited( FALSE ); + formWindow()->formFile()->setEditor( 0 ); + } + if ( ::qt_cast(o) ) + ( (FormWindow*)o )->formFile()->setCodeEdited( TRUE ); + save(); + bool changed = FALSE; + if ( &(*obj) != o ) { + saveBreakPoints(); + changed = TRUE; + } + obj = o; + pro = p; + if ( formWindow() ) { + if ( formWindow()->isFake() ) + setCaption( formWindow()->project()->objectForFakeForm( formWindow() )->name() ); + else + setCaption( obj->name() ); + } else { + setCaption( sourceFile()->fileName() ); + } + if ( sourceFile() ) + sourceFile()->setEditor( this ); + else if ( formWindow() ) + formWindow()->formFile()->setEditor( this ); + iFace->setText( sourceOfObject( obj, lang, iFace, lIface ) ); + if ( pro && formWindow() ) { + if ( formWindow()->isFake() ) + iFace->setContext( pro->objectForFakeFormFile( formWindow()->formFile() ) ); + else + iFace->setContext( formWindow()->mainContainer() ); + } else { + iFace->setContext( 0 ); + } + if ( changed || sourceFile() ) + iFace->setBreakPoints( MetaDataBase::breakPoints( o ) ); + MainWindow::self->objectHierarchy()->showClasses( this ); +} + +QString SourceEditor::sourceOfObject( QObject *o, const QString &, + EditorInterface *, LanguageInterface * ) +{ + QString txt; + if ( !o ) + return txt; + if ( ::qt_cast(o) ) + txt = ( (FormWindow*)o )->formFile()->code(); + else if ( ::qt_cast(o) ) + txt = ( (SourceFile*)o )->text(); + return txt; +} + +void SourceEditor::setFunction( const QString &func, const QString &clss ) +{ + iFace->scrollTo( lIface->createFunctionStart( obj->name(), func, "", "" ), clss ); +} + +void SourceEditor::setClass( const QString &clss ) +{ + iFace->scrollTo( clss, QString::null ); +} + +void SourceEditor::closeEvent( QCloseEvent *e ) +{ + e->accept(); + if ( !obj ) + return; + if ( formWindow() ) { + save(); + formWindow()->formFile()->cm = formWindow()->formFile()->isModified(); + } else { + if ( !sourceFile()->closeEvent() ) + e->ignore(); + } +} + +void SourceEditor::save() +{ + if ( !obj ) + return; + if ( formWindow() ) + formWindow()->formFile()->syncCode(); + else if ( sourceFile() && sourceFile()->editor() ) + sourceFile()->setText( iFace->text() ); +} + +QString SourceEditor::language() const +{ + return lang; +} + +void SourceEditor::setLanguage( const QString &l ) +{ + lang = l; +} + +void SourceEditor::editCut() +{ + iFace->cut(); +} + +void SourceEditor::editCopy() +{ + iFace->copy(); +} + +void SourceEditor::editPaste() +{ + iFace->paste(); +} + +bool SourceEditor::editIsUndoAvailable() +{ + return iFace->isUndoAvailable(); +} + +bool SourceEditor::editIsRedoAvailable() +{ + return iFace->isRedoAvailable(); +} + +void SourceEditor::editUndo() +{ + iFace->undo(); +} + +void SourceEditor::editRedo() +{ + iFace->redo(); +} + +void SourceEditor::editSelectAll() +{ + iFace->selectAll(); +} + +void SourceEditor::configChanged() +{ + iFace->readSettings(); +} + +void SourceEditor::setModified( bool b ) +{ + iFace->setModified( b ); +} + +void SourceEditor::refresh( bool allowSave ) +{ + if ( allowSave ) + save(); + bool oldMod = iFace->isModified(); + iFace->setText( sourceOfObject( obj, lang, iFace, lIface ) ); + iFace->setModified( oldMod ); +} + +void SourceEditor::resetContext() +{ + if ( pro && formWindow() ) { + if ( formWindow()->isFake() ) + iFace->setContext( pro->objectForFakeFormFile( formWindow()->formFile() ) ); + else + iFace->setContext( formWindow()->mainContainer() ); + } else { + iFace->setContext( 0 ); + } +} + +void SourceEditor::setFocus() +{ + if ( formWindow() ) + formWindow()->formFile()->setCodeEdited( TRUE ); + if ( editor ) + editor->setFocus(); +} + +int SourceEditor::numLines() const +{ + return iFace->numLines(); +} + +void SourceEditor::saveBreakPoints() +{ + if ( !obj ) + return; + QValueList l; + iFace->breakPoints( l ); + MetaDataBase::setBreakPoints( obj, l ); +} + +void SourceEditor::clearStep() +{ + iFace->clearStep(); +} + +void SourceEditor::clearStackFrame() +{ + iFace->clearStackFrame(); +} + +void SourceEditor::resetBreakPoints() +{ + iFace->setBreakPoints( MetaDataBase::breakPoints( obj ) ); +} + +QString SourceEditor::text() const +{ + return iFace->text(); +} + +bool SourceEditor::isModified() const +{ + return iFace->isModified(); +} + +void SourceEditor::checkTimeStamp() +{ + if ( formWindow() ) + formWindow()->formFile()->checkTimeStamp(); + else if ( sourceFile() ) + sourceFile()->checkTimeStamp(); +} + +bool SourceEditor::saveAs() +{ + if ( formWindow() ) + return formWindow()->formFile()->saveAs(); + else if ( sourceFile() ) + return sourceFile()->saveAs(); + return FALSE; +} + +SourceFile *SourceEditor::sourceFile() const +{ + if ( !::qt_cast((QObject *)obj) ) + return 0; + return (SourceFile*)(QObject*)obj; +} + +FormWindow *SourceEditor::formWindow() const +{ + if ( !::qt_cast((QObject *)obj) ) + return 0; + return (FormWindow*)(QObject*)obj; +} diff --git a/tools/designer/designer/sourceeditor.h b/tools/designer/designer/sourceeditor.h new file mode 100644 index 0000000..c87a94a --- /dev/null +++ b/tools/designer/designer/sourceeditor.h @@ -0,0 +1,113 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SOURCEEDITOR_H +#define SOURCEEDITOR_H + +#include "../interfaces/editorinterface.h" +#include +#include + +class FormWindow; +class QCloseEvent; +struct LanguageInterface; +class Project; +class SourceFile; + +class SourceEditor : public QVBox +{ + Q_OBJECT + +public: + SourceEditor( QWidget *parent, EditorInterface *iface, LanguageInterface *liface ); + ~SourceEditor(); + + void setObject( QObject *fw, Project *p ); + QObject *object() const { return obj; } + Project *project() const { return pro; } + void setFunction( const QString &func, const QString &clss = QString::null ); + void setClass( const QString &clss ); + void save(); + bool saveAs(); + void setModified( bool b ); + bool isModified() const; + + static QString sourceOfObject( QObject *fw, const QString &lang, EditorInterface *iface, LanguageInterface *lIface ); + + QString language() const; + void setLanguage( const QString &l ); + + void editCut(); + void editCopy(); + void editPaste(); + bool editIsUndoAvailable(); + bool editIsRedoAvailable(); + void editUndo(); + void editRedo(); + void editSelectAll(); + + void configChanged(); + void refresh( bool allowSave ); + void resetContext(); + + EditorInterface *editorInterface() const { return iFace; } + + void setFocus(); + int numLines() const; + void saveBreakPoints(); + void clearStep(); + void clearStackFrame(); + void resetBreakPoints(); + + QString text() const; + + void checkTimeStamp(); + + SourceFile *sourceFile() const; + FormWindow *formWindow() const; + +protected: + void closeEvent( QCloseEvent *e ); + + +private: + EditorInterface *iFace; + LanguageInterface *lIface; + QGuardedPtr obj; + Project *pro; + QString lang; + QGuardedPtr editor; + +}; + +#endif diff --git a/tools/designer/designer/sourcefile.cpp b/tools/designer/designer/sourcefile.cpp new file mode 100644 index 0000000..370bfd3 --- /dev/null +++ b/tools/designer/designer/sourcefile.cpp @@ -0,0 +1,302 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "sourcefile.h" +#include +#include +#include "designerappiface.h" +#include "sourceeditor.h" +#include "metadatabase.h" +#include "../interfaces/languageinterface.h" +#include +#include +#include "mainwindow.h" +#include "workspace.h" +#include + +SourceFile::SourceFile( const QString &fn, bool temp, Project *p ) + : filename( fn ), ed( 0 ), fileNameTemp( temp ), + timeStamp( 0, p->makeAbsolute( fn ) ), pro( p ), pkg( FALSE ) + , accepted( TRUE ) +{ + iface = 0; + + if ( !temp ) + accepted = checkFileName( TRUE ); + + if (accepted) { + load(); + pro->addSourceFile( this ); + MetaDataBase::addEntry( this ); + } + +} + +SourceFile::~SourceFile() +{ + if (iface) + delete iface; +} + +QString SourceFile::text() const +{ + return txt; +} + +void SourceFile::setText( const QString &s ) +{ + txt = s; +} + +bool SourceFile::save( bool ignoreModified ) +{ + if ( fileNameTemp ) + return saveAs(); + if ( !ignoreModified && !isModified() ) + return TRUE; + if ( ed ) + ed->save(); + + if ( QFile::exists( pro->makeAbsolute( filename ) ) ) { + QString fn( pro->makeAbsolute( filename ) ); +#if defined(Q_OS_WIN32) + fn += ".bak"; +#else + fn += "~"; +#endif + QFile f( pro->makeAbsolute( filename ) ); + if ( f.open( IO_ReadOnly ) ) { + QFile f2( fn ); + if ( f2.open( IO_WriteOnly | IO_Translate ) ) { + QCString data( f.size() ); + f.readBlock( data.data(), f.size() ); + f2.writeBlock( data ); + } + } + } + + QFile f( pro->makeAbsolute( filename ) ); + if ( !f.open( IO_WriteOnly | IO_Translate ) ) + return saveAs(); + + QTextStream ts( &f ); + ts << txt; + timeStamp.update(); + setModified( FALSE ); + return TRUE; +} + +bool SourceFile::saveAs( bool ignoreModified ) +{ + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + QString filter; + if ( iface ) + filter = iface->fileFilterList().join(";;"); + + QString old = filename; + QString initFn = pro->makeAbsolute( filename ); + if ( ignoreModified ) { + QString dir = QStringList::split( ':', project()->iFace()->customSetting( "QTSCRIPT_PACKAGES" ) ).first(); + initFn = QFileInfo( initFn ).fileName(); + initFn.prepend( dir + "/" ); + } + QString fn = QFileDialog::getSaveFileName( initFn, filter ); + if ( fn.isEmpty() ) + return FALSE; + fileNameTemp = FALSE; + filename = pro->makeRelative( fn ); + if ( !checkFileName( TRUE ) ) { + filename = old; + return FALSE; + } + pro->setModified( TRUE ); + timeStamp.setFileName( pro->makeAbsolute( filename ) ); + if ( ed ) + ed->setCaption( tr( "Edit %1" ).arg( filename ) ); + setModified( TRUE ); + if ( pro->isDummy() ) { + QObject *o = ed->parent(); + while ( o && !o->isA( "MainWindow" ) ) + o = o->parent(); + if ( o ) + ((MainWindow *)o)->addRecentlyOpenedFile( fn ); + } + return save( ignoreModified ); +} + +bool SourceFile::load() +{ + QFile f( pro->makeAbsolute( filename ) ); + if ( !f.open( IO_ReadOnly ) ) + return FALSE; + QTextStream ts( &f ); + txt = ts.read(); + timeStamp.update(); + return TRUE; +} + +DesignerSourceFile *SourceFile::iFace() +{ + if ( !iface ) + iface = new DesignerSourceFileImpl( this ); + return iface; +} + +void SourceFile::setEditor( SourceEditor *e ) +{ + ed = e; +} + +bool SourceFile::isModified() const +{ + if ( !ed ) + return FALSE; + return ed->isModified(); +} + +static QMap *extensionCounter; +QString SourceFile::createUnnamedFileName( const QString &extension ) +{ + if ( !extensionCounter ) + extensionCounter = new QMap; + int count = -1; + QMap::Iterator it; + if ( ( it = extensionCounter->find( extension ) ) != extensionCounter->end() ) { + count = *it; + ++count; + extensionCounter->replace( extension, count ); + } else { + count = 1; + extensionCounter->insert( extension, count ); + } + + return "unnamed" + QString::number( count ) + "." + extension; +} + +void SourceFile::setModified( bool m ) +{ + if ( !ed ) + return; + ed->setModified( m ); +} + +bool SourceFile::closeEvent() +{ + if ( !isModified() && fileNameTemp ) { + pro->removeSourceFile( this ); + return TRUE; + } + + if ( !isModified() ) + return TRUE; + + if ( ed ) + ed->save(); + + switch ( QMessageBox::warning( MainWindow::self, tr( "Save Code" ), + tr( "Save changes to '%1'?" ).arg( filename ), + tr( "&Yes" ), tr( "&No" ), tr( "&Cancel" ), 0, 2 ) ) { + case 0: // save + if ( !save() ) + return FALSE; + break; + case 1: // don't save + load(); + if ( ed ) + ed->editorInterface()->setText( txt ); + if ( fileNameTemp ) { + pro->removeSourceFile( this ); + return TRUE; + } + if ( MainWindow::self ) + MainWindow::self->workspace()->update(); + break; + case 2: // cancel + return FALSE; + default: + break; + } + setModified( FALSE ); + return TRUE; +} + +bool SourceFile::close() +{ + if ( !ed ) + return TRUE; + return ed->close(); +} + +Project *SourceFile::project() const +{ + return pro; +} + +void SourceFile::checkTimeStamp() +{ + if ( timeStamp.isUpToDate() ) + return; + timeStamp.update(); + if ( QMessageBox::information( MainWindow::self, tr( "Qt Designer" ), + tr( "File '%1' has been changed outside Qt Designer.\n" + "Do you want to reload it?" ).arg( filename ), + tr( "&Yes" ), tr( "&No" ) ) == 0 ) { + load(); + if ( ed ) + ed->editorInterface()->setText( txt ); + } +} + +bool SourceFile::checkFileName( bool allowBreak ) +{ + SourceFile *sf = pro->findSourceFile( filename, this ); + if ( sf ) + QMessageBox::warning( MainWindow::self, tr( "Invalid Filename" ), + tr( "The project already contains a source file with \n" + "filename '%1'. Please choose a new filename." ).arg( filename ) ); + while ( sf ) { + LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() ); + QString filter; + if ( iface ) + filter = iface->fileFilterList().join(";;"); + QString fn; + while ( fn.isEmpty() ) { + fn = QFileDialog::getSaveFileName( pro->makeAbsolute( filename ), filter ); + if ( allowBreak && fn.isEmpty() ) + return FALSE; + } + filename = pro->makeRelative( fn ); + sf = pro->findSourceFile( filename, this ); + } + return TRUE; +} diff --git a/tools/designer/designer/sourcefile.h b/tools/designer/designer/sourcefile.h new file mode 100644 index 0000000..8e69efd --- /dev/null +++ b/tools/designer/designer/sourcefile.h @@ -0,0 +1,93 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SOURCEFILE_H +#define SOURCEFILE_H + +#include +#include "timestamp.h" + +struct DesignerSourceFile; +class SourceEditor; +class Project; + +class SourceFile : public QObject +{ + Q_OBJECT + +public: + SourceFile( const QString &fn, bool temp, Project *p ); + ~SourceFile(); + + void setText( const QString &s ); + void setModified( bool m ); + + bool save( bool ignoreModified = FALSE ); + bool saveAs( bool ignoreModified = FALSE ); + bool load(); + bool close(); + bool closeEvent(); + Project *project() const; + + QString text() const; + QString fileName() const { return filename; } + bool isModified() const; + + void checkTimeStamp(); + + DesignerSourceFile *iFace(); + + void setEditor( SourceEditor *e ); + SourceEditor *editor() const { return ed; } + + static QString createUnnamedFileName( const QString &extension ); + + bool isAccepted() const { return accepted; } + +private: + bool checkFileName( bool allowBreak ); + +private: + QString filename; + QString txt; + DesignerSourceFile *iface; + SourceEditor *ed; + bool fileNameTemp; + TimeStamp timeStamp; + Project *pro; + bool pkg; + bool accepted; + +}; + +#endif diff --git a/tools/designer/designer/startdialog.ui b/tools/designer/designer/startdialog.ui new file mode 100644 index 0000000..b8f6e7a --- /dev/null +++ b/tools/designer/designer/startdialog.ui @@ -0,0 +1,331 @@ + +StartDialogBase +********************************************************************* +** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + StartDialogBase + + + + 0 + 0 + 576 + 420 + + + + + 5 + 5 + 0 + 0 + + + + Qt Designer - New/Open + + + true + + + + unnamed + + + 11 + + + 6 + + + + tabWidget + + + + Widget8 + + + &New File/Project + + + + unnamed + + + 11 + + + 6 + + + + templateView + + + 120 + + + Adjust + + + false + + + + + + + tab + + + &Open File/Project + + + + unnamed + + + 11 + + + 6 + + + + + + Widget9 + + + &Recently Opened + + + + unnamed + + + 11 + + + 6 + + + + recentView + + + WheelFocus + + + 120 + + + Adjust + + + false + + + + + fileInfoLabel + + + + 2 + 5 + 0 + 0 + + + + + + + + + + + + checkShowInFuture + + + &Don't show this dialog in the future + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + 4144 + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 0 + 20 + + + + + + buttonOk + + + OK + + + 0 + + + true + + + true + + + + + buttonCancel + + + Cancel + + + 0 + + + true + + + + + + + + + buttonOk + clicked() + StartDialogBase + accept() + + + buttonCancel + clicked() + StartDialogBase + reject() + + + templateView + doubleClicked(QIconViewItem*) + StartDialogBase + accept() + + + templateView + returnPressed(QIconViewItem*) + StartDialogBase + accept() + + + recentView + doubleClicked(QIconViewItem*) + StartDialogBase + accept() + + + recentView + onItem(QIconViewItem*) + StartDialogBase + recentItemChanged(QIconViewItem*) + + + recentView + onViewport() + StartDialogBase + clearFileInfo() + + + recentView + returnPressed(QIconViewItem*) + StartDialogBase + accept() + + + recentView + selectionChanged(QIconViewItem*) + StartDialogBase + recentItemChanged(QIconViewItem*) + + + + recentItemChanged( QIconViewItem * ) + clearFileInfo() + accept() + reject() + + + diff --git a/tools/designer/designer/startdialogimpl.cpp b/tools/designer/designer/startdialogimpl.cpp new file mode 100644 index 0000000..231e7b6 --- /dev/null +++ b/tools/designer/designer/startdialogimpl.cpp @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "startdialogimpl.h" +#include "designerapp.h" + +FileDialog::FileDialog( const QString &dir, QWidget *parent ) + : QFileDialog( dir, QString::null, parent ) +{ +} + +void FileDialog::accept() +{ + emit fileSelected(); +} + + +StartDialog::StartDialog( QWidget *parent, const QString &templatePath ) + : StartDialogBase( parent, 0 ) +{ + newForm = new NewForm( templateView, templatePath ); + recentFiles.clear(); + initFileOpen(); + showInFuture = TRUE; + + connect( buttonHelp, SIGNAL( clicked() ), + MainWindow::self, SLOT( showDialogHelp() ) ); + connect( recentView, SIGNAL( doubleClicked(QIconViewItem*) ), + this, SLOT( accept() ) ); + connect( recentView, SIGNAL( returnPressed(QIconViewItem*) ), + this, SLOT( accept() ) ); + connect( fd, SIGNAL( fileSelected() ), this, SLOT( accept() ) ); +} + +void StartDialog::accept() +{ + hide(); + showInFuture = !checkShowInFuture->isChecked(); // means don't show it anymore + + int tabindex = tabWidget->currentPageIndex(); + QString filename; + if( !tabindex ) { + if ( !templateView->currentItem() ) + return; + Project *pro = MainWindow::self->findProject( tr( "" ) ); + if ( !pro ) + return; + MainWindow::self->setCurrentProject( pro ); + ( (NewItem*)templateView->currentItem() )->insert( pro ); + } else if ( tabindex == 1 ) { + filename = fd->selectedFile(); + } else if ( tabindex == 2 ) { + filename = recentFiles[recentView->currentItem()->index()]; + } + if ( tabindex ) { + if ( !filename.isEmpty() ) { + QFileInfo fi( filename ); + if ( fi.extension() == "pro" ) + MainWindow::self->openProject( filename ); + else + MainWindow::self->fileOpen( "", "", filename ); + } + } + + done( Accepted ); +} + +void StartDialog::reject() +{ + done( Rejected ); +} + +void StartDialog::recentItemChanged( QIconViewItem *item ) +{ + QString msg( recentFiles[item->index()] ); + QFileInfo f( recentFiles[item->index()] ); + uint s = f.size(); + QString unit( "B" ); + if( s > 1024 ) { + s /= 1024; + unit = "KB"; + } + if ( s > 1024 ) { + s /= 1024; + unit = "MB"; + } + QDateTime dt( f.lastModified() ); + QString date( dt.toString( "MMMM dd hh:mm" )); + msg = QString( "%1 (%2 %3) %4" ).arg(msg).arg(s).arg(unit).arg(date); + fileInfoLabel->setText( msg ); +} + +void StartDialog::clearFileInfo() +{ + fileInfoLabel->clear(); +} + +void StartDialog::setRecentlyFiles( QStringList &files ) +{ + insertRecentItems( files, FALSE ); +} + +void StartDialog::setRecentlyProjects( QStringList &projects ) +{ + insertRecentItems( projects, TRUE ); +} + +void StartDialog::insertRecentItems( QStringList &files, bool isProject ) +{ + QString iconName = "designer_newform.png"; + if ( isProject ) + iconName = "designer_project.png"; + QIconViewItem *item; + QStringList::iterator it = files.begin(); + for( ; it != files.end(); ++it ) { + QFileInfo fi( *it ); + item = new QIconViewItem( recentView, fi.fileName() ); + recentFiles[recentView->index( item )] = *it; + item->setPixmap( QPixmap::fromMimeSource( iconName ) ); + item->setDragEnabled( FALSE ); + } +} + +void StartDialog::initFileOpen() +{ + QString encode = QDir::currentDirPath(); + QUrl::encode( encode ); + fd = new FileDialog( encode, this ); + QPoint point( 0, 0 ); + fd->reparent( tab, point ); + + QObjectList *l = fd->queryList( "QPushButton" ); + QObjectListIt it( *l ); + QObject *obj; + while ( (obj = it.current()) != 0 ) { + ++it; + ((QPushButton*)obj)->hide(); + } + delete l; + + fd->setSizeGripEnabled ( FALSE ); + tabLayout->addWidget( fd ); + + QPluginManager manager( IID_ImportFilter, QApplication::libraryPaths(), + MainWindow::self->pluginDirectory() ); + QStringList filterlist; + filterlist << tr( "Designer Files (*.ui *.pro)" ); + filterlist << tr( "Qt User-Interface Files (*.ui)" ); + filterlist << tr( "QMAKE Project Files (*.pro)" ); + + QStringList list = manager.featureList(); + for ( QStringList::Iterator it2 = list.begin(); it2 != list.end(); ++it2 ) + filterlist << *it2; + + filterlist << tr( "All Files (*)" ); + QString filters = filterlist.join( ";;" ); + fd->setFilters( filters ); + + fd->show(); +} diff --git a/tools/designer/designer/startdialogimpl.h b/tools/designer/designer/startdialogimpl.h new file mode 100644 index 0000000..7ad3b22 --- /dev/null +++ b/tools/designer/designer/startdialogimpl.h @@ -0,0 +1,87 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef STARTDIALOGIMPL_H +#define STARTDIALOGIMPL_H + +#include +#include +#include +#include +#include +#include + +#include "newformimpl.h" +#include "startdialog.h" + +class FileDialog : public QFileDialog +{ + Q_OBJECT + +public: + FileDialog( const QString &dir, QWidget *parent ); + +protected slots: + void accept(); + +signals: + void fileSelected(); +}; + + +class StartDialog : public StartDialogBase +{ + Q_OBJECT + +public: + StartDialog( QWidget *parent, const QString &templatePath ); + void setRecentlyFiles( QStringList& ); + void setRecentlyProjects( QStringList& ); + bool showDialogInFuture() const { return showInFuture; } + +protected slots: + void recentItemChanged( QIconViewItem *item ); + void clearFileInfo(); + void accept(); + void reject(); + +private: + void initFileOpen(); + void insertRecentItems( QStringList &files, bool isProject ); + NewForm *newForm; + FileDialog *fd; + QMap recentFiles; + bool showInFuture; +}; + +#endif diff --git a/tools/designer/designer/styledbutton.cpp b/tools/designer/designer/styledbutton.cpp new file mode 100644 index 0000000..9365698 --- /dev/null +++ b/tools/designer/designer/styledbutton.cpp @@ -0,0 +1,302 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include // HP-UX compiler needs this here +#include "styledbutton.h" +#include "formwindow.h" +#include "pixmapchooser.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +StyledButton::StyledButton(QWidget* parent, const char* name) + : QButton( parent, name ), pix( 0 ), spix( 0 ), s( 0 ), formWindow( 0 ), mousePressed( FALSE ) +{ + setMinimumSize( minimumSizeHint() ); + setAcceptDrops( TRUE ); + + connect( this, SIGNAL(clicked()), SLOT(onEditor())); + + setEditor( ColorEditor ); +} + +StyledButton::StyledButton( const QBrush& b, QWidget* parent, const char* name, WFlags f ) + : QButton( parent, name, f ), spix( 0 ), s( 0 ), formWindow( 0 ) +{ + col = b.color(); + pix = b.pixmap(); + setMinimumSize( minimumSizeHint() ); +} + +StyledButton::~StyledButton() +{ +} + +void StyledButton::setEditor( EditorType e ) +{ + if ( edit == e ) + return; + + edit = e; + update(); +} + +StyledButton::EditorType StyledButton::editor() const +{ + return edit; +} + +void StyledButton::setColor( const QColor& c ) +{ + col = c; + update(); +} + +void StyledButton::setPixmap( const QPixmap & pm ) +{ + if ( !pm.isNull() ) { + delete pix; + pix = new QPixmap( pm ); + } else { + delete pix; + pix = 0; + } + scalePixmap(); +} + +QColor StyledButton::color() const +{ + return col; +} + +QPixmap* StyledButton::pixmap() const +{ + return pix; +} + +bool StyledButton::scale() const +{ + return s; +} + +void StyledButton::setScale( bool on ) +{ + if ( s == on ) + return; + + s = on; + scalePixmap(); +} + +QSize StyledButton::sizeHint() const +{ + return QSize( 50, 25 ); +} + +QSize StyledButton::minimumSizeHint() const +{ + return QSize( 50, 25 ); +} + +void StyledButton::scalePixmap() +{ + delete spix; + + if ( pix ) { + spix = new QPixmap( 6*width()/8, 6*height()/8 ); + QImage img = pix->convertToImage(); + + spix->convertFromImage( s? img.smoothScale( 6*width()/8, 6*height()/8 ) : img ); + } else { + spix = 0; + } + + update(); +} + +void StyledButton::resizeEvent( QResizeEvent* e ) +{ + scalePixmap(); + QButton::resizeEvent( e ); +} + +void StyledButton::drawButton( QPainter *paint ) +{ + style().drawPrimitive(QStyle::PE_ButtonBevel, paint, rect(), colorGroup(), + isDown() ? QStyle::Style_Sunken : QStyle::Style_Raised); + drawButtonLabel(paint); + + if (hasFocus()) + style().drawPrimitive(QStyle::PE_FocusRect, paint, + style().subRect(QStyle::SR_PushButtonFocusRect, this), + colorGroup(), QStyle::Style_Default); +} + +void StyledButton::drawButtonLabel( QPainter *paint ) +{ + QColor pen = isEnabled() ? + hasFocus() ? palette().active().buttonText() : palette().inactive().buttonText() + : palette().disabled().buttonText(); + paint->setPen( pen ); + + if(!isEnabled()) { + paint->setBrush( QBrush( colorGroup().button() ) ); + } + else if ( edit == PixmapEditor && spix ) { + paint->setBrush( QBrush( col, *spix ) ); + paint->setBrushOrigin( width()/8, height()/8 ); + } else + paint->setBrush( QBrush( col ) ); + + paint->drawRect( width()/8, height()/8, 6*width()/8, 6*height()/8 ); +} + +void StyledButton::onEditor() +{ + switch (edit) { + case ColorEditor: { + QColor c = QColorDialog::getColor( palette().active().background(), this ); + if ( c.isValid() ) { + setColor( c ); + emit changed(); + } + } break; + case PixmapEditor: { + QPixmap p; + if ( pixmap() ) + p = qChoosePixmap( this, formWindow, *pixmap() ); + else + p = qChoosePixmap( this, formWindow, QPixmap() ); + if ( !p.isNull() ) { + setPixmap( p ); + emit changed(); + } + } break; + default: + break; + } +} + +void StyledButton::mousePressEvent(QMouseEvent* e) +{ + QButton::mousePressEvent(e); + mousePressed = TRUE; + pressPos = e->pos(); +} + +void StyledButton::mouseMoveEvent(QMouseEvent* e) +{ + QButton::mouseMoveEvent( e ); +#ifndef QT_NO_DRAGANDDROP + if ( !mousePressed ) + return; + if ( ( pressPos - e->pos() ).manhattanLength() > QApplication::startDragDistance() ) { + if ( edit == ColorEditor ) { + QColorDrag *drg = new QColorDrag( col, this ); + QPixmap pix( 25, 25 ); + pix.fill( col ); + QPainter p( &pix ); + p.drawRect( 0, 0, pix.width(), pix.height() ); + p.end(); + drg->setPixmap( pix ); + mousePressed = FALSE; + drg->dragCopy(); + } + else if ( edit == PixmapEditor && pix && !pix->isNull() ) { + QImage img = pix->convertToImage(); + QImageDrag *drg = new QImageDrag( img, this ); + if(spix) + drg->setPixmap( *spix ); + mousePressed = FALSE; + drg->dragCopy(); + } + } +#endif +} + +#ifndef QT_NO_DRAGANDDROP +void StyledButton::dragEnterEvent( QDragEnterEvent *e ) +{ + setFocus(); + if ( edit == ColorEditor && QColorDrag::canDecode( e ) ) + e->accept(); + else if ( edit == PixmapEditor && QImageDrag::canDecode( e ) ) + e->accept(); + else + e->ignore(); +} + +void StyledButton::dragLeaveEvent( QDragLeaveEvent * ) +{ + if ( hasFocus() ) + parentWidget()->setFocus(); +} + +void StyledButton::dragMoveEvent( QDragMoveEvent *e ) +{ + if ( edit == ColorEditor && QColorDrag::canDecode( e ) ) + e->accept(); + else if ( edit == PixmapEditor && QImageDrag::canDecode( e ) ) + e->accept(); + else + e->ignore(); +} + +void StyledButton::dropEvent( QDropEvent *e ) +{ + if ( edit == ColorEditor && QColorDrag::canDecode( e ) ) { + QColor color; + QColorDrag::decode( e, color ); + setColor(color); + emit changed(); + e->accept(); + } + else if ( edit == PixmapEditor && QImageDrag::canDecode( e ) ) { + QImage img; + QImageDrag::decode( e, img ); + QPixmap pm; + pm.convertFromImage(img); + setPixmap(pm); + emit changed(); + e->accept(); + } else { + e->ignore(); + } +} +#endif // QT_NO_DRAGANDDROP diff --git a/tools/designer/designer/styledbutton.h b/tools/designer/designer/styledbutton.h new file mode 100644 index 0000000..f847306 --- /dev/null +++ b/tools/designer/designer/styledbutton.h @@ -0,0 +1,110 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef STYLEDBUTTON_H +#define STYLEDBUTTON_H + +#include +#include + +class QColor; +class QBrush; +class FormWindow; + +class StyledButton : public QButton +{ + Q_OBJECT + + Q_PROPERTY( QColor color READ color WRITE setColor ) + Q_PROPERTY( QPixmap pixmap READ pixmap WRITE setPixmap ) + Q_PROPERTY( EditorType editor READ editor WRITE setEditor ) + Q_PROPERTY( bool scale READ scale WRITE setScale ) + + Q_ENUMS( EditorType ) + +public: + enum EditorType { ColorEditor, PixmapEditor }; + + StyledButton( QWidget* parent = 0, const char* name = 0 ); + StyledButton( const QBrush& b, QWidget* parent = 0, const char* name = 0, WFlags f = 0 ); + ~StyledButton(); + + void setEditor( EditorType ); + EditorType editor() const; + + void setColor( const QColor& ); + void setPixmap( const QPixmap& ); + + QPixmap* pixmap() const; + QColor color() const; + + void setScale( bool ); + bool scale() const; + + QSize sizeHint() const; + QSize minimumSizeHint() const; + + void setFormWindow( FormWindow *fw ) { formWindow = fw; } + +public slots: + virtual void onEditor(); + +signals: + void changed(); + +protected: + void mousePressEvent(QMouseEvent*); + void mouseMoveEvent(QMouseEvent*); +#ifndef QT_NO_DRAGANDDROP + void dragEnterEvent ( QDragEnterEvent * ); + void dragMoveEvent ( QDragMoveEvent * ); + void dragLeaveEvent ( QDragLeaveEvent * ); + void dropEvent ( QDropEvent * ); +#endif // QT_NO_DRAGANDDROP + void drawButton( QPainter* ); + void drawButtonLabel( QPainter* ); + void resizeEvent( QResizeEvent* ); + void scalePixmap(); + +private: + QPixmap* pix; + QPixmap* spix; // the pixmap scaled down to fit into the button + QColor col; + EditorType edit; + bool s; + FormWindow *formWindow; + QPoint pressPos; + bool mousePressed; +}; + +#endif //STYLEDBUTTON_H diff --git a/tools/designer/designer/syntaxhighlighter_html.cpp b/tools/designer/designer/syntaxhighlighter_html.cpp new file mode 100644 index 0000000..da9be19 --- /dev/null +++ b/tools/designer/designer/syntaxhighlighter_html.cpp @@ -0,0 +1,167 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "syntaxhighlighter_html.h" +#include "qstring.h" +#include "qmap.h" +#include "qapplication.h" + + +SyntaxHighlighter_HTML::SyntaxHighlighter_HTML() + : QTextPreProcessor(), lastFormat( 0 ), lastFormatId( -1 ) +{ + QFont f( qApp->font() ); + + addFormat(Standard, new QTextFormat(f, qApp->palette().color(QPalette::Active, QColorGroup::Text))); + addFormat(Keyword, new QTextFormat(f, qApp->palette().color(QPalette::Active, QColorGroup::Dark))); + addFormat(Attribute, new QTextFormat(f, qApp->palette().color(QPalette::Active, QColorGroup::Link))); + addFormat(AttribValue, new QTextFormat(f, qApp->palette().color(QPalette::Active, QColorGroup::LinkVisited))); +} + +SyntaxHighlighter_HTML::~SyntaxHighlighter_HTML() +{ +} + +void SyntaxHighlighter_HTML::process( QTextDocument *doc, QTextParagraph *string, int, bool invalidate ) +{ + + QTextFormat *formatStandard = format( Standard ); + QTextFormat *formatKeyword = format( Keyword ); + QTextFormat *formatAttribute = format( Attribute ); + QTextFormat *formatAttribValue = format( AttribValue ); + + const int StateStandard = 0; + const int StateTag = 1; + const int StateAttribute = 2; + const int StateAttribVal = 3; + + QString buffer = ""; + + int state = StateStandard; + + + if ( string->prev() ) { + if ( string->prev()->endState() == -1 ) + process( doc, string->prev(), 0, FALSE ); + state = string->prev()->endState(); + } + + + int i = 0; + for ( ;; ) { + QChar c = string->at( i )->c; + + if ( c == '<' ) { + if ( state != StateStandard ) + string->setFormat( i - buffer.length(), buffer.length(), formatStandard, FALSE ); + buffer = c; + state = StateTag; + string->setFormat( i, 1, formatKeyword, FALSE ); + } + else if ( c == '>' && ( state != StateStandard ) ) { + string->setFormat( i, 1, formatKeyword, FALSE ); + buffer = ""; + state = StateStandard; + } + else if ( c == ' ' && state == StateTag ) { + buffer += c; + string->setFormat( i, 1, formatStandard, FALSE ); + state = StateAttribute; + } + else if ( c == '=' && state == StateAttribute ) { + buffer += c; + string->setFormat( i, 1, formatStandard, FALSE ); + state = StateAttribute; + } + else if ( c == '\"' && state == StateAttribute ) { + buffer += c; + string->setFormat( i, 1, formatStandard, FALSE ); + state = StateAttribVal; + } + else if ( c == '\"' && state == StateAttribVal ) { + buffer += c; + string->setFormat( i, 1, formatStandard, FALSE ); + state = StateAttribute; + } + else if ( state == StateAttribute ) { + buffer += c; + string->setFormat( i, 1, formatAttribute, FALSE ); + } + else if ( state == StateAttribVal ) { + buffer += c; + string->setFormat( i, 1, formatAttribValue, FALSE ); + } + else if ( state == StateTag ) { + string->setFormat( i, 1, formatKeyword, FALSE ); + buffer += c; + } + else if ( state == StateStandard ) { + string->setFormat( i, 1, formatStandard, FALSE ); + } + + i++; + if ( i >= string->length() ) + break; + } + + string->setEndState( state ); + string->setFirstPreProcess( FALSE ); + + if ( invalidate && string->next() && + !string->next()->firstPreProcess() && string->next()->endState() != -1 ) { + QTextParagraph *p = string->next(); + while ( p ) { + if ( p->endState() == -1 ) + return; + p->setEndState( -1 ); + p = p->next(); + } + } +} + +QTextFormat *SyntaxHighlighter_HTML::format( int id ) +{ + if ( lastFormatId == id && lastFormat ) + return lastFormat; + + QTextFormat *f = formats[ id ]; + lastFormat = f ? f : formats[ 0 ]; + lastFormatId = id; + return lastFormat; +} + +void SyntaxHighlighter_HTML::addFormat( int id, QTextFormat *f ) +{ + formats.insert( id, f ); +} diff --git a/tools/designer/designer/syntaxhighlighter_html.h b/tools/designer/designer/syntaxhighlighter_html.h new file mode 100644 index 0000000..862600b --- /dev/null +++ b/tools/designer/designer/syntaxhighlighter_html.h @@ -0,0 +1,64 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SYNTAXHIGHLIGHTER_HTML_H +#define SYNTAXHIGHLIGHTER_HTML_H + +#include <./private/qrichtext_p.h> + +class SyntaxHighlighter_HTML : public QTextPreProcessor +{ +public: + + enum HTML { + Standard = 1, + Keyword, + Attribute, + AttribValue + }; + + SyntaxHighlighter_HTML(); + virtual ~SyntaxHighlighter_HTML(); + void process( QTextDocument *doc, QTextParagraph *string, int start, bool invalidate = TRUE ); + QTextFormat *format( int id ); + +private: + void addFormat( int id, QTextFormat *f ); + + QTextFormat *lastFormat; + int lastFormatId; + QIntDict formats; + +}; + +#endif diff --git a/tools/designer/designer/tableeditor.ui b/tools/designer/designer/tableeditor.ui new file mode 100644 index 0000000..6ac73d3 --- /dev/null +++ b/tools/designer/designer/tableeditor.ui @@ -0,0 +1,831 @@ + +TableEditorBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + TableEditorBase + + + + 0 + 0 + 484 + 406 + + + + Edit Table + + + true + + + + unnamed + + + 11 + + + 6 + + + + table + + + 1 + + + 1 + + + true + + + + + Layout11 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonApply + + + &Apply + + + true + + + Apply all changes. + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + TabWidget + + + + columns_tab + + + Co&lumns + + + + unnamed + + + 11 + + + 6 + + + + Spacer3 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + listColumns + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonColumnUp + + + + + + designer_s_up.png + + + Move up + + + <b>Move the selected item up.</b><p>The top-most column will be the first column of the list.</p> + + + + + buttonColumnDown + + + + + + designer_s_down.png + + + Move down + + + <b>Move the selected item down.</b><p>The top-most column will be the first column of the list.</p> + + + + + buttonDeleteColumn + + + &Delete Column + + + + + buttonNewColumn + + + &New Column + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + labelTable + + + Table: + + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + labelColumnPixmap + + + Label4 + + + + + buttonDeleteColPixmap + + + + 30 + 22 + + + + + + + designer_s_editcut.png + + + Delete Pixmap + + + <b>Delete the selected item's pixmap.</b><p>The pixmap in the current column of the selected item will be deleted.</p> + + + + + buttonChooseColPixmap + + + + 30 + 22 + + + + ... + + + Select a Pixmap + + + <b>Select a pixmap file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p> + + + + + + + TextLabel2 + + + &Label: + + + editColumnText + + + + + Label2 + + + Pixmap: + + + itemChoosePixmap + + + + + labelFields + + + &Field: + + + comboFields + + + + + editColumnText + + + + + comboFields + + + true + + + + + labelTableValue + + + <no table> + + + + + + + + + rows_tab + + + &Rows + + + + unnamed + + + 11 + + + 6 + + + + Spacer3_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonRowUp + + + + + + designer_s_up.png + + + Move up + + + <b>Move the selected item up.</b><p>The top-most column will be the first column of the list.</p> + + + + + listRows + + + + + buttonRowDown + + + + + + designer_s_down.png + + + Move down + + + <b>Move the selected item down.</b><p>The top-most column will be the first column of the list.</p> + + + + + Spacer2_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonNewRow + + + &New Row + + + + + buttonDeleteRow + + + &Delete Row + + + + + Layout7_2 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel2_3 + + + &Label: + + + editRowText + + + + + Label2_2 + + + Pixmap: + + + itemChoosePixmap + + + + + Layout2_2 + + + + unnamed + + + 0 + + + 6 + + + + labelRowPixmap + + + Label4 + + + + + buttonDeleteRowPixmap + + + + 30 + 22 + + + + + + + designer_s_editcut.png + + + Delete Pixmap + + + <b>Delete the selected item's pixmap.</b><p>The pixmap in the current column of the selected item will be deleted.</p> + + + + + buttonChooseRowPixmap + + + + 30 + 22 + + + + ... + + + Select a Pixmap + + + <b>Select a pixmap file for the item.</b><p>The pixmap will be changed in the current column of the selected item.</p> + + + + + + + editRowText + + + + + + + + + + + + buttonApply + clicked() + TableEditorBase + applyClicked() + + + buttonOk + clicked() + TableEditorBase + okClicked() + + + listColumns + currentChanged(QListBoxItem*) + TableEditorBase + currentColumnChanged(QListBoxItem*) + + + listColumns + selectionChanged(QListBoxItem*) + TableEditorBase + currentColumnChanged(QListBoxItem*) + + + editColumnText + textChanged(const QString&) + TableEditorBase + columnTextChanged(const QString&) + + + buttonNewColumn + clicked() + TableEditorBase + newColumnClicked() + + + buttonDeleteColumn + clicked() + TableEditorBase + deleteColumnClicked() + + + buttonColumnUp + clicked() + TableEditorBase + columnUpClicked() + + + buttonColumnDown + clicked() + TableEditorBase + columnDownClicked() + + + comboFields + activated(const QString&) + TableEditorBase + currentFieldChanged(const QString&) + + + listRows + selectionChanged(QListBoxItem*) + TableEditorBase + currentRowChanged(QListBoxItem*) + + + listRows + currentChanged(QListBoxItem*) + TableEditorBase + currentRowChanged(QListBoxItem*) + + + buttonNewRow + clicked() + TableEditorBase + newRowClicked() + + + buttonDeleteRow + clicked() + TableEditorBase + deleteRowClicked() + + + buttonRowUp + clicked() + TableEditorBase + rowUpClicked() + + + buttonRowDown + clicked() + TableEditorBase + rowDownClicked() + + + buttonChooseRowPixmap + clicked() + TableEditorBase + chooseRowPixmapClicked() + + + buttonDeleteColPixmap + clicked() + TableEditorBase + deleteColPixmapClicked() + + + editRowText + textChanged(const QString&) + TableEditorBase + rowTextChanged(const QString&) + + + buttonCancel + clicked() + TableEditorBase + reject() + + + buttonChooseColPixmap + clicked() + TableEditorBase + chooseColPixmapClicked() + + + buttonDeleteRowPixmap + clicked() + TableEditorBase + deleteRowPixmapClicked() + + + + buttonOk + buttonCancel + table + TabWidget + listColumns + buttonNewColumn + buttonDeleteColumn + comboFields + editColumnText + buttonDeleteColPixmap + buttonChooseColPixmap + buttonColumnUp + buttonColumnDown + buttonApply + listRows + buttonNewRow + buttonDeleteRow + editRowText + buttonDeleteRowPixmap + buttonChooseRowPixmap + buttonRowUp + buttonRowDown + buttonHelp + + + qtable.h + + + init() + destroy() + applyClicked() + chooseRowPixmapClicked() + columnTextChanged( const QString & ) + columnUpClicked() + currentColumnChanged( QListBoxItem * ) + currentFieldChanged( const QString & ) + currentRowChanged( QListBoxItem * ) + deleteColPixmapClicked() + deleteColumnClicked() + deleteRowClicked() + deleteRowPixmapClicked() + newColumnClicked() + newRowClicked() + chooseColPixmapClicked() + okClicked() + rowDownClicked() + rowTextChanged( const QString & ) + rowUpClicked() + columnDownClicked() + + + + diff --git a/tools/designer/designer/tableeditorimpl.cpp b/tools/designer/designer/tableeditorimpl.cpp new file mode 100644 index 0000000..2518f6f --- /dev/null +++ b/tools/designer/designer/tableeditorimpl.cpp @@ -0,0 +1,501 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "tableeditorimpl.h" +#ifndef QT_NO_TABLE +#include +#endif +#include "formwindow.h" +#include +#include +#include +#include +#include +#include +#include "pixmapchooser.h" +#include "command.h" +#include +#include +#include +#include "project.h" +#include "metadatabase.h" +#include "mainwindow.h" + +TableEditor::TableEditor( QWidget* parent, QWidget *editWidget, FormWindow *fw, const char* name, bool modal, WFlags fl ) + : TableEditorBase( parent, name, modal, fl ), +#ifndef QT_NO_TABLE + editTable( (QTable*)editWidget ), +#endif + formWindow( fw ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); +#ifndef QT_NO_TABLE + labelColumnPixmap->setText( "" ); + labelRowPixmap->setText( "" ); + +#ifndef QT_NO_SQL + if ( !::qt_cast(editTable) ) +#endif + { + labelFields->hide(); + comboFields->hide(); + labelTable->hide(); + labelTableValue->hide(); + } +#ifndef QT_NO_SQL + if ( ::qt_cast(editTable) ) { + // ## why does this behave weird? + // TabWidget->removePage( rows_tab ); + // rows_tab->hide(); + // ## do this in the meantime... + TabWidget->setTabEnabled( rows_tab, FALSE ); + } + + if ( formWindow->project() && ::qt_cast(editTable) ) { + QStringList lst = MetaDataBase::fakeProperty( editTable, "database" ).toStringList(); + if ( lst.count() == 2 && !lst[ 0 ].isEmpty() && !lst[ 1 ].isEmpty() ) { + QStringList fields; + fields << ""; + fields += formWindow->project()->databaseFieldList( lst[ 0 ], lst[ 1 ] ); + comboFields->insertStringList( fields ); + } + if ( !lst[ 1 ].isEmpty() ) + labelTableValue->setText( lst[ 1 ] ); + } +#endif + + readFromTable(); +#endif +} + +TableEditor::~TableEditor() +{ +} + +void TableEditor::columnDownClicked() +{ + if ( listColumns->currentItem() == -1 || + listColumns->currentItem() == (int)listColumns->count() - 1 || + listColumns->count() < 2 ) + return; + saveFieldMap(); + int index = listColumns->currentItem() + 1; + QListBoxItem *i = listColumns->item( listColumns->currentItem() ); + listColumns->takeItem( i ); + listColumns->insertItem( i, index ); + listColumns->setCurrentItem( i ); + readColumns(); + restoreFieldMap(); + currentColumnChanged( i ); +} + +void TableEditor::columnTextChanged( const QString &s ) +{ + if ( listColumns->currentItem() == -1 ) + return; + listColumns->blockSignals( TRUE ); + listColumns->changeItem( s, listColumns->currentItem() ); + listColumns->blockSignals( FALSE ); +#ifndef QT_NO_TABLE + if ( table->horizontalHeader()->iconSet( listColumns->currentItem() ) ) + table->horizontalHeader()->setLabel( listColumns->currentItem(), + *table->horizontalHeader()->iconSet( listColumns->currentItem() ), s ); + else + table->horizontalHeader()->setLabel( listColumns->currentItem(), s ); +#endif +} + +void TableEditor::columnUpClicked() +{ + if ( listColumns->currentItem() <= 0 || + listColumns->count() < 2 ) + return; + saveFieldMap(); + int index = listColumns->currentItem() - 1; + QListBoxItem *i = listColumns->item( listColumns->currentItem() ); + listColumns->takeItem( i ); + listColumns->insertItem( i, index ); + listColumns->setCurrentItem( i ); + readColumns(); + restoreFieldMap(); + currentColumnChanged( i ); +} + +void TableEditor::currentColumnChanged( QListBoxItem *i ) +{ + if ( !i ) + return; + editColumnText->blockSignals( TRUE ); + editColumnText->setText( i->text() ); + if ( i->pixmap() ) + labelColumnPixmap->setPixmap( *i->pixmap() ); + else + labelColumnPixmap->setText( "" ); + editColumnText->blockSignals( FALSE ); + +#ifndef QT_NO_SQL + if ( ::qt_cast(editTable) ) { + QString s = *fieldMap.find( listColumns->index( i ) ); + if ( s.isEmpty() ) + comboFields->setCurrentItem( 0 ); + else if ( comboFields->listBox()->findItem( s ) ) + comboFields->setCurrentItem( comboFields->listBox()->index( comboFields->listBox()->findItem( s ) ) ); + else + comboFields->lineEdit()->setText( s ); + } +#endif +} + +void TableEditor::currentFieldChanged( const QString &s ) +{ + if ( listColumns->currentItem() == -1 ) + return; + fieldMap.remove( listColumns->currentItem() ); + fieldMap.insert( listColumns->currentItem(), s ); + editColumnText->blockSignals( TRUE ); //## necessary + QString newColText = s.mid(0,1).upper() + s.mid(1); + editColumnText->setText( newColText ); + columnTextChanged( newColText ); + editColumnText->blockSignals( FALSE ); +} + +void TableEditor::currentRowChanged( QListBoxItem *i ) +{ + if ( !i ) + return; + editRowText->blockSignals( TRUE ); + editRowText->setText( i->text() ); + if ( i->pixmap() ) + labelRowPixmap->setPixmap( *i->pixmap() ); + else + labelRowPixmap->setText( "" ); + editRowText->blockSignals( FALSE ); +} + +void TableEditor::deleteColumnClicked() +{ + if ( listColumns->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + table->setNumCols( table->numCols() - 1 ); + delete listColumns->item( listColumns->currentItem() ); + readColumns(); + if ( listColumns->firstItem() ) { + listColumns->setCurrentItem( listColumns->firstItem() ); + listColumns->setSelected( listColumns->firstItem(), TRUE ); + } +#endif +} + +void TableEditor::deleteRowClicked() +{ + if ( listRows->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + table->setNumRows( table->numRows() - 1 ); + delete listRows->item( listRows->currentItem() ); + readRows(); + if ( listRows->firstItem() ) { + listRows->setCurrentItem( listRows->firstItem() ); + listRows->setSelected( listRows->firstItem(), TRUE ); + } +#endif +} + +void TableEditor::newColumnClicked() +{ +#ifndef QT_NO_TABLE + table->setNumCols( table->numCols() + 1 ); + QMap m; + for ( int i = 0; i < table->numCols() - 1; ++i ) + m.insert( table->horizontalHeader()->label( i ), TRUE ); + int n = table->numCols() - 1; + QString t = QString::number( n ); + while ( m.find( t ) != m.end() ) + t = QString::number( ++n ); + table->horizontalHeader()->setLabel( table->numCols() - 1, t ); + listColumns->insertItem( t ); + QListBoxItem *item = listColumns->item( listColumns->count() - 1 ); + listColumns->setCurrentItem( item ); + listColumns->setSelected( item, TRUE ); +#ifndef QT_NO_SQL + if ( ::qt_cast(editTable) ) { + comboFields->setFocus(); + } else +#endif + { + editColumnText->setFocus(); + editColumnText->selectAll(); + } +#endif +} + +void TableEditor::newRowClicked() +{ +#ifndef QT_NO_TABLE + table->setNumRows( table->numRows() + 1 ); + QMap m; + for ( int i = 0; i < table->numRows() - 1; ++i ) + m.insert( table->verticalHeader()->label( i ), TRUE ); + int n = table->numRows() - 1; + QString t = QString::number( n ); + while ( m.find( t ) != m.end() ) + t = QString::number( ++n ); + table->verticalHeader()->setLabel( table->numRows() - 1, t ); + listRows->insertItem( t ); + QListBoxItem *item = listRows->item( listRows->count() - 1 ); + listRows->setCurrentItem( item ); + listRows->setSelected( item, TRUE ); +#endif +} + +void TableEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void TableEditor::rowDownClicked() +{ + if ( listRows->currentItem() == -1 || + listRows->currentItem() == (int)listRows->count() - 1 || + listRows->count() < 2 ) + return; + int index = listRows->currentItem() + 1; + QListBoxItem *i = listRows->item( listRows->currentItem() ); + listRows->takeItem( i ); + listRows->insertItem( i, index ); + listRows->setCurrentItem( i ); + readRows(); +} + +void TableEditor::rowTextChanged( const QString &s ) +{ + if ( listRows->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + listRows->blockSignals(TRUE); + listRows->changeItem( s, listRows->currentItem() ); + listRows->blockSignals(FALSE); + if ( table->verticalHeader()->iconSet( listRows->currentItem() ) ) + table->verticalHeader()->setLabel( listRows->currentItem(), + *table->verticalHeader()->iconSet( listRows->currentItem() ), s ); + else + table->verticalHeader()->setLabel( listRows->currentItem(), s ); +#endif +} + +void TableEditor::rowUpClicked() +{ + if ( listRows->currentItem() <= 0 || + listRows->count() < 2 ) + return; + int index = listRows->currentItem() - 1; + QListBoxItem *i = listRows->item( listRows->currentItem() ); + listRows->takeItem( i ); + listRows->insertItem( i, index ); + listRows->setCurrentItem( i ); + readRows(); +} + +void TableEditor::applyClicked() +{ + QValueList rows; + QValueList cols; + + int i = 0; +#ifndef QT_NO_TABLE + for ( i = 0; i < table->horizontalHeader()->count(); ++i ) { + PopulateTableCommand::Column col; + col.text = table->horizontalHeader()->label( i ); + if ( table->horizontalHeader()->iconSet( i ) ) + col.pix = table->horizontalHeader()->iconSet( i )->pixmap(); + col.field = *fieldMap.find( i ); + cols.append( col ); + } + for ( i = 0; i < table->verticalHeader()->count(); ++i ) { + PopulateTableCommand::Row row; + row.text = table->verticalHeader()->label( i ); + if ( table->verticalHeader()->iconSet( i ) ) + row.pix = table->verticalHeader()->iconSet( i )->pixmap(); + rows.append( row ); + } + PopulateTableCommand *cmd = new PopulateTableCommand( tr( "Edit the Rows and Columns of '%1' " ).arg( editTable->name() ), + formWindow, editTable, rows, cols ); + cmd->execute(); + formWindow->commandHistory()->addCommand( cmd ); +#endif +} + +void TableEditor::chooseRowPixmapClicked() +{ + if ( listRows->currentItem() == -1 ) + return; + QPixmap pix; + if ( listRows->item( listRows->currentItem() )->pixmap() ) + pix = qChoosePixmap( this, formWindow, *listRows->item( listRows->currentItem() )->pixmap() ); + else + pix = qChoosePixmap( this, formWindow, QPixmap() ); + + if ( pix.isNull() ) + return; + +#ifndef QT_NO_TABLE + table->verticalHeader()->setLabel( listRows->currentItem(), pix, table->verticalHeader()->label( listRows->currentItem() ) ); + listRows->changeItem( pix, listRows->currentText(), listRows->currentItem() ); +#endif +} + +void TableEditor::deleteRowPixmapClicked() +{ + if ( listRows->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + table->verticalHeader()->setLabel( listRows->currentItem(), QPixmap(), table->verticalHeader()->label( listRows->currentItem() ) ); + listRows->changeItem( listRows->currentText(), listRows->currentItem() ); +#endif +} + +void TableEditor::chooseColPixmapClicked() +{ + if ( listColumns->currentItem() == -1 ) + return; + QPixmap pix; + if ( listColumns->item( listColumns->currentItem() )->pixmap() ) + pix = qChoosePixmap( this, formWindow, *listColumns->item( listColumns->currentItem() )->pixmap() ); + else + pix = qChoosePixmap( this, formWindow, QPixmap() ); + + if ( pix.isNull() ) + return; +#ifndef QT_NO_TABLE + table->horizontalHeader()->setLabel( listColumns->currentItem(), pix, table->horizontalHeader()->label( listColumns->currentItem() ) ); + listColumns->changeItem( pix, listColumns->currentText(), listColumns->currentItem() ); +#endif +} + +void TableEditor::deleteColPixmapClicked() +{ + if ( listColumns->currentItem() == -1 ) + return; +#ifndef QT_NO_TABLE + table->horizontalHeader()->setLabel( listColumns->currentItem(), QPixmap(), table->horizontalHeader()->label( listColumns->currentItem() ) ); + listColumns->changeItem( listColumns->currentText(), listColumns->currentItem() ); +#endif +} + +void TableEditor::readFromTable() +{ +#ifndef QT_NO_TABLE + QHeader *cols = editTable->horizontalHeader(); + table->setNumCols( cols->count() ); + QMap columnFields = MetaDataBase::columnFields( editTable ); + for ( int i = 0; i < cols->count(); ++i ) { + if ( editTable->horizontalHeader()->iconSet( i ) ) { + table->horizontalHeader()->setLabel( i, *editTable->horizontalHeader()->iconSet( i ), + editTable->horizontalHeader()->label( i ) ); + listColumns->insertItem( editTable->horizontalHeader()->iconSet( i )->pixmap(), + editTable->horizontalHeader()->label( i ) ); + } else { + table->horizontalHeader()->setLabel( i, editTable->horizontalHeader()->label( i ) ); + listColumns->insertItem( editTable->horizontalHeader()->label( i ) ); + } + QString cf = *columnFields.find( editTable->horizontalHeader()->label( i ) ); + fieldMap.insert( i, cf ); + } + + if ( listColumns->firstItem() ) { + listColumns->setCurrentItem( listColumns->firstItem() ); + listColumns->setSelected( listColumns->firstItem(), TRUE ); + } + + QHeader *rows = editTable->verticalHeader(); + table->setNumRows( rows->count() ); + for ( int j = 0; j < rows->count(); ++j ) { + if ( editTable->verticalHeader()->iconSet( j ) ) { + table->verticalHeader()->setLabel( j, *editTable->verticalHeader()->iconSet( j ), + editTable->verticalHeader()->label( j ) ); + listRows->insertItem( editTable->verticalHeader()->iconSet( j )->pixmap(), + editTable->verticalHeader()->label( j ) ); + } else { + table->verticalHeader()->setLabel( j, editTable->verticalHeader()->label( j ) ); + listRows->insertItem( editTable->verticalHeader()->label( j ) ); + } + } + + if ( listRows->firstItem() ) { + listRows->setCurrentItem( listRows->firstItem() ); + listRows->setSelected( listRows->firstItem(), TRUE ); + } +#endif +} + +void TableEditor::readColumns() +{ + int j = 0; +#ifndef QT_NO_TABLE + for ( QListBoxItem *i = listColumns->firstItem(); i; i = i->next(), ++j ) { + if ( i->pixmap() ) + table->horizontalHeader()->setLabel( j, *i->pixmap(), i->text() ); + else + table->horizontalHeader()->setLabel( j, i->text() ); + } +#endif +} + +void TableEditor::readRows() +{ + int j = 0; +#ifndef QT_NO_TABLE + for ( QListBoxItem *i = listRows->firstItem(); i; i = i->next(), ++j ) { + if ( i->pixmap() ) + table->verticalHeader()->setLabel( j, *i->pixmap(), i->text() ); + else + table->verticalHeader()->setLabel( j, i->text() ); + } +#endif +} + +void TableEditor::saveFieldMap() +{ + tmpFieldMap.clear(); + for ( QMap::Iterator it = fieldMap.begin(); it != fieldMap.end(); ++it ) + tmpFieldMap.insert( listColumns->item( it.key() ), *it ); +} + +void TableEditor::restoreFieldMap() +{ + fieldMap.clear(); + for ( QMap::Iterator it = tmpFieldMap.begin(); it != tmpFieldMap.end(); ++it ) + fieldMap.insert( listColumns->index( it.key() ), *it ); +} diff --git a/tools/designer/designer/tableeditorimpl.h b/tools/designer/designer/tableeditorimpl.h new file mode 100644 index 0000000..88e5dc1 --- /dev/null +++ b/tools/designer/designer/tableeditorimpl.h @@ -0,0 +1,89 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TABLEEDITORIMPL_H +#define TABLEEDITORIMPL_H + +#include "tableeditor.h" +#include + +class QListBoxItem; +class QTable; +class FormWindow; + +class TableEditor : public TableEditorBase +{ + Q_OBJECT + +public: + TableEditor( QWidget* parent = 0, QWidget *editWidget = 0, FormWindow *fw = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~TableEditor(); + +protected slots: + void columnDownClicked(); + void columnTextChanged( const QString & ); + void columnUpClicked(); + void currentColumnChanged( QListBoxItem * ); + void currentFieldChanged( const QString & ); + void currentRowChanged( QListBoxItem * ); + void deleteColumnClicked(); + void deleteRowClicked(); + void newColumnClicked(); + void newRowClicked(); + void okClicked(); + void rowDownClicked(); + void rowTextChanged( const QString & ); + void rowUpClicked(); + void applyClicked(); + void chooseRowPixmapClicked(); + void deleteRowPixmapClicked(); + void chooseColPixmapClicked(); + void deleteColPixmapClicked(); + +private: + void readFromTable(); + void readColumns(); + void readRows(); + void saveFieldMap(); + void restoreFieldMap(); + +private: + QTable *editTable; + FormWindow *formWindow; + QMap fieldMap; + QMap tmpFieldMap; + +}; + +#endif // TABLEEDITOR_H diff --git a/tools/designer/designer/timestamp.cpp b/tools/designer/designer/timestamp.cpp new file mode 100644 index 0000000..2822292 --- /dev/null +++ b/tools/designer/designer/timestamp.cpp @@ -0,0 +1,93 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "timestamp.h" +#include +#include + +class QTimer; + +TimeStamp::TimeStamp( QObject *parent, const QString &f ) + : QObject( parent ), filename( f ), autoCheck( FALSE ) +{ + timer = new QTimer( this ); + connect( timer, SIGNAL( timeout() ), this, SLOT( autoCheckTimeStamp() ) ); + update(); +} + +void TimeStamp::setFileName( const QString &f ) +{ + filename = f; + update(); +} + +QString TimeStamp::fileName() const +{ + return filename; +} + +void TimeStamp::setAutoCheckEnabled( bool a ) +{ + autoCheck = a; + if ( autoCheck ) + timer->start( 5000 ); + else + timer->stop(); +} + +void TimeStamp::update() +{ + QFile f( filename ); + if ( !f.exists() ) + return; + lastTimeStamp = QFileInfo( f ).lastModified(); +} + +bool TimeStamp::isUpToDate() const +{ + QFile f( filename ); + if ( !f.exists() ) + return TRUE; + return lastTimeStamp == QFileInfo( f ).lastModified(); +} + +bool TimeStamp::isAutoCheckEnabled() const +{ + return autoCheck; +} + +void TimeStamp::autoCheckTimeStamp() +{ + if ( !isUpToDate() ) + emit timeStampChanged(); +} diff --git a/tools/designer/designer/timestamp.h b/tools/designer/designer/timestamp.h new file mode 100644 index 0000000..c36c0bf --- /dev/null +++ b/tools/designer/designer/timestamp.h @@ -0,0 +1,70 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TIMESTAMP_H +#define TIMESTAMP_H + +#include +#include +#include + +class TimeStamp : public QObject +{ + Q_OBJECT + +public: + TimeStamp( QObject *parent, const QString &f ); + + void setFileName( const QString &f ); + QString fileName() const; + void setAutoCheckEnabled( bool a ); + void update(); + + bool isUpToDate() const; + bool isAutoCheckEnabled() const; + +signals: + void timeStampChanged(); + +private slots: + void autoCheckTimeStamp(); + +private: + QDateTime lastTimeStamp; + QString filename; + bool autoCheck; + QTimer *timer; + +}; + +#endif diff --git a/tools/designer/designer/variabledialog.ui b/tools/designer/designer/variabledialog.ui new file mode 100644 index 0000000..bf3dc3c --- /dev/null +++ b/tools/designer/designer/variabledialog.ui @@ -0,0 +1,301 @@ + +VariableDialogBase +********************************************************************* +** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + VariableDialogBase + + + + 0 + 0 + 276 + 320 + + + + Edit Variables + + + + unnamed + + + 11 + + + 6 + + + + + Variable + + + true + + + true + + + + + Access + + + true + + + true + + + + varView + + + StyledPanel + + + Sunken + + + true + + + LastColumn + + + + + deleteButton + + + &Delete + + + + + propBox + + + Variable Properties + + + + unnamed + + + 11 + + + 6 + + + + TextLabel2 + + + Acc&ess: + + + accessCombo + + + + + TextLabel1 + + + &Variable: + + + varName + + + + + varName + + + + + + public + + + + + protected + + + + + private + + + + accessCombo + + + + + + + addButton + + + &Add + + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 0 + 21 + + + + + + cancelButton + + + &Cancel + + + + + okButton + + + &OK + + + + + Spacer3 + + + Horizontal + + + Expanding + + + + 0 + 21 + + + + + + + + cancelButton + clicked() + VariableDialogBase + reject() + + + addButton + clicked() + VariableDialogBase + addVariable() + + + okButton + clicked() + VariableDialogBase + okClicked() + + + varName + textChanged(const QString&) + VariableDialogBase + nameChanged() + + + deleteButton + clicked() + VariableDialogBase + deleteVariable() + + + accessCombo + activated(int) + VariableDialogBase + accessChanged() + + + varView + currentChanged(QListViewItem*) + VariableDialogBase + currentItemChanged(QListViewItem*) + + + varView + selectionChanged(QListViewItem*) + VariableDialogBase + currentItemChanged(QListViewItem*) + + + + varView + addButton + deleteButton + varName + accessCombo + okButton + cancelButton + + + addVariable() + deleteVariable() + accessChanged() + nameChanged() + okClicked() + currentItemChanged( QListViewItem * i ) + + + diff --git a/tools/designer/designer/variabledialogimpl.cpp b/tools/designer/designer/variabledialogimpl.cpp new file mode 100644 index 0000000..f71264e --- /dev/null +++ b/tools/designer/designer/variabledialogimpl.cpp @@ -0,0 +1,185 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#include + +#include "metadatabase.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "hierarchyview.h" +#include "command.h" +#include "variabledialogimpl.h" + + +VariableDialog::VariableDialog( FormWindow *fw, QWidget *parent ) + : VariableDialogBase( parent ), formWindow( fw ) +{ + varView->setSorting( -1 ); + QValueList varLst = MetaDataBase::variables( formWindow ); + QValueList::Iterator it = varLst.begin(); + for ( ; it != varLst.end(); ++it ) { + QListViewItem *i = new QListViewItem( varView ); + i->setText( 0, (*it).varName ); + i->setText( 1, (*it).varAccess ); + } + + if ( varView->firstChild() ) + varView->setCurrentItem( varView->firstChild() ); + else + propBox->setEnabled( FALSE ); +} + +VariableDialog::~VariableDialog() +{ +} + +void VariableDialog::setCurrentItem( QString text ) +{ + QListViewItem *i = varView->findItem( text, 0 ); + if ( i ) + varView->setCurrentItem( i ); +} + +void VariableDialog::okClicked() +{ + QValueList lst; + + QListViewItemIterator it( varView ); + while ( it.current() != 0 ) { + MetaDataBase::Variable v; + v.varName = it.current()->text( 0 ).simplifyWhiteSpace(); + if ( v.varName[ (int)v.varName.length() - 1 ] != ';' ) + v.varName += ";"; + v.varAccess = it.current()->text( 1 ); + lst << v; + ++it; + } + + if ( !lst.isEmpty() ) { + QValueList invalidLst; + QValueList::Iterator it1 = lst.begin(); + QValueList::Iterator it2; + for ( ; it1 != lst.end(); ++it1 ) { + it2 = it1; + ++it2; + for ( ; it2 != lst.end(); ++it2 ) { + if ( MetaDataBase::extractVariableName( (*it1).varName ) == + MetaDataBase::extractVariableName( (*it2).varName ) ) { + invalidLst << (*it1); + break; + } + } + } + if ( !invalidLst.isEmpty() ) { + if ( QMessageBox::information( this, tr( "Edit Variables" ), + tr( "One variable has been declared twice.\n" + "Remove this variable?" ), tr( "&Yes" ), tr( "&No" ) ) == 0 ) { + for ( it2 = invalidLst.begin(); it2 != invalidLst.end(); ++it2 ) { + it = varView->firstChild(); + while ( it.current() != 0 ) { + if ( MetaDataBase::extractVariableName( (*it)->text( 0 ).simplifyWhiteSpace() ) == + MetaDataBase::extractVariableName( (*it2).varName ) ) { + delete (*it); + break; + } + ++it; + } + } + } + formWindow->mainWindow()->objectHierarchy()->updateFormDefinitionView(); + return; + } + } + Command *cmd = new SetVariablesCommand( "Edit variables", formWindow, lst ); + formWindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + accept(); +} + +void VariableDialog::addVariable() +{ + QListViewItem *i = new QListViewItem( varView, varView->lastItem() ); + i->setText( 0, "int newVariable" ); + i->setText( 1, "protected" ); + varView->setCurrentItem( i ); + varView->setSelected( i, TRUE ); + varName->setFocus(); + varName->selectAll(); +} + +void VariableDialog::deleteVariable() +{ + QListViewItem *i = varView->selectedItem(); + if ( !i ) + return; + delete i; + i = 0; + if ( varView->firstChild() ) + varView->setSelected( varView->firstChild(), TRUE ); +} + +void VariableDialog::currentItemChanged( QListViewItem *i ) +{ + if ( !i ) { + varName->clear(); + accessCombo->setCurrentItem( 1 ); + propBox->setEnabled( FALSE ); + return; + } + varName->setText( i->text( 0 ) ); + if ( i->text( 1 ) == "public" ) + accessCombo->setCurrentItem( 0 ); + else if ( i->text( 1 ) == "protected" ) + accessCombo->setCurrentItem( 1 ); + else + accessCombo->setCurrentItem( 2 ); + propBox->setEnabled( TRUE ); +} + +void VariableDialog::nameChanged() +{ + if ( !varView->currentItem() ) + return; + varView->currentItem()->setText( 0, varName->text() ); +} + +void VariableDialog::accessChanged() +{ + if ( !varView->currentItem() ) + return; + varView->currentItem()->setText( 1, accessCombo->currentText() ); +} diff --git a/tools/designer/designer/variabledialogimpl.h b/tools/designer/designer/variabledialogimpl.h new file mode 100644 index 0000000..d2dbbc1 --- /dev/null +++ b/tools/designer/designer/variabledialogimpl.h @@ -0,0 +1,63 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef VARIABLEDIALOGIMPL_H +#define VARIABLEDIALOGIMPL_H + +#include "variabledialog.h" + +class FormWindow; +class QListView; + +class VariableDialog : public VariableDialogBase +{ + Q_OBJECT +public: + VariableDialog( FormWindow *fw, QWidget* parent = 0 ); + ~VariableDialog(); + + void setCurrentItem( QString text ); + +protected slots: + void okClicked(); + void addVariable(); + void deleteVariable(); + void nameChanged(); + void accessChanged(); + void currentItemChanged( QListViewItem *i ); + +private: + FormWindow *formWindow; +}; + +#endif diff --git a/tools/designer/designer/widgetaction.cpp b/tools/designer/designer/widgetaction.cpp new file mode 100644 index 0000000..3b59fec --- /dev/null +++ b/tools/designer/designer/widgetaction.cpp @@ -0,0 +1,65 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "widgetaction.h" +#include +#include +#include "mainwindow.h" +#include +#include + +static QStyle *windowsStyle = 0; + +void WidgetAction::addedTo( QWidget *w, QWidget *container ) +{ + if ( ::qt_cast(w) && ::qt_cast(container->parent()->parent()) ) { + if ( !windowsStyle ) + windowsStyle = QStyleFactory::create( "windows" ); + w->setStyle( windowsStyle ); + ( (QToolButton*)w )->setUsesTextLabel( TRUE ); + ( (QToolButton*)w )->setTextPosition( QToolButton::Right ); + w->setBackgroundMode( container->backgroundMode() ); + } +} + +WidgetAction::~WidgetAction() +{ + if ( MainWindow::self ) + MainWindow::self->toolActions.removeRef( this ); +} + +void WidgetAction::init( const QString &g ) +{ + MainWindow::self->toolActions.append( this ); + grp = g; +} diff --git a/tools/designer/designer/widgetaction.h b/tools/designer/designer/widgetaction.h new file mode 100644 index 0000000..4eacca8 --- /dev/null +++ b/tools/designer/designer/widgetaction.h @@ -0,0 +1,72 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef WIDGETACTION_H +#define WIDGETACTION_H + +#include + +class WidgetAction : public QAction +{ + Q_OBJECT + +public: + WidgetAction( const QString &grp, QObject* parent, + const char* name = 0, bool toggle = FALSE ) + : QAction( parent, name, toggle ) { init( grp ); } + WidgetAction( const QString &grp, const QString& text, + const QIconSet& icon, const QString& menuText, QKeySequence accel, + QObject* parent, const char* name = 0, bool toggle = FALSE ) + : QAction( text, icon, menuText, accel, parent, name, toggle ) { init( grp ); } + WidgetAction( const QString &grp, const QString& text, + const QString& menuText, QKeySequence accel, QObject* parent, + const char* name = 0, bool toggle = FALSE ) + : QAction( text, menuText, accel, parent, name, toggle ) { init( grp ); } + ~WidgetAction(); + +#if !defined(Q_NO_USING_KEYWORD) + using QAction::addedTo; +#endif + void addedTo( QWidget *, QWidget * ); + + QString group() const { return grp; } + +private: + void init( const QString &g ); + +private: + QString grp; + +}; + +#endif diff --git a/tools/designer/designer/widgetfactory.cpp b/tools/designer/designer/widgetfactory.cpp new file mode 100644 index 0000000..e168b4f --- /dev/null +++ b/tools/designer/designer/widgetfactory.cpp @@ -0,0 +1,1821 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include // HP-UX compiler need this here +#include "widgetfactory.h" +#include +#include "metadatabase.h" +#include "mainwindow.h" +#include "formwindow.h" +#include "propertyeditor.h" +#include "layout.h" +#include "listboxeditorimpl.h" +#include "listvieweditorimpl.h" +#include "iconvieweditorimpl.h" +#include "formwindow.h" +#include "multilineeditorimpl.h" +#include "../interfaces/widgetinterface.h" +#ifndef QT_NO_TABLE +#include "tableeditorimpl.h" +#endif +#include "project.h" +#include "menubareditor.h" +#include "popupmenueditor.h" + +#include + +#include +#include +#include +#ifndef QT_NO_TABLE +#include +#endif +#ifndef QT_NO_SQL +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef QT_NO_SQL +#include "database.h" +#endif + +#define NO_STATIC_COLORS +#include +#include + +FormWindow *find_formwindow( QWidget *w ) +{ + if ( !w ) + return 0; + for (;;) { + if ( ::qt_cast(w) ) + return (FormWindow*)w; + if ( !w->parentWidget() ) + return 0; + w = w->parentWidget(); + } +} + +void QLayoutWidget::paintEvent( QPaintEvent* ) +{ + QPainter p ( this ); + p.setPen( red ); + p.drawRect( rect() ); +} + + +QDesignerTabWidget::QDesignerTabWidget( QWidget *parent, const char *name ) + : QTabWidget( parent, name ), dropIndicator( 0 ), dragPage( 0 ), mousePressed( FALSE ) +{ + tabBar()->setAcceptDrops( TRUE ); + tabBar()->installEventFilter( this ); +} + +int QDesignerTabWidget::currentPage() const +{ + return tabBar()->currentTab(); +} + +void QDesignerTabWidget::setCurrentPage( int i ) +{ + tabBar()->setCurrentTab( i ); +} + +QString QDesignerTabWidget::pageTitle() const +{ + return ((QTabWidget*)this)->tabLabel( QTabWidget::currentPage() ); +} + +void QDesignerTabWidget::setPageTitle( const QString& title ) +{ + changeTab( QTabWidget::currentPage(), title ); +} + +void QDesignerTabWidget::setPageName( const QCString& name ) +{ + if ( QTabWidget::currentPage() ) + QTabWidget::currentPage()->setName( name ); +} + +QCString QDesignerTabWidget::pageName() const +{ + if ( !QTabWidget::currentPage() ) + return 0; + return QTabWidget::currentPage()->name(); +} + +int QDesignerTabWidget::count() const +{ + return tabBar()->count(); +} + +bool QDesignerTabWidget::eventFilter( QObject *o, QEvent *e ) +{ + if ( o != tabBar() ) return FALSE; + + switch ( e->type() ) { + case QEvent::MouseButtonPress: { + mousePressed = TRUE; + QMouseEvent *me = (QMouseEvent*)e; + pressPoint = me->pos(); + } + break; + case QEvent::MouseMove: { + QMouseEvent *me = (QMouseEvent*)e; + if ( mousePressed && ( pressPoint - me->pos()).manhattanLength() > QApplication::startDragDistance() ) { + QTextDrag *drg = new QTextDrag( QString::number( (long) this ) , this ); + mousePressed = FALSE; + dragPage = QTabWidget::currentPage(); + dragLabel = QTabWidget::tabLabel( dragPage ); + + int index = indexOf( dragPage ); + + removePage( dragPage ); + if ( !drg->dragMove() ) { + insertTab( dragPage, dragLabel, index ); + showPage( dragPage ); + } + if ( dropIndicator ) + dropIndicator->hide(); + } + } + break; + case QEvent::DragLeave: { + if ( dropIndicator ) + dropIndicator->hide(); + } + break; + case QEvent::DragMove: { + QDragEnterEvent *de = (QDragEnterEvent*) e; + if ( QTextDrag::canDecode( de ) ) { + QString text; + QTextDrag::decode( de, text ); + if ( text == QString::number( (long)this ) ) + de->accept(); + else + return FALSE; + } + + int index = 0; + QRect rect; + for ( ; index < tabBar()->count(); index++ ) { + if ( tabBar()->tabAt( index )->rect().contains( de->pos() ) ) { + rect = tabBar()->tabAt( index )->rect(); + break; + } + } + + if ( index == tabBar()->count() -1 ) { + QRect rect2 = rect; + rect2.setLeft( rect2.left() + rect2.width() / 2 ); + if ( rect2.contains( de->pos() ) ) + index++; + } + + if ( ! dropIndicator ) { + dropIndicator = new QWidget( this ); + dropIndicator->setBackgroundColor( red ); + } + + QPoint pos; + if ( index == tabBar()->count() ) + pos = tabBar()->mapToParent( QPoint( rect.x() + rect.width(), rect.y() ) ); + else + pos = tabBar()->mapToParent( QPoint( rect.x(), rect.y() ) ); + + dropIndicator->setGeometry( pos.x(), pos.y() , 3, rect.height() ); + dropIndicator->show(); + } + break; + case QEvent::Drop: { + QDragEnterEvent *de = (QDragEnterEvent*) e; + if ( QTextDrag::canDecode( de ) ) { + QString text; + QTextDrag::decode( de, text ); + if ( text == QString::number( (long)this ) ) { + + int newIndex = 0; + for ( ; newIndex < tabBar()->count(); newIndex++ ) { + if ( tabBar()->tabAt( newIndex )->rect().contains( de->pos() ) ) + break; + } + + if ( newIndex == tabBar()->count() -1 ) { + QRect rect2 = tabBar()->tabAt( newIndex )->rect(); + rect2.setLeft( rect2.left() + rect2.width() / 2 ); + if ( rect2.contains( de->pos() ) ) + newIndex++; + } + + int oldIndex = 0; + for ( ; oldIndex < tabBar()->count(); oldIndex++ ) { + if ( tabBar()->tabAt( oldIndex )->rect().contains( pressPoint ) ) + break; + } + + FormWindow *fw = find_formwindow( this ); + MoveTabPageCommand *cmd = + new MoveTabPageCommand( tr( "Move Tab Page" ), fw, this, + dragPage, dragLabel, newIndex, oldIndex ); + fw->commandHistory()->addCommand( cmd ); + cmd->execute(); + de->accept(); + } + } + } + break; + default: + break; + } + return FALSE; +} + + +QDesignerWidgetStack::QDesignerWidgetStack( QWidget *parent, const char *name ) + : QWidgetStack( parent, name ) +{ + prev = new QToolButton( Qt::LeftArrow, this, "designer_wizardstack_button" ); + prev->setAutoRaise( TRUE ); + prev->setAutoRepeat( TRUE ); + prev->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ) ); + next = new QToolButton( Qt::RightArrow, this, "designer_wizardstack_button" ); + next->setAutoRaise( TRUE ); + next->setAutoRepeat( TRUE ); + next->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ) ); + connect( prev, SIGNAL( clicked() ), this, SLOT( prevPage() ) ); + connect( next, SIGNAL( clicked() ), this, SLOT( nextPage() ) ); + updateButtons(); +} + +void QDesignerWidgetStack::updateButtons() +{ + prev->setGeometry( width() - 31, 1, 15, 15 ); + next->setGeometry( width() - 16, 1, 15, 15 ); + prev->show(); + next->show(); + prev->raise(); + next->raise(); +} + +void QDesignerWidgetStack::prevPage() +{ + setCurrentPage( currentPage() - 1 ); +} + +void QDesignerWidgetStack::nextPage() +{ + setCurrentPage( currentPage() + 1 ); +} + +int QDesignerWidgetStack::currentPage() const +{ + QDesignerWidgetStack* that = (QDesignerWidgetStack*) this; + return that->pages.find( visibleWidget() ); +} + +void QDesignerWidgetStack::setCurrentPage( int i ) +{ + // help next/prev page commands + if ( i < 0 ) + i += count(); + if ( i >= count() ) + i -= count(); + + if ( i < 0 || i >= count() ) + return; + raiseWidget( pages.at( i ) ); + updateButtons(); +} + +QCString QDesignerWidgetStack::pageName() const +{ + if ( !visibleWidget() ) + return 0; + return visibleWidget()->name(); +} + +void QDesignerWidgetStack::setPageName( const QCString& name ) +{ + if ( visibleWidget() ) + visibleWidget()->setName( name ); +} + +int QDesignerWidgetStack::count() const +{ + return pages.count(); +} + +QWidget* QDesignerWidgetStack::page( int i ) const +{ + if ( i < 0 || i >= count() ) + return 0; + QDesignerWidgetStack* that = (QDesignerWidgetStack*) this; + return that->pages.at( i ); +} + + +int QDesignerWidgetStack::insertPage( QWidget *p, int i ) +{ + if ( i < 0 ) + pages.append( p ); + else + pages.insert( (uint) i, p ); + addWidget( p ); + p->show(); + raiseWidget( p ); + QApplication::sendPostedEvents(); + updateButtons(); + return pages.find( p ); +} + +int QDesignerWidgetStack::removePage( QWidget *p ) +{ + int i = pages.find( p ); + pages.remove( p ); + removeWidget( p ); + setCurrentPage( 0 ); + updateButtons(); + return i; +} + + +int QDesignerWizard::currentPageNum() const +{ + for ( int i = 0; i < pageCount(); ++i ) { + if ( page( i ) == currentPage() ) + return i; + } + return 0; +} + + + + + +void QDesignerWizard::setCurrentPage( int i ) +{ + if ( i < currentPageNum() ) { + while ( i < currentPageNum() ) { + if ( currentPageNum() == 0 ) + break; + back(); + } + + } else { + while ( i > currentPageNum() ) { + if ( currentPageNum() == pageCount() - 1 ) + break; + next(); + } + } +} + +QString QDesignerWizard::pageTitle() const +{ + return title( currentPage() ); +} + +void QDesignerWizard::setPageTitle( const QString& title ) +{ + setTitle( currentPage(), title ); +} + +void QDesignerWizard::setPageName( const QCString& name ) +{ + if ( QWizard::currentPage() ) + QWizard::currentPage()->setName( name ); +} + +QCString QDesignerWizard::pageName() const +{ + if ( !QWizard::currentPage() ) + return 0; + return QWizard::currentPage()->name(); +} + +int QDesignerWizard::pageNum( QWidget *p ) +{ + for ( int i = 0; i < pageCount(); ++i ) { + if ( page( i ) == p ) + return i; + } + return -1; +} + +void QDesignerWizard::addPage( QWidget *p, const QString &t ) +{ + QWizard::addPage( p, t ); + if ( removedPages.find( p ) ) + removedPages.remove( p ); +} + +void QDesignerWizard::removePage( QWidget *p ) +{ + QWizard::removePage( p ); + removedPages.insert( p, p ); +} + +void QDesignerWizard::insertPage( QWidget *p, const QString &t, int index ) +{ + QWizard::insertPage( p, t, index ); + if ( removedPages.find( p ) ) + removedPages.remove( p ); +} + +QMap< int, QMap< QString, QVariant> > *defaultProperties = 0; +QMap< int, QStringList > *changedProperties = 0; + +/*! + \class WidgetFactory widgetfactory.h + \brief Set of static functions for creating widgets, layouts and do other stuff + + The widget factory offers functions to create widgets, create and + delete layouts find out other details - all based on the + WidgetDatabase's data. So the functions that use ids use the same + ids as in the WidgetDatabase. +*/ + + +void WidgetFactory::saveDefaultProperties( QObject *w, int id ) +{ + QMap< QString, QVariant> propMap; + QStrList lst = w->metaObject()->propertyNames( TRUE ); + for ( uint i = 0; i < lst.count(); ++i ) { + QVariant var = w->property( lst.at( i ) ); + if ( !var.isValid() && qstrcmp( "pixmap", lst.at( i ) ) == 0 ) + var = QVariant( QPixmap() ); + else if ( !var.isValid() && qstrcmp( "iconSet", lst.at( i ) ) == 0 ) + var = QVariant( QIconSet() ); + propMap.replace( lst.at( i ), var ); + } + defaultProperties->replace( id, propMap ); +} + +void WidgetFactory::saveChangedProperties( QObject *w, int id ) +{ + QStringList l = MetaDataBase::changedProperties( w ); + changedProperties->insert( id, l ); +} + +/*! Creates a widget of the type which is registered as \a id as + child of \a parent. The \a name is optional. If \a init is TRUE, the + widget is initialized with some defaults, else the plain widget is + created. +*/ + +QWidget *WidgetFactory::create( int id, QWidget *parent, const char *name, bool init, const QRect *r, Qt::Orientation orient ) +{ + QString n = WidgetDatabase::className( id ); + if ( n.isEmpty() ) + return 0; + + if ( !defaultProperties ) { + defaultProperties = new QMap< int, QMap< QString, QVariant> >(); + changedProperties = new QMap< int, QStringList >(); + } + + QWidget *w = 0; + QString str = WidgetDatabase::createWidgetName( id ); + const char *s = str.latin1(); + w = createWidget( n, parent, name ? name : s, init, r, orient ); + if ( ::qt_cast(w) ) + ( (QScrollView*)w )->disableSizeHintCaching(); + if ( !w && WidgetDatabase::isCustomWidget( id ) ) + w = createCustomWidget( parent, name ? name : s, MetaDataBase::customWidget( id ) ); + if ( !w ) + return 0; + MetaDataBase::addEntry( w ); + + if ( !defaultProperties->contains( id ) ) + saveDefaultProperties( w, id ); + if ( !changedProperties->contains( id ) ) + saveChangedProperties( w, id ); + + return w; +} + +/*! Creates a layout on the widget \a widget of the type \a type + which can be \c HBox, \c VBox or \c Grid. +*/ + +QLayout *WidgetFactory::createLayout( QWidget *widget, QLayout *layout, LayoutType type ) +{ + int spacing = MainWindow::self->currentLayoutDefaultSpacing(); + int margin = 0; + + int metaspacing = MetaDataBase::spacing( widget ); + int metamargin = MetaDataBase::margin( widget ); + + if ( ::qt_cast(widget) && + ( WidgetDatabase::isContainer( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( widget ) ) ) || + widget && ::qt_cast(widget->parentWidget()) ) ) + margin = MainWindow::self->currentLayoutDefaultMargin(); + + if ( !layout && ::qt_cast(widget) ) + widget = ((QTabWidget*)widget)->currentPage(); + + if ( !layout && ::qt_cast(widget) ) + widget = ((QWizard*)widget)->currentPage(); + + if ( !layout && ::qt_cast(widget) ) + widget = ((QMainWindow*)widget)->centralWidget(); + + if ( !layout && ::qt_cast(widget) ) + widget = ((QWidgetStack*)widget)->visibleWidget(); + + if ( !layout && ::qt_cast(widget) ) + widget = ((QToolBox*)widget)->currentItem(); + + MetaDataBase::addEntry( widget ); + + QLayout *l = 0; + int align = 0; + if ( !layout && ::qt_cast(widget) ) { + QGroupBox *gb = (QGroupBox*)widget; + gb->setColumnLayout( 0, Qt::Vertical ); + layout = gb->layout(); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + switch ( type ) { + case HBox: + l = new QHBoxLayout( layout ); + break; + case VBox: + l = new QVBoxLayout( layout ); + break; + case Grid: + l = new QDesignerGridLayout( layout ); + break; + default: + return 0; + } + align = Qt::AlignTop; + MetaDataBase::setMargin( gb, metamargin ); + MetaDataBase::setSpacing( gb, metaspacing ); + } else { + if ( layout ) { + switch ( type ) { + case HBox: + l = new QHBoxLayout( layout ); + break; + case VBox: + l = new QVBoxLayout( layout ); + break; + case Grid: + l = new QDesignerGridLayout( layout ); + break; + default: + return 0; + } + MetaDataBase::addEntry( l ); + l->setSpacing( spacing ); + l->setMargin( margin ); + } else { + switch ( type ) { + case HBox: + l = new QHBoxLayout( widget ); + break; + case VBox: + l = new QVBoxLayout( widget ); + break; + case Grid: + l = new QDesignerGridLayout( widget ); + break; + default: + return 0; + } + MetaDataBase::addEntry( l ); + if ( widget ) { + MetaDataBase::setMargin( widget, metamargin ); + MetaDataBase::setSpacing( widget, metaspacing ); + } else { + l->setMargin( margin ); + l->setSpacing( spacing ); + } + } + } + l->setAlignment( align ); + MetaDataBase::addEntry( l ); + return l; +} + +void WidgetFactory::deleteLayout( QWidget *widget ) +{ + if ( !widget ) + return; + + if ( ::qt_cast(widget) ) + widget = ((QTabWidget*)widget)->currentPage(); + if ( ::qt_cast(widget) ) + widget = ((QWizard*)widget)->currentPage(); + if ( ::qt_cast(widget) ) + widget = ((QMainWindow*)widget)->centralWidget(); + if ( ::qt_cast(widget) ) + widget = ((QWidgetStack*)widget)->visibleWidget(); + if ( ::qt_cast(widget) ) + widget = ((QToolBox*)widget)->currentItem(); + delete widget->layout(); +} + +/*! Factory functions for creating a widget of the type \a className + as child of \a parent with the name \a name. + + If \a init is TRUE, some initial default properties are set. This + has to be in sync with the initChangedProperties() function! +*/ + +QWidget *WidgetFactory::createWidget( const QString &className, QWidget *parent, const char *name, bool init, + const QRect *r, Qt::Orientation orient ) +{ + if ( className == "QPushButton" ) { + QPushButton *b = 0; + if ( init ) { + b = new QDesignerPushButton( parent, name ); + b->setText( QString::fromLatin1( name ) ); + } else { + b = new QDesignerPushButton( parent, name ); + } + QWidget *w = find_formwindow( b ); + b->setAutoDefault( w && ::qt_cast(((FormWindow*)w)->mainContainer()) ); + return b; + } else if ( className == "QToolButton" ) { + if ( init ) { + QDesignerToolButton *tb = new QDesignerToolButton( parent, name ); + if ( ::qt_cast(widgetOfContainer(parent))) { + tb->setUsesTextLabel(TRUE); + tb->setTextLabel("..."); + tb->setAutoRaise(TRUE); + tb->setTextPosition(QToolButton::BesideIcon); + } else { + tb->setText( "..." ); + } + return tb; + } + return new QDesignerToolButton( parent, name ); + } else if ( className == "QCheckBox" ) { + if ( init ) { + QDesignerCheckBox *cb = new QDesignerCheckBox( parent, name ); + cb->setText( QString::fromLatin1( name ) ); + return cb; + } + return new QDesignerCheckBox( parent, name ); + } else if ( className == "QRadioButton" ) { + if ( init ) { + QDesignerRadioButton *rb = new QDesignerRadioButton( parent, name ); + rb->setText( QString::fromLatin1( name ) ); + return rb; + } + return new QDesignerRadioButton( parent, name ); + } else if ( className == "QGroupBox" ) { + if ( init ) + return new QGroupBox( QString::fromLatin1( name ), parent, name ); + return new QGroupBox( parent, name ); + } else if ( className == "QButtonGroup" ) { + if ( init ) + return new QButtonGroup( QString::fromLatin1( name ), parent, name ); + return new QButtonGroup( parent, name ); + } else if ( className == "QIconView" ) { +#if !defined(QT_NO_ICONVIEW) + QIconView* iv = new QIconView( parent, name ); + if ( init ) + (void) new QIconViewItem( iv, MainWindow::tr( "New Item" ) ); + return iv; +#else + return 0; +#endif + } else if ( className == "QTable" ) { +#if !defined(QT_NO_TABLE) + if ( init ) + return new QTable( 3, 3, parent, name ); + return new QTable( parent, name ); +#else + return 0; +#endif +#ifndef QT_NO_SQL + } else if ( className == "QDataTable" ) { + return new QDataTable( parent, name ); +#endif //QT_NO_SQL + } else if ( className == "QDateEdit" ) { + return new QDateEdit( parent, name ); + } else if ( className == "QTimeEdit" ) { + return new QTimeEdit( parent, name ); + } else if ( className == "QDateTimeEdit" ) { + return new QDateTimeEdit( parent, name ); + } + else if ( className == "QListBox" ) { + QListBox* lb = new QListBox( parent, name ); + if ( init ) { + lb->insertItem( MainWindow::tr( "New Item" ) ); + lb->setCurrentItem( 0 ); + } + return lb; + } else if ( className == "QListView" ) { + QListView *lv = new QListView( parent, name ); + lv->setSorting( -1 ); + if ( init ) { + lv->addColumn( MainWindow::tr( "Column 1" ) ); + lv->setCurrentItem( new QListViewItem( lv, MainWindow::tr( "New Item" ) ) ); + } + return lv; + } else if ( className == "QLineEdit" ) + return new QLineEdit( parent, name ); + else if ( className == "QSpinBox" ) + return new QSpinBox( parent, name ); + else if ( className == "QSplitter" ) + return new QSplitter( parent, name ); + else if ( className == "QMultiLineEdit" ) + return new QMultiLineEdit( parent, name ); + else if ( className == "QTextEdit" ) + return new QTextEdit( parent, name ); + else if ( className == "QLabel" || className == "TextLabel" ) { + QDesignerLabel *l = new QDesignerLabel( parent, name ); + if ( init ) { + l->setText( QString::fromLatin1( name ) ); + MetaDataBase::addEntry( l ); + MetaDataBase::setPropertyChanged( l, "text", TRUE ); + } + return l; + } else if ( className == "PixmapLabel" ) { + QDesignerLabel *l = new QDesignerLabel( parent, name ); + if ( init ) { + l->setPixmap( QPixmap::fromMimeSource( "designer_qtlogo.png" ) ); + l->setScaledContents( TRUE ); + MetaDataBase::addEntry( l ); + MetaDataBase::setPropertyChanged( l, "pixmap", TRUE ); + MetaDataBase::setPropertyChanged( l, "scaledContents", TRUE ); + } + return l; + } else if ( className == "QLayoutWidget" ) + return new QLayoutWidget( parent, name ); + else if ( className == "QTabWidget" ) { + QTabWidget *tw = new QDesignerTabWidget( parent, name ); + if ( init ) { + FormWindow *fw = find_formwindow( parent ); + QWidget *w = fw ? new QDesignerWidget( fw, tw, "tab" ) : new QWidget( tw, "tab" ); + tw->addTab( w, MainWindow::tr("Tab 1") ); + MetaDataBase::addEntry( w ); + w = fw ? new QDesignerWidget( fw, tw, "tab" ) : new QWidget( tw, "tab" ); + tw->addTab( w, MainWindow::tr("Tab 2") ); + MetaDataBase::addEntry( tw ); + MetaDataBase::addEntry( w ); + } + return tw; + } else if ( className == "QWidgetStack" ) { + QDesignerWidgetStack *ws = new QDesignerWidgetStack( parent, name ); + if ( init ) { + FormWindow *fw = find_formwindow( parent ); + QWidget *w = fw ? new QDesignerWidget( fw, ws, "WStackPage" ) : new QWidget( ws, "WStackPage" ); + ws->insertPage( w ); + MetaDataBase::addEntry( w ); + MetaDataBase::addEntry( ws ); + } + return ws; + } else if ( className == "QComboBox" ) { + return new QComboBox( FALSE, parent, name ); + } else if ( className == "QWidget" ) { + if ( parent && + ( ::qt_cast(parent) || + ::qt_cast(parent) || + ::qt_cast(parent) || + ::qt_cast(parent) || + ::qt_cast(parent) || + ::qt_cast(parent) ) ) { + FormWindow *fw = find_formwindow( parent ); + if ( fw ) { + QDesignerWidget *dw = new QDesignerWidget( fw, parent, name ); + MetaDataBase::addEntry( dw ); + return dw; + } + } + return new QWidget( parent, name ); + } else if ( className == "QDialog" ) { + QDialog *dia = 0; + if ( ::qt_cast(parent) ) + dia = new QDesignerDialog( (FormWindow*)parent, parent, name ); + else + dia = new QDialog( parent, name ); +#if defined(QT_NON_COMMERCIAL) + if ( ::qt_cast(parent) ) +#else + if ( parent ) +#endif + dia->reparent( parent, QPoint( 0, 0 ), TRUE ); + return dia; + } else if ( className == "QWizard" ) { + QWizard *wiz = new QDesignerWizard( parent, name ); +#if defined(QT_NON_COMMERCIAL) + if ( ::qt_cast(parent) ) +#else + if ( parent ) +#endif + wiz->reparent( parent, QPoint( 0, 0 ), TRUE ); + if ( init && ::qt_cast(parent) ) { + QDesignerWidget *dw = new QDesignerWidget( (FormWindow*)parent, wiz, "WizardPage" ); + MetaDataBase::addEntry( dw ); + wiz->addPage( dw, FormWindow::tr( "Page" ) ); + QTimer::singleShot( 0, wiz, SLOT( next() ) ); + } + return wiz; + } else if ( className == "Spacer" ) { + Spacer *s = new Spacer( parent, name ); + MetaDataBase::addEntry( s ); + MetaDataBase::setPropertyChanged( s, "orientation", TRUE ); + MetaDataBase::setPropertyChanged( s, "sizeType", TRUE ); + if ( !r ) + return s; + if ( !r->isValid() || r->width() < 2 && r->height() < 2 ) + s->setOrientation( orient ); + else if ( r->width() < r->height() ) + s->setOrientation( Qt::Vertical ); + else + s->setOrientation( Qt::Horizontal ); + return s; + } else if ( className == "QLCDNumber" ) + return new QLCDNumber( parent, name ); + else if ( className == "QProgressBar" ) + return new QProgressBar( parent, name ); + else if ( className == "QTextView" ) + return new QTextView( parent, name ); + else if ( className == "QTextBrowser" ) + return new QTextBrowser( parent, name ); + else if ( className == "QDial" ) + return new QDial( parent, name ); + else if ( className == "QSlider" ) { + QSlider *s = new QSlider( parent, name ); + if ( !r ) + return s; + if ( !r->isValid() || r->width() < 2 && r->height() < 2 ) + s->setOrientation( orient ); + else if ( r->width() > r->height() ) + s->setOrientation( Qt::Horizontal ); + MetaDataBase::addEntry( s ); + MetaDataBase::setPropertyChanged( s, "orientation", TRUE ); + return s; + } else if ( className == "QScrollBar" ) { + QScrollBar *s = new QScrollBar( parent, name ); + if ( !r ) + return s; + if ( !r->isValid() || r->width() < 2 && r->height() < 2 ) + s->setOrientation( orient ); + else if ( r->width() > r->height() ) + s->setOrientation( Qt::Horizontal ); + MetaDataBase::addEntry( s ); + MetaDataBase::setPropertyChanged( s, "orientation", TRUE ); + return s; + } else if ( className == "QFrame" ) { + if ( !init ) + return new QFrame( parent, name ); + QFrame *f = new QFrame( parent, name ); + f->setFrameStyle( QFrame::StyledPanel | QFrame::Raised ); + return f; + } else if ( className == "Line" ) { + Line *l = new Line( parent, name ); + MetaDataBase::addEntry( l ); + MetaDataBase::setPropertyChanged( l, "orientation", TRUE ); + MetaDataBase::setPropertyChanged( l, "frameShadow", TRUE ); + MetaDataBase::setPropertyChanged( l, "frameShape", TRUE ); + if ( !r ) + return l; + if ( !r->isValid() || r->width() < 2 && r->height() < 2 ) + l->setOrientation( orient ); + else if ( r->width() < r->height() ) + l->setOrientation( Qt::Vertical ); + return l; + } else if ( className == "QMainWindow" ) { + QMainWindow *mw = new QMainWindow( parent, name, 0 ); + mw->setDockEnabled( Qt::DockMinimized, FALSE ); + QDesignerWidget *dw = new QDesignerWidget( (FormWindow*)parent, mw, "central widget" ); + mw->setDockMenuEnabled( FALSE ); + MetaDataBase::addEntry( dw ); + mw->setCentralWidget( dw ); + (void)mw->statusBar(); + dw->show(); + return mw; + } else if ( className == "QToolBox" ) { + if ( !init ) + return new QDesignerToolBox( parent, name ); + QToolBox *tb = new QDesignerToolBox( parent, name ); + FormWindow *fw = find_formwindow( parent ); + QWidget *w = fw ? new QDesignerWidget( fw, tb, "page1" ) : + new QWidget( tb, "page1" ); + tb->addItem( w, MainWindow::tr("Page 1") ); + MetaDataBase::addEntry( w ); + w = fw ? new QDesignerWidget( fw, tb, "page2" ) : new QWidget( tb, "page2" ); + tb->addItem( w, MainWindow::tr("Page 2") ); + MetaDataBase::addEntry( tb ); + MetaDataBase::addEntry( w ); + return tb; + } +#ifndef QT_NO_SQL + else if ( className == "QDataBrowser" ) { + QWidget *w = new QDesignerDataBrowser( parent, name ); + if ( parent ) + w->reparent( parent, QPoint( 0, 0 ), TRUE ); + return w; + } else if ( className == "QDataView" ) { + QWidget *w = new QDesignerDataView( parent, name ); + if ( parent ) + w->reparent( parent, QPoint( 0, 0 ), TRUE ); + return w; + } +#endif + + WidgetInterface *iface = 0; + widgetManager()->queryInterface( className, &iface ); + if ( !iface ) + return 0; + + QWidget *w = iface->create( className, parent, name ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + if ( init && WidgetDatabase::isCustomPluginWidget( WidgetDatabase::idFromClassName( className ) ) ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + iface2->addPage( className, w, "Page", -1 ); + iface2->release(); + } + } +#endif // QT_CONTAINER_CUSTOM_WIDGETS + iface->release(); + return w; +} + + + +/*! Find out which type the layout of the widget is. Returns \c HBox, + \c VBox, \c Grid or \c NoLayout. \a layout points to this + QWidget::layout() of \a w or to 0 after the function call. +*/ + +WidgetFactory::LayoutType WidgetFactory::layoutType( QWidget *w, QLayout *&layout ) +{ + layout = 0; + + if ( ::qt_cast(w) ) + w = ((QTabWidget*)w)->currentPage(); + if ( ::qt_cast(w) ) + w = ((QWizard*)w)->currentPage(); + if ( ::qt_cast(w) ) + w = ((QMainWindow*)w)->centralWidget(); + if ( ::qt_cast(w) ) + w = ((QWidgetStack*)w)->visibleWidget(); + if ( ::qt_cast(w) ) + w = ((QToolBox*)w)->currentItem(); + + if ( ::qt_cast(w) ) + return ( (QSplitter*)w )->orientation() == Horizontal ? HBox : VBox; + + if ( !w || !w->layout() ) + return NoLayout; + QLayout *lay = w->layout(); + + if ( ::qt_cast(w) ) { + QObjectList *l = lay->queryList( "QLayout" ); + if ( l && l->first() ) + lay = (QLayout*)l->first(); + delete l; + } + layout = lay; + + if ( ::qt_cast(lay) ) + return HBox; + else if ( ::qt_cast(lay) ) + return VBox; + else if ( ::qt_cast(lay) ) + return Grid; + return NoLayout; +} + +/*! + \overload +*/ +WidgetFactory::LayoutType WidgetFactory::layoutType( QLayout *layout ) +{ + if ( ::qt_cast(layout) ) + return HBox; + else if ( ::qt_cast(layout) ) + return VBox; + else if ( ::qt_cast(layout) ) + return Grid; + return NoLayout; +} + +/*! + \overload +*/ +WidgetFactory::LayoutType WidgetFactory::layoutType( QWidget *w ) +{ + QLayout *l = 0; + return layoutType( w, l ); +} + + +QWidget *WidgetFactory::layoutParent( QLayout *layout ) +{ + QObject *o = layout; + while ( o ) { + if ( o->isWidgetType() ) + return (QWidget*)o; + o = o->parent(); + } + return 0; +} + +/*! Returns the widget into which children should be inserted when \a + w is a container known to the designer. + + Usually that is \a w itself, sometimes it is different (e.g. a + tabwidget is known to the designer as a container but the child + widgets should be inserted into the current page of the + tabwidget. So in this case this function returns the current page of + the tabwidget.) + */ +QWidget* WidgetFactory::containerOfWidget( QWidget *w ) +{ + if ( !w ) + return w; + if ( ::qt_cast(w) ) + return ((QTabWidget*)w)->currentPage(); + if ( ::qt_cast(w) ) + return ((QWizard*)w)->currentPage(); + if ( ::qt_cast(w) ) + return ((QWidgetStack*)w)->visibleWidget(); + if ( ::qt_cast(w) ) + return ((QToolBox*)w)->currentItem(); + if ( ::qt_cast(w) ) + return ((QMainWindow*)w)->centralWidget(); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + if ( !WidgetDatabase::isCustomPluginWidget( WidgetDatabase::idFromClassName( classNameOf( w ) ) ) ) + return w; + WidgetInterface *iface = 0; + widgetManager()->queryInterface( classNameOf( w ), &iface ); + if ( !iface ) + return w; + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( !iface2 ) + return w; + QWidget *c = iface2->containerOfWidget( w->className(), w ); + iface2->release(); + iface->release(); + if ( c ) + return c; +#endif // QT_CONTAINER_CUSTOM_WIDGETS + return w; +} + +/*! Returns the actual designer widget of the container \a w. This is + normally \a w itself, but might be a parent or grand parent of \a w + (e.g. when working with a tabwidget and \a w is the container which + contains and layouts childs, but the actual widget known to the + designer is the tabwidget which is the parent of \a w. So this + function returns the tabwidget then.) +*/ + +QWidget* WidgetFactory::widgetOfContainer( QWidget *w ) +{ + if ( w && ::qt_cast(w->parentWidget()) ) + w = w->parentWidget(); + if ( w->parentWidget() && w->parentWidget()->parentWidget() && + w->parentWidget()->parentWidget()->parentWidget() && + ::qt_cast(w->parentWidget()->parentWidget()->parentWidget()) ) + return w->parentWidget()->parentWidget()->parentWidget(); + while ( w ) { + int id = WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ); + if ( WidgetDatabase::isContainer( id ) || + w && ::qt_cast(w->parentWidget()) ) + return w; + w = w->parentWidget(); + } + return w; +} + +/*! + Returns whether \a o is a passive interactor or not. + */ + +bool WidgetFactory::lastWasAPassiveInteractor = FALSE; +QGuardedPtr *WidgetFactory::lastPassiveInteractor = new QGuardedPtr(); + +bool WidgetFactory::isPassiveInteractor( QObject* o ) +{ + if ( lastPassiveInteractor && *lastPassiveInteractor && (QObject*)(*lastPassiveInteractor) == o ) + return lastWasAPassiveInteractor; + lastWasAPassiveInteractor = FALSE; + (*lastPassiveInteractor) = o; + if ( QApplication::activePopupWidget() ) // if a popup is open, we have to make sure that this one is closed, else X might do funny things + return ( lastWasAPassiveInteractor = TRUE ); + + if ( ::qt_cast(o) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( ::qt_cast(o) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( ::qt_cast(o) && + ( ::qt_cast(o->parent()) || ::qt_cast(o->parent()) ) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( ::qt_cast(o) && ::qt_cast(o->parent()) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( ::qt_cast(o) && ::qt_cast(o->parent()) ) + return ( lastWasAPassiveInteractor = TRUE ); +// else if ( ::qt_cast(o) ) + else if ( o->inherits( "QDockWindowHandle" ) ) + return ( lastWasAPassiveInteractor = TRUE ); +// else if ( ::qt_cast(o) ) + else if ( o->inherits( "QHideDock" ) ) + return ( lastWasAPassiveInteractor = TRUE ); + else if ( qstrcmp( o->name(), "designer_wizardstack_button" ) == 0 ) + return ( lastWasAPassiveInteractor = TRUE ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + if ( !o->isWidgetType() ) + return ( lastWasAPassiveInteractor = FALSE ); + WidgetInterface *iface = 0; + QWidget *w = (QWidget*)o; + while ( !iface && w && !::qt_cast(w) ) { + widgetManager()->queryInterface( classNameOf( w ), &iface ); + w = w->parentWidget(); + } + if ( !iface ) + return ( lastWasAPassiveInteractor = FALSE ); + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( !iface2 ) + return ( lastWasAPassiveInteractor = FALSE ); + QWidget *fw = MainWindow::self->isAFormWindowChild( (QWidget*)o ); + if ( !fw ) + return ( lastWasAPassiveInteractor = FALSE ); + QWidget *dw = ( (FormWindow*)fw )->designerWidget( (QWidget*)o ); + if ( !dw ) + return ( lastWasAPassiveInteractor = FALSE ); + lastWasAPassiveInteractor = iface2->isPassiveInteractor( dw->className(), (QWidget*)o ); + iface2->release(); + iface->release(); +#endif // QT_CONTAINER_CUSTOM_WIDGETS + return lastWasAPassiveInteractor; +} + + +/*! + Returns the class name of object \a o that should be used for externally (i.e. for saving) + */ +const char* WidgetFactory::classNameOf( QObject* o ) +{ + if ( o->isA( "PropertyObject" ) ) + return o->className(); + if (WidgetDatabase::isCustomPluginWidget(WidgetDatabase::idFromClassName(o->className()))) + return o->className(); + else if ( ::qt_cast(o) ) + return "QTabWidget"; + else if ( ::qt_cast(o) ) + return "QWidgetStack"; + else if ( ::qt_cast(o) ) + return "QWeDoNotWantToBreakTabWidget"; + else if ( ::qt_cast(o) ) + return "QDialog"; + else if ( ::qt_cast(o) ) + return "QWidget"; + else if ( o->inherits( "CustomWidget" ) ) + return ( (CustomWidget*)o )->realClassName().latin1(); + else if ( ::qt_cast(o) ) + return "QLabel"; + else if ( ::qt_cast(o) ) + return "QWizard"; + else if ( ::qt_cast(o) ) + return "QPushButton"; + else if ( ::qt_cast(o) ) + return "QToolButton"; + else if ( ::qt_cast(o) ) + return "QRadioButton"; + else if ( ::qt_cast(o) ) + return "QCheckBox"; + else if ( ::qt_cast(o) ) + return "QMenuBar"; + else if ( ::qt_cast(o) ) + return "QToolBar"; + else if ( ::qt_cast(o) ) + return "QAction"; + else if ( ::qt_cast(o) ) + return "QActionGroup"; + else if ( ::qt_cast(o) ) + return "QPopupMenu"; + else if ( ::qt_cast(o) ) + return "QToolBox"; +#ifndef QT_NO_SQL + else if ( ::qt_cast(o) ) + return "QDataBrowser"; + else if ( ::qt_cast(o) ) + return "QDataView"; +#endif + return o->className(); +} + +QString WidgetFactory::defaultSignal( QObject *w ) +{ + if ( ::qt_cast(w) || ::qt_cast(w) ) + return "toggled"; + else if ( ::qt_cast(w) || ::qt_cast(w) ) + return "clicked"; + else if ( ::qt_cast(w) ) + return "linkClicked"; + else if ( ::qt_cast(w) || ::qt_cast(w) ) + return "textChanged"; + else if ( ::qt_cast(w) || ::qt_cast(w) || + ::qt_cast(w) || ::qt_cast(w) ) + return "selectionChanged"; + else if ( ::qt_cast(w) ) + return "selected"; + else if ( ::qt_cast(w) ) + return "currentChanged"; + else if ( ::qt_cast(w) ) + return "aboutToShow"; + else if ( ::qt_cast(w) || ::qt_cast(w) || + ::qt_cast(w) || ::qt_cast(w) || + ::qt_cast(w) || ::qt_cast(w) || + ::qt_cast(w) ) + return "valueChanged"; + else if ( ::qt_cast(w) ) + return "activated"; + return QString::null; +} + +/*! As some properties are set by default when creating a widget this + functions markes this properties as changed. Has to be in sync with + createWidget()! +*/ + +void WidgetFactory::initChangedProperties( QObject *o ) +{ + if ( MainWindow::self && MainWindow::self->currProject() && + MainWindow::self->currProject()->fakeFormFileFor( o ) ) + return; + MetaDataBase::setPropertyChanged( o, "name", TRUE ); + if ( !::qt_cast(o) && !::qt_cast(o) ) + MetaDataBase::setPropertyChanged( o, "geometry", TRUE ); + + if ( ::qt_cast(o) || + ::qt_cast(o) || + ::qt_cast(o) || + ::qt_cast(o) ) { + if (::qt_cast(o) && ::qt_cast(widgetOfContainer((QWidget*)o->parent()))) { + MetaDataBase::setPropertyChanged( o, "usesTextLabel", TRUE ); + MetaDataBase::setPropertyChanged( o, "textLabel", TRUE ); + MetaDataBase::setPropertyChanged( o, "autoRaise", TRUE ); + MetaDataBase::setPropertyChanged( o, "textPosition", TRUE ); + } else { + MetaDataBase::setPropertyChanged( o, "text", TRUE ); + } + } + else if ( ::qt_cast(o) ) + MetaDataBase::setPropertyChanged( o, "title", TRUE ); + else if ( o->isA( "QFrame" ) ) { + MetaDataBase::setPropertyChanged( o, "frameShadow", TRUE ); + MetaDataBase::setPropertyChanged( o, "frameShape", TRUE ); + } else if ( ::qt_cast(o) || ::qt_cast(o) ) { + MetaDataBase::setPropertyChanged( o, "pageTitle", TRUE ); + MetaDataBase::setPropertyChanged( o, "pageName", TRUE ); + MetaDataBase::setPropertyChanged( o, "currentPage", TRUE ); + } else if ( ::qt_cast(o) ) { + MetaDataBase::setPropertyChanged( o, "currentPage", TRUE ); + MetaDataBase::setPropertyChanged( o, "pageName", TRUE ); + } else if ( ::qt_cast(o) ) { + MetaDataBase::setPropertyChanged( o, "currentIndex", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemName", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemLabel", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemIconSet", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemToolTip", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemBackgroundMode", TRUE ); +#ifndef QT_NO_TABLE + } else if ( ::qt_cast(o) ) { +# ifndef QT_NO_SQL + if (!::qt_cast(o) ) +# endif + { + MetaDataBase::setPropertyChanged( o, "numRows", TRUE ); + MetaDataBase::setPropertyChanged( o, "numCols", TRUE ); + QTable *t = (QTable*)o; + for ( int i = 0; i < 3; ++i ) { + t->horizontalHeader()->setLabel( i, QString::number( i + 1 ) ); + t->verticalHeader()->setLabel( i, QString::number( i + 1 ) ); + } + } +#endif + } else if ( ::qt_cast(o) ) { + MetaDataBase::setPropertyChanged( o, "orientation", TRUE ); + } else if ( ::qt_cast(o) ) { + MetaDataBase::setPropertyChanged( o, "label", TRUE ); + } else if ( ::qt_cast(o) ) { + MetaDataBase::setPropertyChanged( o, "itemName", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemNumber", TRUE ); + MetaDataBase::setPropertyChanged( o, "itemText", TRUE ); + } +} + +bool WidgetFactory::hasSpecialEditor( int id, QObject *editorWidget ) +{ + QString className = WidgetDatabase::className( id ); + + if ( className.contains( "ListBox" ) ) + return TRUE; + if ( className.contains( "ComboBox" ) ) + return TRUE; + if ( className.contains( "ListView" ) ) + return TRUE; + if ( className.contains( "IconView" ) ) + return TRUE; + if ( className == "QTextEdit" || className == "QMultiLineEdit" ) + return TRUE; + if ( ::qt_cast(editorWidget) != 0 ) + return TRUE; + + return FALSE; +} + +bool WidgetFactory::hasItems( int id, QObject *editorWidget ) +{ + QString className = WidgetDatabase::className( id ); + + if ( className.contains( "ListBox" ) || className.contains( "ListView" ) || + className.contains( "IconView" ) || className.contains( "ComboBox" ) || + ::qt_cast(editorWidget) != 0 ) + return TRUE; + + return FALSE; +} + +void WidgetFactory::editWidget( int id, QWidget *parent, QWidget *editWidget, FormWindow *fw ) +{ + QString className = WidgetDatabase::className( id ); + + if ( className.contains( "ListBox" ) ) { + if ( !::qt_cast(editWidget) ) + return; + ListBoxEditor *e = new ListBoxEditor( parent, editWidget, fw ); + e->exec(); + delete e; + return; + } + + if ( className.contains( "ComboBox" ) ) { + if ( !::qt_cast(editWidget) ) + return; + QComboBox *cb = (QComboBox*)editWidget; + QListBox *lb = cb->listBox(); + if (!lb) { + lb = new QListBox(cb); + cb->setListBox(lb); + } + ListBoxEditor *e = new ListBoxEditor( parent, lb, fw ); + e->exec(); + delete e; + cb->update(); + return; + } + + if ( className.contains( "ListView" ) ) { + if ( !::qt_cast(editWidget) ) + return; + QListView *lv = (QListView*)editWidget; + ListViewEditor *e = new ListViewEditor( parent, lv, fw ); + e->exec(); + delete e; + return; + } + + if ( className.contains( "IconView" ) ) { + if ( !::qt_cast(editWidget) ) + return; + IconViewEditor *e = new IconViewEditor( parent, editWidget, fw ); + e->exec(); + delete e; + return; + } + + if ( className == "QMultiLineEdit" || className == "QTextEdit" ) { + MultiLineEditor *e = new MultiLineEditor( FALSE, TRUE, parent, editWidget, fw ); + e->exec(); + delete e; + return; + } +#ifndef QT_NO_TABLE + if (::qt_cast(editWidget) != 0) { + TableEditor *e = new TableEditor( parent, editWidget, fw ); + e->exec(); + delete e; + return; + } +#endif +} + +bool WidgetFactory::canResetProperty( QObject *w, const QString &propName ) +{ + if ( propName == "name" || propName == "geometry" ) + return FALSE; + QStringList l = *changedProperties->find( WidgetDatabase::idFromClassName( WidgetFactory::classNameOf( w ) ) ); + return l.findIndex( propName ) == -1; +} + +bool WidgetFactory::resetProperty( QObject *w, const QString &propName ) +{ + const QMetaProperty *p = w->metaObject()->property( w->metaObject()-> + findProperty( propName, TRUE ), TRUE ); + if (!p ) + return FALSE; + return p->reset( w ); +} + +QVariant WidgetFactory::defaultValue( QObject *w, const QString &propName ) +{ + if ( propName == "wordwrap" ) { + int v = defaultValue( w, "alignment" ).toInt(); + return QVariant( ( v & WordBreak ) == WordBreak, 0 ); + } else if ( propName == "toolTip" || propName == "whatsThis" ) { + return QVariant( QString::fromLatin1( "" ) ); + } else if ( w->inherits( "CustomWidget" ) ) { + return QVariant(); + } else if ( propName == "frameworkCode" ) { + return QVariant( TRUE, 0 ); + } else if ( propName == "layoutMargin" || propName == "layoutSpacing" ) { + return QVariant( -1 ); + } + + return *( *defaultProperties->find( WidgetDatabase::idFromClassName( classNameOf( w ) ) ) ).find( propName ); +} + +QString WidgetFactory::defaultCurrentItem( QObject *w, const QString &propName ) +{ + const QMetaProperty *p = w->metaObject()-> + property( w->metaObject()->findProperty( propName, TRUE ), TRUE ); + if ( !p ) { + int v = defaultValue( w, "alignment" ).toInt(); + if ( propName == "hAlign" ) { + if ( ( v & AlignAuto ) == AlignAuto ) + return "AlignAuto"; + if ( ( v & AlignLeft ) == AlignLeft ) + return "AlignLeft"; + if ( ( v & AlignCenter ) == AlignCenter || ( v & AlignHCenter ) == AlignHCenter ) + return "AlignHCenter"; + if ( ( v & AlignRight ) == AlignRight ) + return "AlignRight"; + if ( ( v & AlignJustify ) == AlignJustify ) + return "AlignJustify"; + } else if ( propName == "vAlign" ) { + if ( ( v & AlignTop ) == AlignTop ) + return "AlignTop"; + if ( ( v & AlignCenter ) == AlignCenter || ( v & AlignVCenter ) == AlignVCenter ) + return "AlignVCenter"; + if ( ( v & AlignBottom ) == AlignBottom ) + return "AlignBottom"; + } else if ( propName == "resizeMode" ) { + return "Auto"; + } + return QString::null; + + } + return p->valueToKey( defaultValue( w, propName ).toInt() ); +} + +QWidget *WidgetFactory::createCustomWidget( QWidget *parent, const char *name, MetaDataBase::CustomWidget *w ) +{ + if ( !w ) + return 0; + return new CustomWidget( parent, name, w ); +} + +QVariant WidgetFactory::property( QObject *w, const char *name ) +{ + int id = w->metaObject()->findProperty( name, TRUE ); + const QMetaProperty* p = w->metaObject()->property( id, TRUE ); + if ( !p || !p->isValid() ) + return MetaDataBase::fakeProperty( w, name ); + return w->property( name ); +} + +void QDesignerLabel::updateBuddy() +{ + + if ( myBuddy.isEmpty() ) + return; + + QObjectList *l = topLevelWidget()->queryList( "QWidget", myBuddy, FALSE, TRUE ); + if ( !l || !l->first() ) { + delete l; + return; + } + + QLabel::setBuddy( (QWidget*)l->first() ); + delete l; +} + + +void QDesignerWidget::resizeEvent( QResizeEvent* e) +{ + if ( need_frame ) { + QPainter p(this); + p.setPen( backgroundColor() ); + p.drawRect( QRect( QPoint(0,0), e->oldSize() ) ); + } +} + +void QDesignerWidget::paintEvent( QPaintEvent *e ) +{ + if ( need_frame ) { + QPainter p(this); + p.setPen( backgroundColor().dark() ); + p.drawRect( rect() ); + } + formwindow->paintGrid( this, e ); +} + +void QDesignerDialog::paintEvent( QPaintEvent *e ) +{ + formwindow->paintGrid( this, e ); +} + +QSizePolicy QLayoutWidget::sizePolicy() const +{ + return sp; +} + +bool QLayoutWidget::event( QEvent *e ) +{ + if ( e && ( e->type() == QEvent::ChildInserted || + e->type() == QEvent::ChildRemoved || + e->type() == QEvent::LayoutHint || + e->type() == QEvent::Reparent ) ) + updateSizePolicy(); + return QWidget::event( e ); +} + +/* + This function must be called on QLayoutWidget creation and whenever + the QLayoutWidget's parent layout changes (e.g., from a QHBoxLayout + to a QVBoxLayout), because of the (illogical) way layouting works. +*/ +void QLayoutWidget::updateSizePolicy() +{ + if ( !children() || children()->count() == 0 ) { + sp = QWidget::sizePolicy(); + return; + } + + /* + QSizePolicy::MayShrink & friends are private. Here we assume the + following: + + Fixed = 0 + Maximum = MayShrink + Minimum = MayGrow + Preferred = MayShrink | MayGrow + */ + + int ht = (int) QSizePolicy::Preferred; + int vt = (int) QSizePolicy::Preferred; + + if ( layout() ) { + /* + parentLayout is set to the parent layout if there is one and if it is + top level, in which case layouting is illogical. + */ + QLayout *parentLayout = 0; + if ( parent() && parent()->isWidgetType() ) { + parentLayout = ((QWidget *)parent())->layout(); + if ( parentLayout && + ::qt_cast(parentLayout->mainWidget()) ) + parentLayout = 0; + } + + QObjectListIt it( *children() ); + QObject *o; + + if ( ::qt_cast(layout()) ) { + if ( ::qt_cast(parentLayout) ) + vt = QSizePolicy::Minimum; + else + vt = QSizePolicy::Fixed; + + while ( ( o = it.current() ) ) { + ++it; + if ( !o->isWidgetType() || ( (QWidget*)o )->testWState( WState_ForceHide ) ) + continue; + QWidget *w = (QWidget*)o; + + if ( !w->sizePolicy().mayGrowHorizontally() ) + ht &= ~QSizePolicy::Minimum; + if ( !w->sizePolicy().mayShrinkHorizontally() ) + ht &= ~QSizePolicy::Maximum; + if ( w->sizePolicy().mayGrowVertically() ) + vt |= QSizePolicy::Minimum; + if ( w->sizePolicy().mayShrinkVertically() ) + vt |= QSizePolicy::Maximum; + } + } else if ( ::qt_cast(layout()) ) { + if ( ::qt_cast(parentLayout) ) + ht = QSizePolicy::Minimum; + else + ht = QSizePolicy::Fixed; + + while ( ( o = it.current() ) ) { + ++it; + if ( !o->isWidgetType() || ( (QWidget*)o )->testWState( WState_ForceHide ) ) + continue; + QWidget *w = (QWidget*)o; + + if ( w->sizePolicy().mayGrowHorizontally() ) + ht |= QSizePolicy::Minimum; + if ( w->sizePolicy().mayShrinkHorizontally() ) + ht |= QSizePolicy::Maximum; + if ( !w->sizePolicy().mayGrowVertically() ) + vt &= ~QSizePolicy::Minimum; + if ( !w->sizePolicy().mayShrinkVertically() ) + vt &= ~QSizePolicy::Maximum; + } + } else if ( ::qt_cast(layout()) ) { + ht = QSizePolicy::Fixed; + vt = QSizePolicy::Fixed; + if ( parentLayout ) { + if ( ::qt_cast(parentLayout) ) + ht = QSizePolicy::Minimum; + else if ( ::qt_cast(parentLayout) ) + vt = QSizePolicy::Minimum; + } + + while ( ( o = it.current() ) ) { + ++it; + if ( !o->isWidgetType() || ( (QWidget*)o )->testWState( WState_ForceHide ) ) + continue; + QWidget *w = (QWidget*)o; + + if ( w->sizePolicy().mayGrowHorizontally() ) + ht |= QSizePolicy::Minimum; + if ( w->sizePolicy().mayShrinkHorizontally() ) + ht |= QSizePolicy::Maximum; + if ( w->sizePolicy().mayGrowVertically() ) + vt |= QSizePolicy::Minimum; + if ( w->sizePolicy().mayShrinkVertically() ) + vt |= QSizePolicy::Maximum; + } + } + if ( layout()->expanding() & QSizePolicy::Horizontally ) + ht = QSizePolicy::Expanding; + if ( layout()->expanding() & QSizePolicy::Vertically ) + vt = QSizePolicy::Expanding; + + layout()->invalidate(); + } + + sp = QSizePolicy( (QSizePolicy::SizeType) ht, (QSizePolicy::SizeType) vt ); + updateGeometry(); +} + +void CustomWidget::paintEvent( QPaintEvent *e ) +{ + if ( ::qt_cast(parentWidget()) ) { + ( (FormWindow*)parentWidget() )->paintGrid( this, e ); + } else { + QPainter p( this ); + p.fillRect( rect(), colorGroup().dark() ); + p.setPen( colorGroup().light() ); + p.drawText( 2, 2, width() - 4, height() - 4, Qt::AlignAuto | Qt::AlignTop, cusw->className ); + p.drawPixmap( ( width() - cusw->pixmap->width() ) / 2, + ( height() - cusw->pixmap->height() ) / 2, + *cusw->pixmap ); + } +} + + +CustomWidgetFactory::CustomWidgetFactory() +{ +} + +QWidget *CustomWidgetFactory::createWidget( const QString &className, QWidget *parent, const char *name ) const +{ + MetaDataBase::CustomWidget *w = MetaDataBase::customWidget( WidgetDatabase::idFromClassName( className ) ); + if ( !w ) + return 0; + return WidgetFactory::createCustomWidget( parent, name, w ); +} + +void QDesignerRadioButton::setFocusPolicy( FocusPolicy policy ) +{ + // Make sure we only set a policy that has a key. + // If we set a policy that is a combination of enums, it will be imposible to save + // We need this check because QButtonGroup::buttonToggled(...) will remove TabFocus, + // making the policy StrongFocus & ~TabFocus + + switch ( policy ) { + case NoFocus: + case TabFocus: + case ClickFocus: + case StrongFocus: + case WheelFocus: + QRadioButton::setFocusPolicy( policy ); + return; + } + QRadioButton::setFocusPolicy( NoFocus ); +} + +QDesignerToolBox::QDesignerToolBox( QWidget *parent, const char *name ) + : QToolBox( parent, name ) +{ +} + +QString QDesignerToolBox::itemLabel() const +{ + return QToolBox::itemLabel( currentIndex() ); +} + +void QDesignerToolBox::setItemLabel( const QString &l ) +{ + QToolBox::setItemLabel( currentIndex(), l ); +} + +QCString QDesignerToolBox::itemName() const +{ + return currentItem() ? currentItem()->name() : 0; +} + +void QDesignerToolBox::setItemName( const QCString &n ) +{ + if (currentItem()) + currentItem()->setName( n ); +} + + +Qt::BackgroundMode QDesignerToolBox::itemBackgroundMode() const +{ + return (item(0) ? item(0)->backgroundMode() : PaletteBackground); +} + +void QDesignerToolBox::setItemBackgroundMode( BackgroundMode bmode ) +{ + for (int i = 0; i < count(); ++i) { + QWidget *w = item(i); + w->setBackgroundMode( bmode ); + w->update(); + } +} + +void QDesignerToolBox::itemInserted( int index ) +{ + if (count() > 1) + item(index)->setBackgroundMode(item(index>0?0:1)->backgroundMode()); +} diff --git a/tools/designer/designer/widgetfactory.h b/tools/designer/designer/widgetfactory.h new file mode 100644 index 0000000..8f12193 --- /dev/null +++ b/tools/designer/designer/widgetfactory.h @@ -0,0 +1,509 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef WIDGETFACTORY_H +#define WIDGETFACTORY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "metadatabase.h" +#include "qwidgetfactory.h" + +class QWidget; +class QLayout; +class FormWindow; + +class CustomWidgetFactory : public QWidgetFactory +{ +public: + CustomWidgetFactory(); + QWidget *createWidget( const QString &className, QWidget *parent, const char *name ) const; + +}; + +class WidgetFactory : public Qt +{ + friend class CustomWidgetFactory; + +public: + enum LayoutType { + HBox, + VBox, + Grid, + NoLayout + }; + + static QWidget *create( int id, QWidget *parent, const char *name = 0, bool init = TRUE, + const QRect *rect = 0, Qt::Orientation orient = Qt::Horizontal ); + static QLayout *createLayout( QWidget *widget, QLayout* layout, LayoutType type ); + static void deleteLayout( QWidget *widget ); + + static LayoutType layoutType( QWidget *w ); + static LayoutType layoutType( QWidget *w, QLayout *&layout ); + static LayoutType layoutType( QLayout *layout ); + static QWidget *layoutParent( QLayout *layout ); + + static QWidget* containerOfWidget( QWidget *w ); + static QWidget* widgetOfContainer( QWidget *w ); + + static bool isPassiveInteractor( QObject* o ); + static const char* classNameOf( QObject* o ); + + static void initChangedProperties( QObject *o ); + + static bool hasSpecialEditor( int id, QObject *editorWidget ); + static bool hasItems( int id, QObject *editorWidget ); + static void editWidget( int id, QWidget *parent, QWidget *editWidget, FormWindow *fw ); + + static bool canResetProperty( QObject *w, const QString &propName ); + static bool resetProperty( QObject *w, const QString &propName ); + static QVariant defaultValue( QObject *w, const QString &propName ); + static QString defaultCurrentItem( QObject *w, const QString &propName ); + + static QVariant property( QObject *w, const char *name ); + static void saveDefaultProperties( QObject *w, int id ); + static void saveChangedProperties( QObject *w, int id ); + + static QString defaultSignal( QObject *w ); + +private: + static QWidget *createWidget( const QString &className, QWidget *parent, const char *name, bool init, + const QRect *r = 0, Qt::Orientation orient = Qt::Horizontal ); + static QWidget *createCustomWidget( QWidget *parent, const char *name, MetaDataBase::CustomWidget *w ); + + static QGuardedPtr *lastPassiveInteractor; + static bool lastWasAPassiveInteractor; +}; + + +class QDesignerTabWidget : public QTabWidget +{ + Q_OBJECT + Q_PROPERTY( int currentPage READ currentPage WRITE setCurrentPage STORED false DESIGNABLE true ) + Q_PROPERTY( QString pageTitle READ pageTitle WRITE setPageTitle STORED false DESIGNABLE true ) + Q_PROPERTY( QCString pageName READ pageName WRITE setPageName STORED false DESIGNABLE true ) +public: + QDesignerTabWidget( QWidget *parent, const char *name ); + + int currentPage() const; + void setCurrentPage( int i ); + QString pageTitle() const; + void setPageTitle( const QString& title ); + QCString pageName() const; + void setPageName( const QCString& name ); + + int count() const; + QTabBar *tabBar() const { return QTabWidget::tabBar(); } + + bool eventFilter( QObject*, QEvent* ); + +private: + QPoint pressPoint; + QWidget *dropIndicator; + QWidget *dragPage; + QString dragLabel; + bool mousePressed; +}; + +class QDesignerWidgetStack : public QWidgetStack +{ + Q_OBJECT + Q_PROPERTY( int currentPage READ currentPage WRITE setCurrentPage STORED false DESIGNABLE true ) + Q_PROPERTY( QCString pageName READ pageName WRITE setPageName STORED false DESIGNABLE true ) +public: + QDesignerWidgetStack( QWidget *parent, const char *name ); + + int currentPage() const; + void setCurrentPage( int i ); + QCString pageName() const; + void setPageName( const QCString& name ); + + int count() const; + QWidget* page( int i ) const; + + int insertPage( QWidget *p, int i = -1 ); + int removePage( QWidget *p ); + +public slots: + void updateButtons(); + +protected: + void resizeEvent( QResizeEvent *e ) { + QWidgetStack::resizeEvent( e ); + updateButtons(); + } + + void showEvent( QShowEvent *e ) { + QWidgetStack::showEvent( e ); + updateButtons(); + } + +private slots: + void prevPage(); + void nextPage(); + +private: + QPtrList pages; + QToolButton *prev, *next; + +}; + +class QDesignerWizard : public QWizard +{ + Q_OBJECT + Q_PROPERTY( int currentPage READ currentPageNum WRITE setCurrentPage STORED false DESIGNABLE true ) + Q_PROPERTY( QString pageTitle READ pageTitle WRITE setPageTitle STORED false DESIGNABLE true ) + Q_PROPERTY( QCString pageName READ pageName WRITE setPageName STORED false DESIGNABLE true ) + Q_OVERRIDE( bool modal READ isModal WRITE setModal ) + +public: + QDesignerWizard( QWidget *parent, const char *name ) + : QWizard( parent, name ), modal(FALSE) {} + + int currentPageNum() const; + void setCurrentPage( int i ); + QString pageTitle() const; + void setPageTitle( const QString& title ); + QCString pageName() const; + void setPageName( const QCString& name ); + int pageNum( QWidget *page ); + void addPage( QWidget *p, const QString & ); + void removePage( QWidget *p ); + void insertPage( QWidget *p, const QString &t, int index ); + bool isPageRemoved( QWidget *p ) { return (removedPages.find( p ) != 0); } + + bool isModal() const { return modal; } + void setModal(bool b) { modal = b; } + + void reject() {} + +private: + struct Page + { + Page( QWidget *a, const QString &b ) : p( a ), t( b ) {} + Page() : p( 0 ), t( QString::null ) {} + QWidget *p; + QString t; + }; + QPtrDict removedPages; + bool modal; + +}; + +class QLayoutWidget : public QWidget +{ + Q_OBJECT + +public: + QLayoutWidget( QWidget *parent, const char *name ) : QWidget( parent, name ), sp( QWidget::sizePolicy() ) {} + + QSizePolicy sizePolicy() const; + void updateSizePolicy(); + +protected: + void paintEvent( QPaintEvent * ); + bool event( QEvent * ); + QSizePolicy sp; + +}; + + +class CustomWidget : public QWidget +{ + Q_OBJECT + +public: + CustomWidget( QWidget *parent, const char *name, MetaDataBase::CustomWidget *cw ) + : QWidget( parent, name ), cusw( cw ) { + alwaysExpand = parentWidget() && parentWidget()->inherits( "FormWindow" ); + setSizePolicy( cw->sizePolicy ); + if ( !alwaysExpand ) + setBackgroundMode( PaletteDark ); + } + + QSize sizeHint() const { + QSize sh = cusw->sizeHint; + if ( sh.isValid() ) + return sh; + return QWidget::sizeHint(); + } + + QString realClassName() { return cusw->className; } + MetaDataBase::CustomWidget *customWidget() const { return cusw; } + +protected: + void paintEvent( QPaintEvent *e ); + + MetaDataBase::CustomWidget *cusw; + bool alwaysExpand; + +}; + + +class Line : public QFrame +{ + Q_OBJECT + + Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation ) + Q_OVERRIDE( int frameWidth DESIGNABLE false ) + Q_OVERRIDE( Shape frameShape DESIGNABLE false ) + Q_OVERRIDE( QRect frameRect DESIGNABLE false ) + Q_OVERRIDE( QRect contentsRect DESIGNABLE false ) +public: + Line( QWidget *parent, const char *name ) + : QFrame( parent, name, WMouseNoMask ) { + setFrameStyle( HLine | Sunken ); + } + + void setOrientation( Orientation orient ) { + if ( orient == Horizontal ) + setFrameShape( HLine ); + else + setFrameShape( VLine ); + } + Orientation orientation() const { + return frameShape() == HLine ? Horizontal : Vertical; + } +}; + +class QDesignerLabel : public QLabel +{ + Q_OBJECT + + Q_PROPERTY( QCString buddy READ buddyWidget WRITE setBuddyWidget ) + +public: + QDesignerLabel( QWidget *parent = 0, const char *name = 0 ) + : QLabel( parent, name ) { myBuddy = 0; } + + void setBuddyWidget( const QCString &b ) { + myBuddy = b; + updateBuddy(); + } + QCString buddyWidget() const { + return myBuddy; + }; + +protected: + void showEvent( QShowEvent *e ) { + QLabel::showEvent( e ); + updateBuddy(); + } + + +private: + void updateBuddy(); + + QCString myBuddy; + +}; + +class QDesignerWidget : public QWidget +{ + Q_OBJECT + +public: + QDesignerWidget( FormWindow *fw, QWidget *parent, const char *name ) + : QWidget( parent, name, WResizeNoErase ), formwindow( fw ) { + need_frame = parent && parent->inherits("QDesignerWidgetStack" ); + } + +protected: + void resizeEvent( QResizeEvent* e); + void paintEvent( QPaintEvent *e ); + +private: + FormWindow *formwindow; + uint need_frame : 1; + +}; + +class QDesignerDialog : public QDialog +{ + Q_OBJECT + Q_OVERRIDE( bool modal READ isModal WRITE setModal ) + +public: + QDesignerDialog( FormWindow *fw, QWidget *parent, const char *name ) + : QDialog( parent, name, FALSE, WResizeNoErase ), formwindow( fw ), modal(FALSE) {} + + bool isModal() const { return modal; } + void setModal(bool b) { modal = b; } + +protected: + void paintEvent( QPaintEvent *e ); + +private: + FormWindow *formwindow; + bool modal; + +}; + +class QDesignerToolButton : public QToolButton +{ + Q_OBJECT + Q_PROPERTY( int buttonGroupId READ buttonGroupId WRITE setButtonGroupId ) + +public: + QDesignerToolButton( QWidget *parent, const char *name ) + : QToolButton( parent, name ) {} + + bool isInButtonGroup() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ); + } + int buttonGroupId() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ? ( (QButtonGroup*)parentWidget() )->id( (QButton*)this ) : -1; + } + void setButtonGroupId( int id ) { + if ( parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ) { + ( (QButtonGroup*)parentWidget() )->remove( this ); + ( (QButtonGroup*)parentWidget() )->insert( this, id ); + } + } +}; + +class QDesignerRadioButton : public QRadioButton +{ + Q_OBJECT + Q_PROPERTY( int buttonGroupId READ buttonGroupId WRITE setButtonGroupId ) + +public: + QDesignerRadioButton( QWidget *parent, const char *name ) + : QRadioButton( parent, name ) {} + + bool isInButtonGroup() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ); + } + int buttonGroupId() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ? ( (QButtonGroup*)parentWidget() )->id( (QButton*)this ) : -1; + } + void setButtonGroupId( int id ) { + if ( parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ) { + ( (QButtonGroup*)parentWidget() )->remove( this ); + ( (QButtonGroup*)parentWidget() )->insert( this, id ); + } + } + + void setFocusPolicy( FocusPolicy policy ); +}; + +class QDesignerPushButton : public QPushButton +{ + Q_OBJECT + Q_PROPERTY( int buttonGroupId READ buttonGroupId WRITE setButtonGroupId ) + +public: + QDesignerPushButton( QWidget *parent, const char *name ) + : QPushButton( parent, name ) {} + + bool isInButtonGroup() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ); + } + int buttonGroupId() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ? ( (QButtonGroup*)parentWidget() )->id( (QButton*)this ) : -1; + } + void setButtonGroupId( int id ) { + if ( parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ) { + ( (QButtonGroup*)parentWidget() )->remove( this ); + ( (QButtonGroup*)parentWidget() )->insert( this, id ); + } + } + +}; + +class QDesignerCheckBox : public QCheckBox +{ + Q_OBJECT + Q_PROPERTY( int buttonGroupId READ buttonGroupId WRITE setButtonGroupId ) + +public: + QDesignerCheckBox( QWidget *parent, const char *name ) + : QCheckBox( parent, name ) {} + + bool isInButtonGroup() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ); + } + int buttonGroupId() const { + return parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ? ( (QButtonGroup*)parentWidget() )->id( (QButton*)this ) : -1; + } + void setButtonGroupId( int id ) { + if ( parentWidget() && parentWidget()->inherits( "QButtonGroup" ) ) { + ( (QButtonGroup*)parentWidget() )->remove( this ); + ( (QButtonGroup*)parentWidget() )->insert( this, id ); + } + } + +}; + +class QDesignerToolBox : public QToolBox +{ + Q_OBJECT + Q_PROPERTY( QString itemLabel READ itemLabel WRITE setItemLabel STORED false DESIGNABLE true ) + Q_PROPERTY( QCString itemName READ itemName WRITE setItemName STORED false DESIGNABLE true ) + Q_PROPERTY( BackgroundMode itemBackgroundMode READ itemBackgroundMode WRITE setItemBackgroundMode STORED false DESIGNABLE true ) + +public: + QDesignerToolBox( QWidget *parent, const char *name ); + + QString itemLabel() const; + void setItemLabel( const QString &l ); + QCString itemName() const; + void setItemName( const QCString &n ); + BackgroundMode itemBackgroundMode() const; + void setItemBackgroundMode( BackgroundMode ); + +protected: + void itemInserted( int index ); +}; + +#endif diff --git a/tools/designer/designer/wizardeditor.ui b/tools/designer/designer/wizardeditor.ui new file mode 100644 index 0000000..7fbd6bf --- /dev/null +++ b/tools/designer/designer/wizardeditor.ui @@ -0,0 +1,345 @@ + +WizardEditorBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + WizardEditorBase + + + + 0 + 0 + 396 + 233 + + + + Wizard Page Editor + + + + unnamed + + + 11 + + + 6 + + + + Layout19 + + + + unnamed + + + 0 + + + 6 + + + + Layout14 + + + + unnamed + + + 0 + + + 2 + + + + pagesLabel + + + Wizard Pages: + + + + + listBox + + + + + + + Layout18 + + + + unnamed + + + 0 + + + 6 + + + + buttonAdd + + + A&dd + + + + + buttonRemove + + + &Remove + + + + + Spacer11 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonUp + + + + + + designer_s_up.png + + + + + buttonDown + + + + + + designer_s_down.png + + + + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonApply + + + &Apply + + + true + + + Apply all changes. + + + + + buttonOk + + + &OK + + + true + + + true + + + Close the dialog and apply all the changes. + + + + + buttonCancel + + + &Cancel + + + true + + + Close the dialog and discard any changes. + + + + + + + + + buttonHelp + clicked() + WizardEditorBase + helpClicked() + + + buttonApply + clicked() + WizardEditorBase + applyClicked() + + + buttonUp + clicked() + WizardEditorBase + upClicked() + + + buttonDown + clicked() + WizardEditorBase + downClicked() + + + buttonAdd + clicked() + WizardEditorBase + addClicked() + + + buttonRemove + clicked() + WizardEditorBase + removeClicked() + + + listBox + selected(int) + WizardEditorBase + itemSelected(int) + + + listBox + highlighted(int) + WizardEditorBase + itemHighlighted(int) + + + buttonOk + clicked() + WizardEditorBase + okClicked() + + + buttonCancel + clicked() + WizardEditorBase + cancelClicked() + + + + init() + destroy() + addClicked() + applyClicked() + cancelClicked() + downClicked() + helpClicked() + itemHighlighted(int) + itemSelected(int) + okClicked() + removeClicked() + upClicked() + + + + diff --git a/tools/designer/designer/wizardeditorimpl.cpp b/tools/designer/designer/wizardeditorimpl.cpp new file mode 100644 index 0000000..8754953 --- /dev/null +++ b/tools/designer/designer/wizardeditorimpl.cpp @@ -0,0 +1,258 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "wizardeditorimpl.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "command.h" +#include "listboxdnd.h" +#include "listboxrename.h" + +#include +#include +#include +#include + +WizardEditor::WizardEditor( QWidget *parent, QWizard *w, FormWindow *fw ) + : WizardEditorBase( parent, 0 ), formwindow( fw ), wizard( w ), draggedItem( 0 ) +{ + connect( buttonHelp, SIGNAL( clicked() ), MainWindow::self, SLOT( showDialogHelp() ) ); + fillListBox(); + + // Add drag and drop + ListBoxDnd *listBoxDnd = new ListBoxDnd( listBox ); + listBoxDnd->setDragMode( ListBoxDnd::Internal | ListBoxDnd::Move ); + QObject::connect( listBoxDnd, SIGNAL( dropped( QListBoxItem * ) ), + listBoxDnd, SLOT( confirmDrop( QListBoxItem * ) ) ); + + QObject::connect( listBoxDnd, SIGNAL( dragged( QListBoxItem * ) ), + this, SLOT( itemDragged( QListBoxItem * ) ) ); + QObject::connect( listBoxDnd, SIGNAL( dropped( QListBoxItem * ) ), + this, SLOT( itemDropped( QListBoxItem * ) ) ); + + // Add in-place rename + new ListBoxRename( listBox ); +} + +WizardEditor::~WizardEditor() +{ + commands.setAutoDelete( TRUE ); +} + +void WizardEditor::okClicked() +{ + applyClicked(); + accept(); +} + +void WizardEditor::cancelClicked() +{ + reject(); +} + +void WizardEditor::applyClicked() +{ + if ( commands.isEmpty() ) return; + + // schedule macro command + MacroCommand* cmd = new MacroCommand( tr( "Edit Wizard Pages" ), formwindow, commands ); + formwindow->commandHistory()->addCommand( cmd ); + cmd->execute(); + + // clear command list + commands.clear(); + + // fix wizard buttons + for ( int i = 0; i < wizard->pageCount(); i++ ) { + + QWidget * page = wizard->page( i ); + if ( i == 0 ) { // first page + + wizard->setBackEnabled( page, FALSE ); + wizard->setNextEnabled( page, TRUE ); + } + else if ( i == wizard->pageCount() - 1 ) { // last page + + wizard->setBackEnabled( page, TRUE ); + wizard->setNextEnabled( page, FALSE ); + } + else { + + wizard->setBackEnabled( page, TRUE ); + wizard->setNextEnabled( page, TRUE ); + } + wizard->setFinishEnabled( page, FALSE ); + } + + // update listbox + int index = listBox->currentItem(); + fillListBox(); + listBox->setCurrentItem( index ); + + // show current page + wizard->showPage( wizard->page( 0 ) ); +} + +void WizardEditor::helpClicked() +{ + +} + +void WizardEditor::addClicked() +{ + int index = listBox->currentItem() + 1; + // update listbox + listBox->insertItem( "Page", index ); + + // schedule add command + AddWizardPageCommand *cmd = new AddWizardPageCommand( tr( "Add Page to %1" ).arg( wizard->name() ), + formwindow, wizard, "Page", index, FALSE); + commands.append( cmd ); + + // update buttons + updateButtons(); +} + +void WizardEditor::removeClicked() +{ + if ( listBox->count() < 2 ) return; + + int index = listBox->currentItem(); + + // update listbox + listBox->removeItem( index ); + + // schedule remove command + DeleteWizardPageCommand *cmd = new DeleteWizardPageCommand( tr( "Delete Page %1 of %2" ) + .arg( listBox->text( index ) ).arg( wizard->name() ), + formwindow, wizard, index, FALSE ); + commands.append( cmd ); + + // update buttons + updateButtons(); +} + +void WizardEditor::upClicked() +{ + int index1 = listBox->currentItem(); + int index2 = index1 - 1; + + // swap listbox items + QString item1 = listBox->text( index1 ); + listBox->removeItem( index1 ); + listBox->insertItem( item1, index2 ); + listBox->setCurrentItem( index2 ); + + // schedule swap command + SwapWizardPagesCommand *cmd = new SwapWizardPagesCommand( tr( "Swap pages %1 and %2 of %1" ).arg( index1 ).arg( index2 ) + .arg( wizard->name() ), formwindow, wizard, index1, index2); + commands.append( cmd ); + + // update buttons + updateButtons(); +} + +void WizardEditor::downClicked() +{ + int index1 = listBox->currentItem(); + int index2 = index1 + 1; + + // swap listbox items + QString item1 = listBox->text( index1 ); + listBox->removeItem( index1 ); + listBox->insertItem( item1, index2 ); + listBox->setCurrentItem( index2 ); + + // schedule swap command + SwapWizardPagesCommand *cmd = new SwapWizardPagesCommand( tr( "Swap pages %1 and %2 of %1" ).arg( index1 ).arg( index2 ).arg( wizard->name() ), formwindow, wizard, index2, index1); + commands.append( cmd ); + + // update buttons + updateButtons(); +} + +void WizardEditor::fillListBox() +{ + listBox->clear(); + + if ( !wizard ) return; + for ( int i = 0; i < wizard->pageCount(); i++ ) + listBox->insertItem( wizard->title( wizard->page( i ) ) ); + + updateButtons(); +} + +void WizardEditor::itemHighlighted( int ) +{ + updateButtons(); +} + +void WizardEditor::itemSelected( int index ) +{ + if ( index < 0 ) return; + // Called when Qt::Key_Enter was pressed. + // ListBoxRename has renamed the list item, so we only need to rename the page to the same name. + QString pn( tr( "Rename page %1 of %2" ).arg( wizard->title( wizard->page( index ) ) ).arg( wizard->name() ) ); + RenameWizardPageCommand *cmd = new RenameWizardPageCommand( pn, formwindow, wizard, index, listBox->text( index ) ); + commands.append( cmd ); +} + +void WizardEditor::updateButtons() +{ + int index = listBox->currentItem(); + + buttonUp->setEnabled( index > 0 ); + buttonDown->setEnabled( index < (int)listBox->count() - 1 ); + buttonRemove->setEnabled( index >= 0 ); + + if ( listBox->count() < 2 ) + buttonRemove->setEnabled( FALSE ); +} + +void WizardEditor::itemDragged( QListBoxItem * i ) +{ + // Store item index + draggedItem = listBox->index( i ); +} + +void WizardEditor::itemDropped( QListBoxItem * i ) +{ + if ( draggedItem < 0 ) return; + // The reorder the pages acording to the listBox list of items + // Assumes that only one item has been moved. + int droppedItem = listBox->index( i ); + + //qDebug( "Moving page %d -> %d", draggedItem, droppedItem ); + MoveWizardPageCommand *cmd = new MoveWizardPageCommand( tr( "Move page %1 to %2 in %3" ).arg( draggedItem ).arg( droppedItem ).arg( wizard->name() ), formwindow, wizard, draggedItem, droppedItem ); + commands.append( cmd ); +} diff --git a/tools/designer/designer/wizardeditorimpl.h b/tools/designer/designer/wizardeditorimpl.h new file mode 100644 index 0000000..e1207b4 --- /dev/null +++ b/tools/designer/designer/wizardeditorimpl.h @@ -0,0 +1,81 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef WIZARDEDITORIMPL_H +#define WIZARDEDITORIMPL_H + +class QWizard; +class FormWindow; + +#include + +#include "wizardeditor.h" +#include "command.h" + +class WizardEditor : public WizardEditorBase +{ + Q_OBJECT + +public: + WizardEditor( QWidget *parent, QWizard *wizard, FormWindow *fw ); + ~WizardEditor(); + +protected slots: + void okClicked(); + void applyClicked(); + void cancelClicked(); + void helpClicked(); + + void addClicked(); + void removeClicked(); + void upClicked(); + void downClicked(); + + void itemHighlighted( int ); + void itemSelected( int ); + + void itemDragged( QListBoxItem * ); + void itemDropped( QListBoxItem * ); + +private: + void updateButtons(); + void fillListBox(); + +private: + FormWindow *formwindow; + QWizard *wizard; + QPtrList commands; + int draggedItem; +}; + +#endif diff --git a/tools/designer/designer/workspace.cpp b/tools/designer/designer/workspace.cpp new file mode 100644 index 0000000..41ee23e --- /dev/null +++ b/tools/designer/designer/workspace.cpp @@ -0,0 +1,713 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include // HP-UX compiler needs this here +#include "workspace.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "globaldefs.h" +#include "command.h" +#include "project.h" +#include "pixmapcollection.h" +#include "sourcefile.h" +#include "sourceeditor.h" +#include "propertyeditor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qcompletionedit.h" + +WorkspaceItem::WorkspaceItem( QListView *parent, Project* p ) + : QListViewItem( parent ) +{ + init(); + project = p; + t = ProjectType; + setPixmap( 0, QPixmap::fromMimeSource( "designer_folder.png" ) ); + setExpandable( FALSE ); +} + +WorkspaceItem::WorkspaceItem( QListViewItem *parent, SourceFile* sf ) + : QListViewItem( parent ) +{ + init(); + sourceFile = sf; + t = SourceFileType; + setPixmap( 0, QPixmap::fromMimeSource( "designer_filenew.png" ) ); +} + +WorkspaceItem::WorkspaceItem( QListViewItem *parent, QObject *o, Project *p ) + : QListViewItem( parent ) +{ + init(); + object = o; + project = p; + t = ObjectType; + setPixmap( 0, QPixmap::fromMimeSource( "designer_object.png" ) ); + QObject::connect( p->fakeFormFileFor( o ), SIGNAL( somethingChanged(FormFile*) ), + listView(), SLOT( update() ) ); +} + +WorkspaceItem::WorkspaceItem( QListViewItem *parent, FormFile* ff, Type type ) + : QListViewItem( parent ) +{ + init(); + formFile = ff; + t = type; + if ( type == FormFileType ) { + setPixmap( 0, QPixmap::fromMimeSource( "designer_form.png" ) ); + QObject::connect( ff, SIGNAL( somethingChanged(FormFile*) ), listView(), SLOT( update(FormFile*) ) ); + if ( formFile->supportsCodeFile() ) { + (void) new WorkspaceItem( this, formFile, FormSourceType ); + } + } else if ( type == FormSourceType ) { + setPixmap( 0, QPixmap::fromMimeSource( "designer_filenew.png" ) ); + } +} + + +void WorkspaceItem::init() +{ + autoOpen = FALSE; + useOddColor = FALSE; + project = 0; + sourceFile = 0; + formFile = 0; +} + +void WorkspaceItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ) +{ + QColorGroup g( cg ); + g.setColor( QColorGroup::Base, backgroundColor() ); + g.setColor( QColorGroup::Foreground, Qt::black ); + + if ( type() == FormSourceType && + ( !formFile->hasFormCode() || ( formFile->codeFileState() == FormFile::Deleted && formFile->formWindow() ) ) && + parent() && parent()->parent() && ( (WorkspaceItem*)parent()->parent() )->project && + ( (WorkspaceItem*)parent()->parent() )->project->isCpp() ) { + g.setColor( QColorGroup::Text, listView()->palette().disabled().color( QColorGroup::Text) ); + g.setColor( QColorGroup::HighlightedText, listView()->palette().disabled().color( QColorGroup::Text) ); + } else { + g.setColor( QColorGroup::Text, Qt::black ); + } + p->save(); + + if ( isModified() ) { + QFont f = p->font(); + f.setBold( TRUE ); + p->setFont( f ); + } + + QListViewItem::paintCell( p, g, column, width, align ); + p->setPen( QPen( cg.dark(), 1 ) ); + if ( column == 0 ) + p->drawLine( 0, 0, 0, height() - 1 ); + if ( listView()->firstChild() != this ) { + if ( nextSibling() != itemBelow() && itemBelow()->depth() < depth() ) { + int d = depth() - itemBelow()->depth(); + p->drawLine( -listView()->treeStepSize() * d, height() - 1, 0, height() - 1 ); + } + } + p->drawLine( 0, height() - 1, width, height() - 1 ); + p->drawLine( width - 1, 0, width - 1, height() ); + p->restore(); +} + +QString WorkspaceItem::text( int column ) const +{ + if ( column != 0 ) + return QListViewItem::text( column ); + switch( t ) { + case ProjectType: + if ( project->isDummy() ) { + return Project::tr("" ); + } else if ( MainWindow::self->singleProjectMode() ) { + return QFileInfo( project->fileName() ).baseName(); + } + return project->makeRelative( project->fileName() ); + case FormFileType: + if ( !MainWindow::self->singleProjectMode() ) + return formFile->formName() + ": " + formFile->fileName(); + return formFile->formName(); + case FormSourceType: + if ( !MainWindow::self->singleProjectMode() ) + return formFile->codeFile(); + return formFile->formName() + " [Source]"; + case SourceFileType: + return sourceFile->fileName(); + case ObjectType: + if ( !project->hasParentObject( object ) ) + return object->name(); + return project->qualifiedName( object ); + } + + return QString::null; // shut up compiler +} + +void WorkspaceItem::fillCompletionList( QStringList& completion ) +{ + switch( t ) { + case ProjectType: + break; + case FormFileType: + completion += formFile->formName(); + completion += formFile->fileName(); + break; + case FormSourceType: + completion += formFile->codeFile(); + break; + case SourceFileType: + completion += sourceFile->fileName(); + break; + case ObjectType: + completion += object->name(); + } +} + +bool WorkspaceItem::checkCompletion( const QString& completion ) +{ + switch( t ) { + case ProjectType: + break; + case FormFileType: + return completion == formFile->formName() + || completion == formFile->fileName(); + case FormSourceType: + return completion == formFile->codeFile(); + case SourceFileType: + return completion == sourceFile->fileName(); + case ObjectType: + return completion == object->name(); + } + return FALSE; +} + + +bool WorkspaceItem::isModified() const +{ + switch( t ) { + case ProjectType: + return project->isModified(); + case FormFileType: + return formFile->isModified( FormFile::WFormWindow ); + case FormSourceType: + return formFile->isModified( FormFile::WFormCode ); + case SourceFileType: + return sourceFile->isModified(); + case ObjectType: + return project->fakeFormFileFor( object )->isModified(); + break; + } + return FALSE; // shut up compiler +} + +QString WorkspaceItem::key( int column, bool ) const +{ + QString key = text( column ); + if ( t == FormFileType ) + key.prepend( "0" ); + else if ( t == ObjectType ) + key.prepend( "a" ); + else + key.prepend( "A" ); + return key; +} + +QColor WorkspaceItem::backgroundColor() +{ + bool b = useOddColor; + if ( t == FormSourceType && parent() ) + b = ( ( WorkspaceItem*)parent() )->useOddColor; + return b ? *backColor2 : *backColor1; +} + + +void WorkspaceItem::setOpen( bool b ) +{ + QListViewItem::setOpen( b ); + autoOpen = FALSE; +} + +void WorkspaceItem::setAutoOpen( bool b ) +{ + QListViewItem::setOpen( b ); + autoOpen = b; +} + +Workspace::Workspace( QWidget *parent, MainWindow *mw ) + : QListView( parent, 0, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | + WStyle_Tool | WStyle_MinMax | WStyle_SysMenu ), mainWindow( mw ), + project( 0 ), completionDirty( FALSE ) +{ + init_colors(); + + setDefaultRenameAction( Accept ); + blockNewForms = FALSE; + bufferEdit = 0; + header()->setStretchEnabled( TRUE ); + header()->hide(); + setSorting( 0 ); + setResizePolicy( QScrollView::Manual ); +#ifndef Q_WS_MAC + QPalette p( palette() ); + p.setColor( QColorGroup::Base, QColor( *backColor2 ) ); + (void)*selectedBack; // hack + setPalette( p ); +#endif + addColumn( tr( "Files" ) ); + setAllColumnsShowFocus( TRUE ); + connect( this, SIGNAL( mouseButtonClicked( int, QListViewItem *, const QPoint &, int ) ), + this, SLOT( itemClicked( int, QListViewItem *, const QPoint& ) ) ), + connect( this, SIGNAL( doubleClicked( QListViewItem * ) ), + this, SLOT( itemDoubleClicked( QListViewItem * ) ) ), + connect( this, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint &, int ) ), + this, SLOT( rmbClicked( QListViewItem *, const QPoint& ) ) ), + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOn ); + viewport()->setAcceptDrops( TRUE ); + setAcceptDrops( TRUE ); + setColumnWidthMode( 1, Manual ); +} + + +void Workspace::projectDestroyed( QObject* o ) +{ + if ( o == project ) { + project = 0; + clear(); + } +} + +void Workspace::setCurrentProject( Project *pro ) +{ + if ( project == pro ) + return; + if ( project ) { + disconnect( project, SIGNAL( sourceFileAdded(SourceFile*) ), this, SLOT( sourceFileAdded(SourceFile*) ) ); + disconnect( project, SIGNAL( sourceFileRemoved(SourceFile*) ), this, SLOT( sourceFileRemoved(SourceFile*) ) ); + disconnect( project, SIGNAL( formFileAdded(FormFile*) ), this, SLOT( formFileAdded(FormFile*) ) ); + disconnect( project, SIGNAL( formFileRemoved(FormFile*) ), this, SLOT( formFileRemoved(FormFile*) ) ); + disconnect( project, SIGNAL( objectAdded(QObject*) ), this, SLOT( objectAdded(QObject*) ) ); + disconnect( project, SIGNAL( objectRemoved(QObject*) ), this, SLOT( objectRemoved(QObject*) ) ); + disconnect( project, SIGNAL( projectModified() ), this, SLOT( update() ) ); + } + project = pro; + connect( project, SIGNAL( sourceFileAdded(SourceFile*) ), this, SLOT( sourceFileAdded(SourceFile*) ) ); + connect( project, SIGNAL( sourceFileRemoved(SourceFile*) ), this, SLOT( sourceFileRemoved(SourceFile*) ) ); + connect( project, SIGNAL( formFileAdded(FormFile*) ), this, SLOT( formFileAdded(FormFile*) ) ); + connect( project, SIGNAL( formFileRemoved(FormFile*) ), this, SLOT( formFileRemoved(FormFile*) ) ); + connect( project, SIGNAL( destroyed(QObject*) ), this, SLOT( projectDestroyed(QObject*) ) ); + connect( project, SIGNAL( objectAdded(QObject*) ), this, SLOT( objectAdded(QObject*) ) ); + connect( project, SIGNAL( objectRemoved(QObject*) ), this, SLOT( objectRemoved(QObject*) ) ); + connect( project, SIGNAL( projectModified() ), this, SLOT( update() ) ); + clear(); + + if ( bufferEdit ) + bufferEdit->clear(); + + projectItem = new WorkspaceItem( this, project ); + + projectItem->setOpen( TRUE ); + + for ( QPtrListIterator sources = project->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + (void) new WorkspaceItem( projectItem, f ); + } + + for ( QPtrListIterator forms = project->formFiles(); + forms.current(); ++forms ) { + FormFile* f = forms.current(); + if ( f->isFake() ) + continue; + + (void) new WorkspaceItem( projectItem, f ); + } + + QObjectList l = project->objects(); + QObjectListIt objs( l ); + for ( ;objs.current(); ++objs ) { + QObject* o = objs.current(); + (void) new WorkspaceItem( projectItem, o, project ); + } + + updateColors(); + completionDirty = TRUE; +} + +void Workspace::sourceFileAdded( SourceFile* sf ) +{ + (void) new WorkspaceItem( projectItem, sf ); + updateColors(); +} + +void Workspace::sourceFileRemoved( SourceFile* sf ) +{ + delete findItem( sf ); + updateColors(); +} + +void Workspace::formFileAdded( FormFile* ff ) +{ + if ( ff->isFake() ) + return; + (void) new WorkspaceItem( projectItem, ff ); + updateColors(); +} + +void Workspace::formFileRemoved( FormFile* ff ) +{ + delete findItem( ff ); + updateColors(); +} + +void Workspace::objectAdded( QObject *o ) +{ + (void) new WorkspaceItem( projectItem, o, project ); + updateColors(); +} + +void Workspace::objectRemoved( QObject *o ) +{ + delete findItem( o ); + updateColors(); +} + +void Workspace::update() +{ + completionDirty = TRUE; + triggerUpdate(); +} + +void Workspace::update( FormFile* ff ) +{ + QListViewItem* i = findItem( ff ); + if ( i ) { + i->repaint(); + if ( (i = i->firstChild()) ) + i->repaint(); + } +} + + +void Workspace::activeFormChanged( FormWindow *fw ) +{ + WorkspaceItem *i = findItem( fw->formFile() ); + if ( i ) { + setCurrentItem( i ); + setSelected( i, TRUE ); + if ( !i->isOpen() ) + i->setAutoOpen( TRUE ); + } + + closeAutoOpenItems(); + +} + +void Workspace::activeEditorChanged( SourceEditor *se ) +{ + if ( !se->object() ) + return; + + if ( se->formWindow() ) { + WorkspaceItem *i = findItem( se->formWindow()->formFile() ); + if ( i && i->firstChild() ) { + if ( !i->isOpen() ) + i->setAutoOpen( TRUE ); + setCurrentItem( i->firstChild() ); + setSelected( i->firstChild(), TRUE ); + } + } else { + WorkspaceItem *i = findItem( se->sourceFile() ); + if ( i ) { + setCurrentItem( i ); + setSelected( i, TRUE ); + } + } + + closeAutoOpenItems(); +} + +WorkspaceItem *Workspace::findItem( FormFile* ff) +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->formFile == ff ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +WorkspaceItem *Workspace::findItem( SourceFile *sf ) +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->sourceFile == sf ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +WorkspaceItem *Workspace::findItem( QObject *o ) +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->object == o ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +void Workspace::closeAutoOpenItems() +{ + QListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + WorkspaceItem* i = (WorkspaceItem*) it.current(); + WorkspaceItem* ip = (WorkspaceItem*) i->parent(); + if ( i->type() == WorkspaceItem::FormSourceType ) { + if ( !i->isSelected() && !ip->isSelected() + && ip->isAutoOpen() ) { + ip->setAutoOpen( FALSE ); + } + } + } +} + + +void Workspace::closeEvent( QCloseEvent *e ) +{ + e->accept(); +} + +void Workspace::itemDoubleClicked( QListViewItem *i ) +{ + if ( ( (WorkspaceItem*)i)->type()== WorkspaceItem::ProjectType ) + i->setOpen( TRUE ); +} + +void Workspace::itemClicked( int button, QListViewItem *i, const QPoint& ) +{ + if ( !i || button != LeftButton ) + return; + + closeAutoOpenItems(); + + WorkspaceItem* wi = (WorkspaceItem*)i; + switch( wi->type() ) { + case WorkspaceItem::ProjectType: + break; // ### TODO + case WorkspaceItem::FormFileType: + wi->formFile->showFormWindow(); + break; + case WorkspaceItem::FormSourceType: + wi->formFile->showEditor( FALSE ); + break; + case WorkspaceItem::SourceFileType: + mainWindow->editSource( wi->sourceFile ); + break; + case WorkspaceItem::ObjectType: + project->fakeFormFileFor( wi->object )->formWindow()->setFocus(); + mainWindow->propertyeditor()->setWidget( wi->object, + project->fakeFormFileFor( wi->object )->formWindow() ); + mainWindow->objectHierarchy()-> + setFormWindow( project->fakeFormFileFor( wi->object )->formWindow(), wi->object ); + project->fakeFormFileFor( wi->object )->showEditor(); + break; + } +} + +void Workspace::contentsDropEvent( QDropEvent *e ) +{ + if ( !QUriDrag::canDecode( e ) ) { + e->ignore(); + } else { + QStringList files; + QUriDrag::decodeLocalFiles( e, files ); + if ( !files.isEmpty() ) { + for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it ) { + QString fn = *it; + mainWindow->fileOpen( "", "", fn ); + } + } + } +} + +void Workspace::contentsDragEnterEvent( QDragEnterEvent *e ) +{ + if ( !QUriDrag::canDecode( e ) ) + e->ignore(); + else + e->accept(); +} + +void Workspace::contentsDragMoveEvent( QDragMoveEvent *e ) +{ + if ( !QUriDrag::canDecode( e ) ) + e->ignore(); + else + e->accept(); +} + +void Workspace::rmbClicked( QListViewItem *i, const QPoint& pos ) +{ + if ( !i ) + return; + WorkspaceItem* wi = (WorkspaceItem*)i; + enum { OPEN_SOURCE, REMOVE_SOURCE, OPEN_FORM, REMOVE_FORM, + OPEN_FORM_SOURCE, REMOVE_FORM_SOURCE, OPEN_OBJECT_SOURCE }; + QPopupMenu menu( this ); + menu.setCheckable( TRUE ); + switch ( wi->type() ) { + case WorkspaceItem::SourceFileType: + menu.insertItem( tr( "&Open source file" ), OPEN_SOURCE ); + menu.insertSeparator(); + menu.insertItem( QPixmap::fromMimeSource( "designer_editcut.png" ), + tr( "&Remove source file from project" ), REMOVE_SOURCE ); + break; + case WorkspaceItem::FormFileType: + menu.insertItem( tr( "&Open form" ), OPEN_FORM ); + menu.insertSeparator(); + menu.insertItem( QPixmap::fromMimeSource( "designer_editcut.png" ), + tr( "&Remove form from project" ), REMOVE_FORM ); + break; + case WorkspaceItem::FormSourceType: + menu.insertItem( tr( "&Open form source" ), OPEN_FORM_SOURCE ); + menu.insertSeparator(); + if ( project->isCpp() ) + menu.insertItem( QPixmap::fromMimeSource( "designer_editcut.png" ), + tr( "&Remove source file from form" ), REMOVE_FORM_SOURCE ); + else + menu.insertItem( QPixmap::fromMimeSource( "designer_editcut.png" ), + tr( "&Remove form from project" ), REMOVE_FORM ); + break; + case WorkspaceItem::ProjectType: + MainWindow::self->popupProjectMenu( pos ); + return; + case WorkspaceItem::ObjectType: + menu.insertItem( tr( "&Open source" ), OPEN_OBJECT_SOURCE ); + break; + } + + switch ( menu.exec( pos ) ) { + case REMOVE_SOURCE: + project->removeSourceFile( wi->sourceFile ); + break; + case REMOVE_FORM: + project->removeFormFile( wi->formFile ); + break; + case REMOVE_FORM_SOURCE: + ( (WorkspaceItem*)i )->formFile->setModified( TRUE ); + ( (WorkspaceItem*)i )->formFile->setCodeFileState( FormFile::Deleted ); + delete ( (WorkspaceItem*)i )->formFile->editor(); + break; + case OPEN_OBJECT_SOURCE: + case OPEN_SOURCE: + case OPEN_FORM: + case OPEN_FORM_SOURCE: + itemClicked( LeftButton, i, pos ); + break; + } +} + +bool Workspace::eventFilter( QObject *o, QEvent * e ) +{ + // Reggie, on what type of events do we have to execute updateBufferEdit() + if ( o ==bufferEdit && e->type() != QEvent::ChildRemoved ) + updateBufferEdit(); + return QListView::eventFilter( o, e ); +} + +void Workspace::setBufferEdit( QCompletionEdit *edit ) +{ + bufferEdit = edit; + connect( bufferEdit, SIGNAL( chosen( const QString & ) ), + this, SLOT( bufferChosen( const QString & ) ) ); + bufferEdit->installEventFilter( this ); +} + +void Workspace::updateBufferEdit() +{ + if ( !bufferEdit || !completionDirty || !MainWindow::self) + return; + completionDirty = FALSE; + QStringList completion = MainWindow::self->projectFileNames(); + QListViewItemIterator it( this ); + while ( it.current() ) { + ( (WorkspaceItem*)it.current())->fillCompletionList( completion ); + ++it; + } + completion.sort(); + bufferEdit->setCompletionList( completion ); +} + +void Workspace::bufferChosen( const QString &buffer ) +{ + if ( bufferEdit ) + bufferEdit->setText( "" ); + + if ( MainWindow::self->projectFileNames().contains( buffer ) ) { + MainWindow::self->setCurrentProjectByFilename( buffer ); + return; + } + + QListViewItemIterator it( this ); + while ( it.current() ) { + if ( ( (WorkspaceItem*)it.current())->checkCompletion( buffer ) ) { + itemClicked( LeftButton, it.current(), QPoint() ); + break; + } + ++it; + } +} + +void Workspace::updateColors() +{ + QListViewItem* i = firstChild(); + if ( i ) + i = i->firstChild(); + bool b = TRUE; + while ( i ) { + WorkspaceItem* wi = ( WorkspaceItem*) i; + i = i->nextSibling(); + wi->useOddColor = b; + b = !b; + } +} diff --git a/tools/designer/designer/workspace.h b/tools/designer/designer/workspace.h new file mode 100644 index 0000000..46a0bac --- /dev/null +++ b/tools/designer/designer/workspace.h @@ -0,0 +1,158 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef WORKSPACE_H +#define WORKSPACE_H + +#include + +class FormWindow; +class QResizeEvent; +class QCloseEvent; +class QDropEvent; +class QDragMoveEvent; +class QDragEnterEvent; +class MainWindow; +class Project; +class SourceFile; +class FormFile; +class QCompletionEdit; +class SourceEditor; + +class WorkspaceItem : public QListViewItem +{ +public: + enum Type { ProjectType, FormFileType, FormSourceType, SourceFileType, ObjectType }; + + WorkspaceItem( QListView *parent, Project* p ); + WorkspaceItem( QListViewItem *parent, SourceFile* sf ); + WorkspaceItem( QListViewItem *parent, FormFile* ff, Type t = FormFileType ); + WorkspaceItem( QListViewItem *parent, QObject *o, Project *p ); + + void paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ); + + Type type() const { return t; } + + bool isModified() const; + + QString text( int ) const; + + void fillCompletionList( QStringList& completion ); + bool checkCompletion( const QString& completion ); + + QString key( int, bool ) const; // column sorting key + + Project* project; + SourceFile* sourceFile; + FormFile* formFile; + QObject *object; + + void setOpen( bool ); + + void setAutoOpen( bool ); + bool isAutoOpen() const { return isOpen() && autoOpen; } + + bool useOddColor; + +private: + void init(); + bool autoOpen; + QColor backgroundColor(); + Type t; +}; + +class Workspace : public QListView +{ + Q_OBJECT + +public: + Workspace( QWidget *parent , MainWindow *mw ); + + void setCurrentProject( Project *pro ); + + void contentsDropEvent( QDropEvent *e ); + void contentsDragEnterEvent( QDragEnterEvent *e ); + void contentsDragMoveEvent( QDragMoveEvent *e ); + + void setBufferEdit( QCompletionEdit *edit ); + +public slots: + + void update(); + void update( FormFile* ); + + void activeFormChanged( FormWindow *fw ); + void activeEditorChanged( SourceEditor *se ); + +protected: + void closeEvent( QCloseEvent *e ); + bool eventFilter( QObject *, QEvent * ); + + +private slots: + void itemClicked( int, QListViewItem *i, const QPoint& pos ); + void itemDoubleClicked( QListViewItem *i ); + void rmbClicked( QListViewItem *i, const QPoint& pos ); + void bufferChosen( const QString &buffer ); + + void projectDestroyed( QObject* ); + + void sourceFileAdded( SourceFile* ); + void sourceFileRemoved( SourceFile* ); + + void formFileAdded( FormFile* ); + void formFileRemoved( FormFile* ); + + void objectAdded( QObject* ); + void objectRemoved( QObject * ); + +private: + WorkspaceItem *findItem( FormFile *ff ); + WorkspaceItem *findItem( SourceFile *sf ); + WorkspaceItem *findItem( QObject *o ); + + void closeAutoOpenItems(); + +private: + MainWindow *mainWindow; + Project *project; + WorkspaceItem *projectItem; + QCompletionEdit *bufferEdit; + bool blockNewForms; + void updateBufferEdit(); + bool completionDirty; + void updateColors(); + +}; + +#endif diff --git a/tools/designer/editor/arghintwidget.cpp b/tools/designer/editor/arghintwidget.cpp new file mode 100644 index 0000000..9d600f6 --- /dev/null +++ b/tools/designer/editor/arghintwidget.cpp @@ -0,0 +1,239 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "arghintwidget.h" +#include +#include +#include +#include +#include + +static const char * left_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ", +" ", +" + ", +" ++ ", +" +++ ", +" ++++ ", +" +++++ ", +" ++++++ ", +" ++++++ ", +" +++++ ", +" ++++ ", +" +++ ", +" ++ ", +" + ", +" ", +" "}; + +static const char * right_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ", +" ", +" + ", +" ++ ", +" +++ ", +" ++++ ", +" +++++ ", +" ++++++ ", +" ++++++ ", +" +++++ ", +" ++++ ", +" +++ ", +" ++ ", +" + ", +" ", +" "}; + +static const char * left_disabled_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c darkgray", +" ", +" ", +" + ", +" ++ ", +" +++ ", +" ++++ ", +" +++++ ", +" ++++++ ", +" ++++++ ", +" +++++ ", +" ++++ ", +" +++ ", +" ++ ", +" + ", +" ", +" "}; + +static const char * right_disabled_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c darkgray", +" ", +" ", +" + ", +" ++ ", +" +++ ", +" ++++ ", +" +++++ ", +" ++++++ ", +" ++++++ ", +" +++++ ", +" ++++ ", +" +++ ", +" ++ ", +" + ", +" ", +" "}; + +class ArrowButton : public QButton +{ + Q_OBJECT + +public: + enum Dir { Left, Right }; + + ArrowButton( QWidget *parent, const char *name, Dir d ); + void drawButton( QPainter *p ); + +private: + QPixmap pix, pix_disabled; + +}; + +ArrowButton::ArrowButton( QWidget *parent, const char *name, Dir d ) + : QButton( parent, name ) +{ + setFixedSize( 16, 16 ); + if ( d == Left ) { + pix = QPixmap( left_xpm ); + pix_disabled = QPixmap( left_disabled_xpm ); + } else { + pix = QPixmap( right_xpm ); + pix_disabled = QPixmap( right_disabled_xpm ); + } +} + +void ArrowButton::drawButton( QPainter *p ) +{ + if ( isDown() ) + p->fillRect( 0, 0, width(), height(), darkGray ); + else + p->fillRect( 0, 0, width(), height(), lightGray ); + if ( isEnabled() ) + p->drawPixmap( 0, 0, pix ); + else + p->drawPixmap( 0, 0, pix_disabled ); +} + + +ArgHintWidget::ArgHintWidget( QWidget *parent, const char*name ) + : QFrame( parent, name, WType_Popup ), curFunc( 0 ), numFuncs( 0 ) +{ + setFrameStyle( QFrame::Box | QFrame::Plain ); + setLineWidth( 1 ); + setBackgroundColor( white ); + QHBoxLayout *hbox = new QHBoxLayout( this ); + hbox->setMargin( 1 ); + hbox->addWidget( ( prev = new ArrowButton( this, "editor_left_btn", ArrowButton::Left ) ) ); + hbox->addWidget( ( funcLabel = new QLabel( this, "editor_func_lbl" ) ) ); + hbox->addWidget( ( next = new ArrowButton( this, "editor_right_btn", ArrowButton::Right ) ) ); + funcLabel->setBackgroundColor( white ); + funcLabel->setAlignment( AlignCenter ); + connect( prev, SIGNAL( clicked() ), this, SLOT( gotoPrev() ) ); + connect( next, SIGNAL( clicked() ), this, SLOT( gotoNext() ) ); + updateState(); + setFocusPolicy( NoFocus ); + prev->setFocusPolicy( NoFocus ); + next->setFocusPolicy( NoFocus ); + funcLabel->setFocusPolicy( NoFocus ); +} + +void ArgHintWidget::setFunctionText( int func, const QString &text ) +{ + funcs.replace( func, text ); + if ( func == curFunc ) { + funcLabel->clear(); + funcLabel->setText( text ); + } +} + +void ArgHintWidget::setNumFunctions( int num ) +{ + funcs.clear(); + numFuncs = num; + curFunc = 0; + updateState(); +} + +void ArgHintWidget::gotoPrev() +{ + if ( curFunc > 0 ) { + curFunc--; + funcLabel->setText( funcs[ curFunc ] ); + updateState(); + } +} + +void ArgHintWidget::gotoNext() +{ + if ( curFunc < numFuncs - 1 ) { + curFunc++; + funcLabel->setText( funcs[ curFunc ] ); + updateState(); + } +} + +void ArgHintWidget::updateState() +{ + prev->setEnabled( curFunc > 0 ); + next->setEnabled( curFunc < numFuncs - 1 ); +} + +void ArgHintWidget::relayout() +{ + funcLabel->setText( "" ); + funcLabel->setText( funcs[ curFunc ] ); +} + +#include "arghintwidget.moc" diff --git a/tools/designer/editor/arghintwidget.h b/tools/designer/editor/arghintwidget.h new file mode 100644 index 0000000..79a4ed6 --- /dev/null +++ b/tools/designer/editor/arghintwidget.h @@ -0,0 +1,69 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef ARGHINTWIDGET_H +#define ARGHINTWIDGET_H + +#include + +class QLabel; +class ArrowButton; + +class ArgHintWidget : public QFrame +{ + Q_OBJECT + +public: + ArgHintWidget( QWidget *parent, const char*name ); + + void setFunctionText( int func, const QString &text ); + void setNumFunctions( int num ); + +public slots: + void relayout(); + void gotoPrev(); + void gotoNext(); + +private: + void updateState(); + +private: + int curFunc; + int numFuncs; + QMap funcs; + QLabel *funcLabel; + ArrowButton *prev, *next; + +}; + +#endif diff --git a/tools/designer/editor/browser.cpp b/tools/designer/editor/browser.cpp new file mode 100644 index 0000000..9d8d818 --- /dev/null +++ b/tools/designer/editor/browser.cpp @@ -0,0 +1,149 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "browser.h" +#include "editor.h" +#include + + +EditorBrowser::EditorBrowser( Editor *e ) + : curEditor( e ), oldHighlightedParag( 0 ) +{ + curEditor = e; + + // ### disabled for now +// curEditor->viewport()->installEventFilter( this ); +// curEditor->installEventFilter( this ); + + QFont fn( curEditor->font() ); + fn.setUnderline( TRUE ); + highlightedFormat = new QTextFormat( fn, blue ); +} + +EditorBrowser::~EditorBrowser() +{ + delete highlightedFormat; +} + +bool EditorBrowser::eventFilter( QObject *o, QEvent *e ) +{ + if ( ::qt_cast(o->parent()) || ::qt_cast(o) ) { + QMouseEvent *me; + QKeyEvent *ke; + switch ( e->type() ) { + case QEvent::MouseMove: + me = (QMouseEvent*)e; + if ( ( me->state() & ControlButton ) == ControlButton ) { + curEditor->viewport()->setCursor( pointingHandCursor ); + QTextCursor c( curEditor->document() ); + curEditor->placeCursor( curEditor->viewportToContents( me->pos() ), &c ); + QTextCursor from, to; + if ( oldHighlightedParag ) { + oldHighlightedParag->setEndState( -1 ); + oldHighlightedParag->format(); + oldHighlightedParag = 0; + } + if ( findCursor( c, from, to ) && from.paragraph() == to.paragraph() ) { + // avoid collision with other selections + for ( int i = 0; i < curEditor->document()->numSelections(); ++i ) + curEditor->document()->removeSelection( i ); + from.paragraph()->setFormat( from.index(), to.index() - from.index() + 1, highlightedFormat, FALSE ); + lastWord = from.paragraph()->string()->toString().mid( from.index(), to.index() - from.index() + 1 ); + oldHighlightedParag = from.paragraph(); + } else { + lastWord = ""; + } + curEditor->repaintChanged(); + return TRUE; + } + break; + case QEvent::MouseButtonPress: { + bool killEvent = !lastWord.isEmpty(); + if ( !lastWord.isEmpty() ) + showHelp( lastWord ); + lastWord = ""; + curEditor->viewport()->setCursor( ibeamCursor ); + if ( oldHighlightedParag ) { + oldHighlightedParag->setEndState( -1 ); + oldHighlightedParag->format(); + curEditor->repaintChanged(); + oldHighlightedParag = 0; + } + if ( killEvent ) + return TRUE; + } break; + case QEvent::KeyRelease: + lastWord = ""; + ke = (QKeyEvent*)e; + if ( ke->key() == Key_Control ) { + curEditor->viewport()->setCursor( ibeamCursor ); + if ( oldHighlightedParag ) { + oldHighlightedParag->setEndState( -1 ); + oldHighlightedParag->format(); + curEditor->repaintChanged(); + oldHighlightedParag = 0; + } + } + default: + break; + } + } + return FALSE; +} + +void EditorBrowser::setCurrentEdior( Editor *e ) +{ + curEditor = e; + curEditor->installEventFilter( this ); +} + +void EditorBrowser::addEditor( Editor *e ) +{ + e->installEventFilter( this ); +} + +bool EditorBrowser::findCursor( const QTextCursor &c, QTextCursor &from, QTextCursor &to ) +{ + from = c; + while ( from.paragraph()->at( from.index() )->c != ' ' && from.paragraph()->at( from.index() )->c != '\t' && from.index() > 0 ) + from.gotoLeft(); + if ( from.paragraph()->at( from.index() )->c == ' ' || from.paragraph()->at( from.index() )->c == '\t' ) + from.gotoRight(); + to = c; + while ( to.paragraph()->at( to.index() )->c != ' ' && to.paragraph()->at( to.index() )->c != '\t' && + to.index() < to.paragraph()->length() - 1 ) + to.gotoRight(); + if ( to.paragraph()->at( to.index() )->c == ' ' || to.paragraph()->at( to.index() )->c == '\t' ) + to.gotoLeft(); + return TRUE; +} diff --git a/tools/designer/editor/browser.h b/tools/designer/editor/browser.h new file mode 100644 index 0000000..a90a9df --- /dev/null +++ b/tools/designer/editor/browser.h @@ -0,0 +1,66 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef BROWSER_H +#define BROWSER_H + +#include + +class Editor; +class QTextCursor; +class QTextParagraph; +class QTextFormat; + +class EditorBrowser : public QObject +{ + Q_OBJECT + +public: + EditorBrowser( Editor *e ); + ~EditorBrowser(); + + bool eventFilter( QObject *o, QEvent *e ); + virtual void setCurrentEdior( Editor *e ); + virtual void addEditor( Editor *e ); + virtual bool findCursor( const QTextCursor &c, QTextCursor &from, QTextCursor &to ); + virtual void showHelp( const QString & ) {} + +protected: + Editor *curEditor; + QTextParagraph *oldHighlightedParag; + QString lastWord; + QTextFormat *highlightedFormat; + +}; + +#endif diff --git a/tools/designer/editor/cindent.cpp b/tools/designer/editor/cindent.cpp new file mode 100644 index 0000000..545c374 --- /dev/null +++ b/tools/designer/editor/cindent.cpp @@ -0,0 +1,163 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "cindent.h" +#include "qregexp.h" + +extern int indentForBottomLine( const QStringList& program, QChar typedIn ); +extern void setTabSize( int s ); +extern void setIndentSize( int s ); + +CIndent::CIndent() + : QTextIndent(), tabSize( 8 ), indentSize( 4 ), + autoIndent( TRUE ), keepTabs( TRUE ), lastDoc( 0 ) +{ +} + +static int indentation( const QString &s ) +{ + if ( s.simplifyWhiteSpace().length() == 0 ) + return 0; + int i = 0; + int ind = 0; + while ( i < (int)s.length() ) { + QChar c = s.at( i ); + if ( c == ' ' ) + ind++; + else if ( c == '\t' ) + ind += 8; + else + break; + ++i; + } + return ind; +} + +void CIndent::tabify( QString &s ) +{ + if ( !keepTabs ) + return; + int i = 0; + for ( ;; ) { + for ( int j = i; j < (int)s.length(); ++j ) { + if ( s[ j ] != ' ' && s[ j ] != '\t' ) { + if ( j > i ) { + QString t = s.mid( i, j - i ); + int spaces = 0; + for ( int k = 0; k < (int)t.length(); ++k ) + spaces += ( t[ k ] == ' ' ? 1 : tabSize ); + s.remove( i, t.length() ); + int tabs = spaces / tabSize; + spaces = spaces - ( tabSize * tabs ); + QString tmp; + tmp.fill( ' ', spaces ); + if ( spaces > 0 ) + s.insert( i, tmp ); + tmp.fill( '\t', tabs ); + if ( tabs > 0 ) + s.insert( i, tmp ); + } + break; + } + } + i = s.find( '\n', i ); + if ( i == -1 ) + break; + ++i; + } +} + +void CIndent::indentLine( QTextParagraph *p, int &oldIndent, int &newIndent ) +{ + QString indentString; + indentString.fill( ' ', newIndent ); + indentString.append( "a" ); + tabify( indentString ); + indentString.remove( indentString.length() - 1, 1 ); + newIndent = indentString.length(); + oldIndent = 0; + while ( p->length() > 0 && ( p->at( 0 )->c == ' ' || p->at( 0 )->c == '\t' ) ) { + ++oldIndent; + p->remove( 0, 1 ); + } + if ( p->string()->length() == 0 ) + p->append( " " ); + if ( !indentString.isEmpty() ) + p->insert( 0, indentString ); +} + + +void CIndent::indent( QTextDocument *doc, QTextParagraph *p, int *oldIndent, int *newIndent ) +{ + lastDoc = doc; + int oi = indentation( p->string()->toString() ); + QStringList code; + QTextParagraph *parag = doc->firstParagraph(); + while ( parag ) { + code << parag->string()->toString(); + if ( parag == p ) + break; + parag = parag->next(); + } + + int ind = indentForBottomLine( code, QChar::null ); + indentLine( p, oi, ind ); + if ( oldIndent ) + *oldIndent = oi; + if ( newIndent ) + *newIndent = ind; +} + +void CIndent::reindent() +{ + if ( !lastDoc ) + return; + // #### this is sloooooooow (O(n^2)) + QTextParagraph *parag = lastDoc->firstParagraph(); + while ( parag ) { + indent( lastDoc, parag, 0, 0 ); + parag = parag->next(); + } +} + +void CIndent::setTabSize( int ts ) +{ + tabSize = ts; + ::setTabSize( ts ); +} + +void CIndent::setIndentSize( int is ) +{ + indentSize = is; + ::setIndentSize( is ); +} diff --git a/tools/designer/editor/cindent.h b/tools/designer/editor/cindent.h new file mode 100644 index 0000000..b184049 --- /dev/null +++ b/tools/designer/editor/cindent.h @@ -0,0 +1,63 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CINDENT_H +#define CINDENT_H + +#include + +class CIndent : public QTextIndent +{ +public: + CIndent(); + virtual ~CIndent() {} + void indent( QTextDocument *doc, QTextParagraph *parag, int *oldIndent, int *newIndent ); + + void setTabSize( int ts ); + void setIndentSize( int is ); + void setAutoIndent( bool ai ) { autoIndent = ai; reindent(); } + void setKeepTabs( bool kt ) { keepTabs = kt; } + +private: + void reindent(); + void indentLine( QTextParagraph *p, int &oldIndent, int &newIndent ); + void tabify( QString &s ); + +public: + int tabSize, indentSize; + bool autoIndent, keepTabs; + QTextDocument *lastDoc; + +}; + +#endif diff --git a/tools/designer/editor/completion.cpp b/tools/designer/editor/completion.cpp new file mode 100644 index 0000000..9ab09fa --- /dev/null +++ b/tools/designer/editor/completion.cpp @@ -0,0 +1,714 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "completion.h" +#include "paragdata.h" +#include "editor.h" +#include +#include +#include +#include +#include +#include +#include "arghintwidget.h" +#include +#include + +static QColor getColor( const QString &type ) +{ + if ( type == "function" || type == "slot" || type == "package" ) + return Qt::blue; + else if ( type == "variable" || type == "widget" || type == "dir" ) + return Qt::darkRed; + else if ( type == "object" || type == "class" ) + return Qt::darkBlue; + else if ( type == "property" ) + return Qt::darkGreen; + else if ( type == "enum" ) + return Qt::darkYellow; + return Qt::black; +} + +class CompletionItem : public QListBoxItem +{ +public: + CompletionItem( QListBox *lb, const QString &txt, const QString &t, const QString &p, + const QString &pre, const QString &p2 ) + : QListBoxItem( lb ), type( t ), postfix( p ), prefix( pre ), postfix2( p2 ), + parag( 0 ), lastState( FALSE ) { setText( txt ); } + ~CompletionItem() { delete parag; } + void paint( QPainter *painter ) { + if ( lastState != isSelected() ) { + delete parag; + parag = 0; + } + lastState = isSelected(); + if ( !parag ) + setupParagraph(); + parag->paint( *painter, listBox()->colorGroup() ); + } + + int height( const QListBox * ) const { + if ( !parag ) + ( (CompletionItem*)this )->setupParagraph(); + return parag->rect().height(); + } + int width( const QListBox * ) const { + if ( !parag ) + ( (CompletionItem*)this )->setupParagraph(); + return parag->rect().width() - 2; + } + QString text() const { return QListBoxItem::text() + postfix; } + +private: + void setupParagraph(); + QString type, postfix, prefix, postfix2; + QTextParagraph *parag; + bool lastState; + +}; + +void CompletionItem::setupParagraph() { + if ( !parag ) { + QTextFormatter *formatter; + formatter = new QTextFormatterBreakWords; + formatter->setWrapEnabled( FALSE ); + parag = new QTextParagraph( 0 ); + parag->setTabStops( listBox()->fontMetrics().width( "propertyXXXX" ) ); + parag->pseudoDocument()->pFormatter = formatter; + parag->insert( 0, " " + type + ( type.isEmpty() ? " " : "\t" ) + prefix + + QListBoxItem::text() + postfix + postfix2 ); + bool selCol = isSelected() && listBox()->colorGroup().highlightedText() != listBox()->colorGroup().text(); + QColor sc = selCol ? listBox()->colorGroup().highlightedText() : getColor( type ); + QTextFormat *f1 = parag->formatCollection()->format( listBox()->font(), sc ); + QTextFormat *f3 = parag->formatCollection()->format( listBox()->font(), isSelected() ? + listBox()->colorGroup().highlightedText() : + listBox()->colorGroup().text() ); + QFont f( listBox()->font() ); + f.setBold( TRUE ); + QTextFormat *f2 = + parag->formatCollection()->format( f, isSelected() ? listBox()->colorGroup().highlightedText() : + listBox()->colorGroup().text() ); + parag->setFormat( 1, type.length() + 1, f1 ); + parag->setFormat( type.length() + 2, prefix.length() + QListBoxItem::text().length(), f2 ); + if ( !postfix.isEmpty() ) + parag->setFormat( type.length() + 2 + prefix.length() + QListBoxItem::text().length(), + postfix.length(), f3 ); + parag->setFormat( type.length() + 2 + prefix.length() + QListBoxItem::text().length() + postfix.length(), + postfix2.length(), f3 ); + f1->removeRef(); + f2->removeRef(); + f3->removeRef(); + parag->format(); + } +} + + +EditorCompletion::EditorCompletion( Editor *e ) +{ + enabled = TRUE; + lastDoc = 0; + completionPopup = new QVBox( e->topLevelWidget(), 0, WType_Popup ); + completionPopup->setFrameStyle( QFrame::Box | QFrame::Plain ); + completionPopup->setLineWidth( 1 ); + functionLabel = new ArgHintWidget( e->topLevelWidget(), "editor_function_lbl" ); + functionLabel->hide(); + completionListBox = new QListBox( completionPopup, "editor_completion_lb" ); + completionListBox->setFrameStyle( QFrame::NoFrame ); + completionListBox->installEventFilter( this ); + completionListBox->setHScrollBarMode( QScrollView::AlwaysOn ); + completionListBox->setVScrollBarMode( QScrollView::AlwaysOn ); + completionListBox->setCornerWidget( new QSizeGrip( completionListBox, "editor_cornerwidget" ) ); + completionPopup->installEventFilter( this ); + functionLabel->installEventFilter( this ); + completionPopup->setFocusProxy( completionListBox ); + completionOffset = 0; + curEditor = e; + curEditor->installEventFilter( this ); +} + +EditorCompletion::~EditorCompletion() +{ + delete completionPopup; + delete functionLabel; +} + +void EditorCompletion::addCompletionEntry( const QString &s, QTextDocument *, bool strict ) +{ + QChar key( s[ 0 ] ); + QMap::Iterator it = completionMap.find( key ); + if ( it == completionMap.end() ) { + completionMap.insert( key, QStringList( s ) ); + } else { + if ( strict ) { + QStringList::Iterator sit; + for ( sit = (*it).begin(); sit != (*it).end(); ) { + QStringList::Iterator it2 = sit; + ++sit; + if ( (*it2).length() > s.length() && (*it2).left( s.length() ) == s ) { + if ( (*it2)[ (int)s.length() ].isLetter() && (*it2)[ (int)s.length() ].upper() != (*it2)[ (int)s.length() ] ) + return; + } else if ( s.length() > (*it2).length() && s.left( (*it2).length() ) == *it2 ) { + if ( s[ (int)(*it2).length() ].isLetter() && s[ (int)(*it2).length() ].upper() != s[ (int)(*it2).length() ] ) + (*it).remove( it2 ); + } + } + } + (*it).append( s ); + } +} + +QValueList EditorCompletion::completionList( const QString &s, QTextDocument *doc ) const +{ + if ( doc ) + ( (EditorCompletion*)this )->updateCompletionMap( doc ); + + QChar key( s[ 0 ] ); + QMap::ConstIterator it = completionMap.find( key ); + if ( it == completionMap.end() ) + return QValueList(); + QStringList::ConstIterator it2 = (*it).begin(); + QValueList lst; + int len = s.length(); + for ( ; it2 != (*it).end(); ++it2 ) { + CompletionEntry c; + c.type = ""; + c.text = *it2; + c.postfix = ""; + c.prefix = ""; + c.postfix2 = ""; + if ( (int)(*it2).length() > len && (*it2).left( len ) == s && lst.find( c ) == lst.end() ) + lst << c; + } + + return lst; +} + +void EditorCompletion::updateCompletionMap( QTextDocument *doc ) +{ + bool strict = TRUE; + if ( doc != lastDoc ) + strict = FALSE; + lastDoc = doc; + QTextParagraph *s = doc->firstParagraph(); + if ( !s->extraData() ) + s->setExtraData( new ParagData ); + while ( s ) { + if ( s->length() == ( (ParagData*)s->extraData() )->lastLengthForCompletion ) { + s = s->next(); + continue; + } + + QChar c; + QString buffer; + for ( int i = 0; i < s->length(); ++i ) { + c = s->at( i )->c; + if ( c.isLetter() || c.isNumber() || c == '_' || c == '#' ) { + buffer += c; + } else { + addCompletionEntry( buffer, doc, strict ); + buffer = QString::null; + } + } + if ( !buffer.isEmpty() ) + addCompletionEntry( buffer, doc, strict ); + + ( (ParagData*)s->extraData() )->lastLengthForCompletion = s->length(); + s = s->next(); + } +} + +bool EditorCompletion::doCompletion() +{ + searchString = ""; + if ( !curEditor ) + return FALSE; + + QTextCursor *cursor = curEditor->textCursor(); + QTextDocument *doc = curEditor->document(); + + if ( cursor->index() > 0 && cursor->paragraph()->at( cursor->index() - 1 )->c == '.' && + ( cursor->index() == 1 || cursor->paragraph()->at( cursor->index() - 2 )->c != '.' ) ) + return doObjectCompletion(); + + int idx = cursor->index(); + if ( idx == 0 ) + return FALSE; + QChar c = cursor->paragraph()->at( idx - 1 )->c; + if ( !c.isLetter() && !c.isNumber() && c != '_' && c != '#' ) + return FALSE; + + QString s; + idx--; + completionOffset = 1; + for (;;) { + s.prepend( QString( cursor->paragraph()->at( idx )->c ) ); + idx--; + if ( idx < 0 ) + break; + if ( !cursor->paragraph()->at( idx )->c.isLetter() && + !cursor->paragraph()->at( idx )->c.isNumber() && + cursor->paragraph()->at( idx )->c != '_' && + cursor->paragraph()->at( idx )->c != '#' ) + break; + completionOffset++; + } + + searchString = s; + + QValueList lst( completionList( s, doc ) ); + if ( lst.count() > 1 ) { + QTextStringChar *chr = cursor->paragraph()->at( cursor->index() ); + int h = cursor->paragraph()->lineHeightOfChar( cursor->index() ); + int x = cursor->paragraph()->rect().x() + chr->x; + int y, dummy; + cursor->paragraph()->lineHeightOfChar( cursor->index(), &dummy, &y ); + y += cursor->paragraph()->rect().y(); + completionListBox->clear(); + for ( QValueList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) + (void)new CompletionItem( completionListBox, (*it).text, (*it).type, (*it).postfix, + (*it).prefix, (*it).postfix2 ); + cList = lst; + completionPopup->resize( completionListBox->sizeHint() + + QSize( completionListBox->verticalScrollBar()->width() + 4, + completionListBox->horizontalScrollBar()->height() + 4 ) ); + completionListBox->setCurrentItem( 0 ); + completionListBox->setFocus(); + if ( curEditor->mapToGlobal( QPoint( 0, y ) ).y() + h + completionPopup->height() < QApplication::desktop()->height() ) + completionPopup->move( curEditor->mapToGlobal( curEditor-> + contentsToViewport( QPoint( x, y + h ) ) ) ); + else + completionPopup->move( curEditor->mapToGlobal( curEditor-> + contentsToViewport( QPoint( x, y - completionPopup->height() ) ) ) ); + completionPopup->show(); + } else if ( lst.count() == 1 ) { + curEditor->insert( lst.first().text.mid( completionOffset, 0xFFFFFF ), + (uint) ( QTextEdit::RedoIndentation | + QTextEdit::CheckNewLines | + QTextEdit::RemoveSelected ) ); + } else { + return FALSE; + } + + return TRUE; +} + +bool EditorCompletion::eventFilter( QObject *o, QEvent *e ) +{ + if ( !enabled ) + return FALSE; + if ( e->type() == QEvent::KeyPress && ::qt_cast(o)) { + curEditor = (Editor*)o; + QKeyEvent *ke = (QKeyEvent*)e; + if ( ke->key() == Key_Tab ) { + QString s = curEditor->textCursor()->paragraph()->string()->toString(). + left( curEditor->textCursor()->index() ); + if ( curEditor->document()->hasSelection( QTextDocument::Standard ) || + s.simplifyWhiteSpace().isEmpty() ) { + if ( curEditor->document()->indent() ) { + curEditor->indent(); + int i = 0; + for ( ; i < curEditor->textCursor()->paragraph()->length() - 1; ++i ) { + if ( curEditor->textCursor()->paragraph()->at( i )->c != ' ' && + curEditor->textCursor()->paragraph()->at( i )->c != '\t' ) + break; + } + curEditor->drawCursor( FALSE ); + curEditor->textCursor()->setIndex( i ); + curEditor->drawCursor( TRUE ); + } else { + curEditor->insert( "\t" ); + } + return TRUE; + } + } + + if ( functionLabel->isVisible() ) { + if ( ke->key() == Key_Up && ( ke->state() & ControlButton ) == ControlButton ) { + functionLabel->gotoPrev(); + return TRUE; + } else if ( ke->key() == Key_Down && ( ke->state() & ControlButton ) == ControlButton ) { + functionLabel->gotoNext(); + return TRUE; + } + } + + if ( ke->text().length() && !( ke->state() & AltButton ) && + ( !ke->ascii() || ke->ascii() >= 32 ) || + ( ke->text() == "\t" && !( ke->state() & ControlButton ) ) ) { + if ( ke->key() == Key_Tab ) { + if ( curEditor->textCursor()->index() == 0 && + curEditor->textCursor()->paragraph()->isListItem() ) + return FALSE; + if ( doCompletion() ) + return TRUE; + } else if ( ke->key() == Key_Period && + ( curEditor->textCursor()->index() == 0 || + curEditor->textCursor()->paragraph()->at( curEditor->textCursor()->index() - 1 )->c != '.' ) + || + ke->key() == Key_Greater && + curEditor->textCursor()->index() > 0 && + curEditor->textCursor()->paragraph()->at( curEditor->textCursor()->index() - 1 )->c == '-' ) { + doObjectCompletion(); + } else { + if ( !doArgumentHint( ke->text() == "(" ) ) + functionLabel->hide(); + } + } + } else if ( o == completionPopup || o == completionListBox || + o == completionListBox->viewport() ) { + if ( e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ke->key() == Key_Enter || ke->key() == Key_Return || ke->key() == Key_Tab ) { + if ( ke->key() == Key_Tab && completionListBox->count() > 1 && + completionListBox->currentItem() < (int)completionListBox->count() - 1 ) { + completionListBox->setCurrentItem( completionListBox->currentItem() + 1 ); + return TRUE; + } + completeCompletion(); + return TRUE; + } else if ( ke->key() == Key_Left || ke->key() == Key_Right || + ke->key() == Key_Up || ke->key() == Key_Down || + ke->key() == Key_Home || ke->key() == Key_End || + ke->key() == Key_Prior || ke->key() == Key_Next ) { + return FALSE; + } else if ( ke->key() != Key_Shift && ke->key() != Key_Control && + ke->key() != Key_Alt ) { + int l = searchString.length(); + if ( ke->key() == Key_Backspace ) { + searchString.remove( searchString.length() - 1, 1 ); + } else { + searchString += ke->text(); + l = 1; + } + if ( !l || !continueComplete() ) { + completionPopup->close(); + curEditor->setFocus(); + } + QApplication::sendEvent( curEditor, e ); + return TRUE; + } + } else if ( e->type() == QEvent::MouseButtonDblClick ) { + completeCompletion(); + return TRUE; + } + } + if ( o == functionLabel || ::qt_cast(o) && functionLabel->isVisible() ) { + if ( e->type() == QEvent::KeyPress ) { + QKeyEvent *ke = (QKeyEvent*)e; + if ( ke->key() == Key_Escape ) { + functionLabel->hide(); + } else { + if ( !doArgumentHint( ke->text() == "(" ) ) + functionLabel->hide(); + if ( o == functionLabel ) { + QApplication::sendEvent( curEditor, e ); + return TRUE; + } + } + } + } + return FALSE; +} + +void EditorCompletion::completeCompletion() +{ + int idx = curEditor->textCursor()->index(); + QString s = completionListBox->currentText().mid( searchString.length() ); + curEditor->insert( s, (uint) ( QTextEdit::RedoIndentation | + QTextEdit::CheckNewLines | + QTextEdit::RemoveSelected ) ); + int i = s.find( '(' ); + completionPopup->close(); + curEditor->setFocus(); + if ( i != -1 && i < (int)s.length() ) { + curEditor->setCursorPosition( curEditor->textCursor()->paragraph()->paragId(), idx + i + 1 ); + doArgumentHint( FALSE ); + } +} + +void EditorCompletion::setCurrentEdior( Editor *e ) +{ + curEditor = e; + curEditor->installEventFilter( this ); +} + +void EditorCompletion::addEditor( Editor *e ) +{ + e->installEventFilter( this ); +} + +bool EditorCompletion::doObjectCompletion() +{ + searchString = ""; + QString object; + int i = curEditor->textCursor()->index(); + i--; + QTextParagraph *p = curEditor->textCursor()->paragraph(); + for (;;) { + if ( i < 0 ) + break; + if ( p->at( i )->c == ' ' || p->at( i )->c == '\t' ) + break; + object.prepend( p->at( i )->c ); + i--; + } + + if ( object[ (int)object.length() - 1 ] == '-' ) + object.remove( object.length() - 1, 1 ); + + if ( object.isEmpty() ) + return FALSE; + return doObjectCompletion( object ); +} + +bool EditorCompletion::doObjectCompletion( const QString & ) +{ + return FALSE; +} + +static void strip( QString &txt ) +{ + int i = txt.find( "(" ); + if ( i == -1 ) + return; + txt = txt.left( i ); +} + +bool EditorCompletion::continueComplete() +{ + if ( searchString.isEmpty() ) { + completionListBox->clear(); + for ( QValueList::ConstIterator it = cList.begin(); it != cList.end(); ++it ) + (void)new CompletionItem( completionListBox, (*it).text, (*it).type, + (*it).postfix, (*it).prefix, (*it).postfix2 ); + completionListBox->setCurrentItem( 0 ); + completionListBox->setSelected( completionListBox->currentItem(), TRUE ); + return TRUE; + } + + QListBoxItem *i = completionListBox->findItem( searchString ); + if ( !i ) + return FALSE; + + QString txt1 = i->text(); + QString txt2 = searchString; + strip( txt1 ); + strip( txt2 ); + if ( txt1 == txt2 && !i->next() ) + return FALSE; + + QValueList res; + for ( QValueList::ConstIterator it = cList.begin(); it != cList.end(); ++it ) { + if ( (*it).text.left( searchString.length() ) == searchString ) + res << *it; + } + if ( res.isEmpty() ) + return FALSE; + completionListBox->clear(); + for ( QValueList::ConstIterator it2 = res.begin(); it2 != res.end(); ++it2 ) + (void)new CompletionItem( completionListBox, (*it2).text, (*it2).type, + (*it2).postfix, (*it2).prefix, (*it2).postfix2 ); + completionListBox->setCurrentItem( 0 ); + completionListBox->setSelected( completionListBox->currentItem(), TRUE ); + return TRUE; +} + +bool EditorCompletion::doArgumentHint( bool useIndex ) +{ + QTextCursor *cursor = curEditor->textCursor(); + int i = cursor->index() ; + if ( !useIndex ) { + bool foundParen = FALSE; + int closeParens = 0; + while ( i >= 0 ) { + if ( cursor->paragraph()->at( i )->c == ')' && i != cursor->index() ) + closeParens++; + if ( cursor->paragraph()->at( i )->c == '(' ) { + closeParens--; + if ( closeParens == -1 ) { + foundParen = TRUE; + break; + } + } + --i; + } + + if ( !foundParen ) + return FALSE; + } + int j = i - 1; + bool foundSpace = FALSE; + bool foundNonSpace = FALSE; + while ( j >= 0 ) { + if ( foundNonSpace && ( cursor->paragraph()->at( j )->c == ' ' || cursor->paragraph()->at( j )->c == ',' ) ) { + foundSpace = TRUE; + break; + } + if ( !foundNonSpace && ( cursor->paragraph()->at( j )->c != ' ' || cursor->paragraph()->at( j )->c != ',' ) ) + foundNonSpace = TRUE; + --j; + } + if ( foundSpace ) + ++j; + j = QMAX( j, 0 ); + QString function( cursor->paragraph()->string()->toString().mid( j, i - j + 1 ) ); + QString part = cursor->paragraph()->string()->toString().mid( j, cursor->index() - j + 1 ); + function = function.simplifyWhiteSpace(); + for (;;) { + if ( function[ (int)function.length() - 1 ] == '(' ) { + function.remove( function.length() - 1, 1 ); + function = function.simplifyWhiteSpace(); + } else if ( function[ (int)function.length() - 1 ] == ')' ) { + function.remove( function.length() - 1, 1 ); + function = function.simplifyWhiteSpace(); + } else { + break; + } + } + + QChar sep; + QString pre, post; + QValueList argl = functionParameters( function, sep, pre, post ); + if ( argl.isEmpty() ) + return FALSE; + + QString label; + int w = 0; + int num = 0; + if ( !functionLabel->isVisible() ) + functionLabel->setNumFunctions( (int)argl.count() ); + for ( QValueList::Iterator vit = argl.begin(); vit != argl.end(); ++vit, ++num ) { + QStringList args = *vit; + int argNum = 0; + int inParen = 0; + for ( int k = 0; k < (int)part.length(); ++k ) { + if ( part[ k ] == sep && inParen < 2 ) + argNum++; + if ( part[ k ] == '(' ) + inParen++; + if ( part[ k ] == ')' ) + inParen--; + } + + QString func = function; + int pnt = -1; + pnt = func.findRev( '.' ); + if ( pnt == -1 ) + func.findRev( '>' ); + if ( pnt != -1 ) + func = func.mid( pnt + 1 ); + + QString s = func + "( "; + if ( s[ 0 ] == '\"' ) + s.remove( (uint)0, 1 ); + i = 0; + for ( QStringList::Iterator it = args.begin(); it != args.end(); ++it, ++i ) { + if ( i == argNum ) + s += "" + *it + ""; + else + s += *it; + if ( i < (int)args.count() - 1 ) + s += ", "; + else + s += " "; + } + s += ")"; + s.prepend( pre ); + s.append( post ); + label += "

    " + s + "

    "; + functionLabel->setFunctionText( num, s ); + w = QMAX( w, functionLabel->fontMetrics().width( s ) + 10 ); + } + w += 16; + if ( label.isEmpty() ) + return FALSE; + if ( functionLabel->isVisible() ) { + functionLabel->resize( w + 50, QMAX( functionLabel->fontMetrics().height(), 16 ) ); + } else { + QTextStringChar *chr = cursor->paragraph()->at( cursor->index() ); + int h = cursor->paragraph()->lineHeightOfChar( cursor->index() ); + int x = cursor->paragraph()->rect().x() + chr->x; + int y, dummy; + cursor->paragraph()->lineHeightOfChar( cursor->index(), &dummy, &y ); + y += cursor->paragraph()->rect().y(); + functionLabel->resize( w + 50, QMAX( functionLabel->fontMetrics().height(), 16 ) ); + functionLabel->move( curEditor->mapToGlobal( curEditor->contentsToViewport( QPoint( x, y + h ) ) ) ); + if ( functionLabel->x() + functionLabel->width() > QApplication::desktop()->width() ) + functionLabel->move( QMAX( 0, QApplication::desktop()->width() - functionLabel->width() ), + functionLabel->y() ); + functionLabel->show(); + curEditor->setFocus(); + } + QTimer::singleShot( 0, functionLabel, SLOT( relayout() ) ); + + return TRUE; +} + +QValueList EditorCompletion::functionParameters( const QString &, QChar &, QString &, QString & ) +{ + return QValueList(); +} + +void EditorCompletion::setContext( QObject * ) +{ +} + +void EditorCompletion::showCompletion( const QValueList &lst ) +{ + QTextCursor *cursor = curEditor->textCursor(); + QTextStringChar *chr = cursor->paragraph()->at( cursor->index() ); + int h = cursor->paragraph()->lineHeightOfChar( cursor->index() ); + int x = cursor->paragraph()->rect().x() + chr->x; + int y, dummy; + cursor->paragraph()->lineHeightOfChar( cursor->index(), &dummy, &y ); + y += cursor->paragraph()->rect().y(); + completionListBox->clear(); + for ( QValueList::ConstIterator it = lst.begin(); it != lst.end(); ++it ) + (void)new CompletionItem( completionListBox, (*it).text, (*it).type, + (*it).postfix, (*it).prefix, (*it).postfix2 ); + cList = lst; + completionPopup->resize( completionListBox->sizeHint() + + QSize( completionListBox->verticalScrollBar()->width() + 4, + completionListBox->horizontalScrollBar()->height() + 4 ) ); + completionListBox->setCurrentItem( 0 ); + completionListBox->setFocus(); + if ( curEditor->mapToGlobal( QPoint( 0, y ) ).y() + h + completionPopup->height() < QApplication::desktop()->height() ) + completionPopup->move( curEditor->mapToGlobal( curEditor-> + contentsToViewport( QPoint( x, y + h ) ) ) ); + else + completionPopup->move( curEditor->mapToGlobal( curEditor-> + contentsToViewport( QPoint( x, y - completionPopup->height() ) ) ) ); + + completionPopup->show(); +} diff --git a/tools/designer/editor/completion.h b/tools/designer/editor/completion.h new file mode 100644 index 0000000..94acf6b --- /dev/null +++ b/tools/designer/editor/completion.h @@ -0,0 +1,110 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef COMPLETION_H +#define COMPLETION_H + +#include +#include +#include +#include + +class QTextDocument; +class Editor; +class QVBox; +class QListBox; +class ArgHintWidget; + +struct CompletionEntry +{ + QString type; + QString text; + QString postfix; + QString prefix; + QString postfix2; + + bool operator==( const CompletionEntry &c ) const { + return ( c.type == type && + c.text == text && + c.postfix == postfix && + c.prefix == prefix && + c.postfix2 == postfix2 ); + } +}; + +class EditorCompletion : public QObject +{ + Q_OBJECT + +public: + EditorCompletion( Editor *e ); + ~EditorCompletion(); + + virtual void addCompletionEntry( const QString &s, QTextDocument *doc, bool strict ); + virtual QValueList completionList( const QString &s, QTextDocument *doc ) const; + virtual void updateCompletionMap( QTextDocument *doc ); + + bool eventFilter( QObject *o, QEvent *e ); + virtual void setCurrentEdior( Editor *e ); + virtual bool doCompletion(); + virtual bool doObjectCompletion(); + virtual bool doObjectCompletion( const QString &object ); + virtual bool doArgumentHint( bool useIndex ); + + virtual void addEditor( Editor *e ); + virtual QValueList functionParameters( const QString &func, QChar &, QString &prefix, QString &postfix ); + + virtual void setContext( QObject *this_ ); + + void setEnabled( bool b ) { enabled = b; } + +protected: + virtual bool continueComplete(); + virtual void showCompletion( const QValueList &lst ); + virtual void completeCompletion(); + +protected: + QVBox *completionPopup; + QListBox *completionListBox; + ArgHintWidget *functionLabel; + int completionOffset; + Editor *curEditor; + QString searchString; + QValueList cList; + QMap completionMap; + bool enabled; + QTextDocument *lastDoc; + +}; + +#endif diff --git a/tools/designer/editor/conf.cpp b/tools/designer/editor/conf.cpp new file mode 100644 index 0000000..11e4f0a --- /dev/null +++ b/tools/designer/editor/conf.cpp @@ -0,0 +1,269 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "conf.h" +#include +#include +#include +#include + +QMap Config::defaultStyles() +{ + ConfigStyle s; + QMap styles; + int normalSize = qApp->font().pointSize(); + QString normalFamily = qApp->font().family(); + QString commentFamily = "times"; + int normalWeight = qApp->font().weight(); + + s.font = QFont( normalFamily, normalSize, normalWeight ); + s.color = Qt::black; + styles.insert( "Standard", s ); + + s.font = QFont( commentFamily, normalSize, normalWeight, TRUE ); + s.color = Qt::red; + styles.insert( "Comment", s ); + + s.font = QFont( normalFamily, normalSize, normalWeight ); + s.color = Qt::blue; + styles.insert( "Number", s ); + + s.font = QFont( normalFamily, normalSize, normalWeight ); + s.color = Qt::darkGreen; + styles.insert( "String", s ); + + s.font = QFont( normalFamily, normalSize, normalWeight ); + s.color = Qt::darkMagenta; + styles.insert( "Type", s ); + + s.font = QFont( normalFamily, normalSize, normalWeight ); + s.color = Qt::darkYellow; + styles.insert( "Keyword", s ); + + s.font = QFont( normalFamily, normalSize, normalWeight ); + s.color = Qt::darkBlue; + styles.insert( "Preprocessor", s ); + + s.font = QFont( normalFamily, normalSize, normalWeight ); + s.color = Qt::darkRed; + styles.insert( "Label", s ); + + return styles; +} + +QMap Config::readStyles( const QString &path ) +{ + QMap styles; + styles = defaultStyles(); + + QString family; + int size = 10; + bool bold = FALSE, italic = FALSE, underline = FALSE; + int red = 0, green = 0, blue = 0; + + QString elements[] = { + "Comment", + "Number", + "String", + "Type", + "Keyword", + "Preprocessor", + "Label", + "Standard", + QString::null + }; + + for ( int i = 0; elements[ i ] != QString::null; ++i ) { + QSettings settings; + bool ok = TRUE; + for (;;) { + family = settings.readEntry( path + elements[ i ] + "/family", QString::null, &ok ); + if ( !ok ) + break; + size = settings.readNumEntry( path + elements[ i ] + "/size", 10, &ok ); + if ( !ok ) + break; + bold = settings.readBoolEntry( path + elements[ i ] + "/bold", FALSE, &ok ); + if ( !ok ) + break; + italic = settings.readBoolEntry( path + elements[ i ] + "/italic", FALSE, &ok ); + if ( !ok ) + break; + underline = settings.readBoolEntry( path + elements[ i ] + "/underline", FALSE, &ok ); + if ( !ok ) + break; + red = settings.readNumEntry( path + elements[ i ] + "/red", 0, &ok ); + if ( !ok ) + break; + green = settings.readNumEntry( path + elements[ i ] + "/green", 0, &ok ); + if ( !ok ) + break; + blue = settings.readNumEntry( path + elements[ i ] + "/blue", 0, &ok ); + if ( !ok ) + break; + break; + } + if ( !ok ) + continue; + QFont f( family ); + f.setPointSize( size ); + f.setBold( bold ); + f.setItalic( italic ); + f.setUnderline( underline ); + QColor c( red, green, blue ); + ConfigStyle s; + s.font = f; + s.color = c; + styles.remove( elements[ i ] ); + styles.insert( elements[ i ], s ); + } + return styles; +} + +void Config::saveStyles( const QMap &styles, const QString &path ) +{ + QString elements[] = { + "Comment", + "Number", + "String", + "Type", + "Keyword", + "Preprocessor", + "Label", + "Standard", + QString::null + }; + + QSettings settings; + for ( int i = 0; elements[ i ] != QString::null; ++i ) { + settings.writeEntry( path + "/" + elements[ i ] + "/family", styles[ elements[ i ] ].font.family() ); + settings.writeEntry( path + "/" + elements[ i ] + "/size", styles[ elements[ i ] ].font.pointSize() ); + settings.writeEntry( path + "/" + elements[ i ] + "/bold", styles[ elements[ i ] ].font.bold() ); + settings.writeEntry( path + "/" + elements[ i ] + "/italic", styles[ elements[ i ] ].font.italic() ); + settings.writeEntry( path + "/" + elements[ i ] + "/underline", styles[ elements[ i ] ].font.underline() ); + settings.writeEntry( path + "/" + elements[ i ] + "/red", styles[ elements[ i ] ].color.red() ); + settings.writeEntry( path + "/" + elements[ i ] + "/green", styles[ elements[ i ] ].color.green() ); + settings.writeEntry( path + "/" + elements[ i ] + "/blue", styles[ elements[ i ] ].color.blue() ); + } +} + +bool Config::completion( const QString &path ) +{ + QSettings settings; + bool ret = settings.readBoolEntry( path + "/completion", TRUE ); + return ret; +} + +bool Config::wordWrap( const QString &path ) +{ + QSettings settings; + bool ret = settings.readBoolEntry( path + "/wordWrap", TRUE ); + return ret; +} + +bool Config::parenMatching( const QString &path ) +{ + QSettings settings; + bool ret = settings.readBoolEntry( path + "/parenMatching", TRUE ); + return ret; +} + +int Config::indentTabSize( const QString &path ) +{ + QSettings settings; + int ret = settings.readNumEntry( path + "/indentTabSize", 8 ); + return ret; +} + +int Config::indentIndentSize( const QString &path ) +{ + QSettings settings; + int ret = settings.readNumEntry( path + "/indentIndentSize", 4 ); + return ret; +} + +bool Config::indentKeepTabs( const QString &path ) +{ + QSettings settings; + bool ret = settings.readBoolEntry( path + "/indentKeepTabs", TRUE ); + return ret; +} + +bool Config::indentAutoIndent( const QString &path ) +{ + QSettings settings; + bool ret = settings.readBoolEntry( path + "/indentAutoIndent", TRUE ); + return ret; +} + +void Config::setCompletion( bool b, const QString &path ) +{ + QSettings settings; + settings.writeEntry( path + "/completion", b ); +} + +void Config::setWordWrap( bool b, const QString &path ) +{ + QSettings settings; + settings.writeEntry( path + "/wordWrap", b ); +} + +void Config::setParenMatching( bool b,const QString &path ) +{ + QSettings settings; + settings.writeEntry( path + "/parenMatching", b ); +} + +void Config::setIndentTabSize( int s, const QString &path ) +{ + QSettings settings; + settings.writeEntry( path + "/indentTabSize", s ); +} + +void Config::setIndentIndentSize( int s, const QString &path ) +{ + QSettings settings; + settings.writeEntry( path + "/indentIndentSize", s ); +} + +void Config::setIndentKeepTabs( bool b, const QString &path ) +{ + QSettings settings; + settings.writeEntry( path + "/indentKeepTabs", b ); +} + +void Config::setIndentAutoIndent( bool b, const QString &path ) +{ + QSettings settings; + settings.writeEntry( path + "/indentAutoIndent", b ); +} diff --git a/tools/designer/editor/conf.h b/tools/designer/editor/conf.h new file mode 100644 index 0000000..fe5111f --- /dev/null +++ b/tools/designer/editor/conf.h @@ -0,0 +1,75 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CONF_H +#define CONF_H + +#include +#include +#include + +struct ConfigStyle +{ + QFont font; + QColor color; + + Q_DUMMY_COMPARISON_OPERATOR( ConfigStyle ) +}; + +struct Config +{ + QMap styles; + bool hasCompletion, hasParenMatching, hasWordWrap; + + static QMap defaultStyles(); + static QMap readStyles( const QString &path ); + static void saveStyles( const QMap &styles, const QString &path ); + static bool completion( const QString &path ); + static bool wordWrap( const QString &path ); + static bool parenMatching( const QString &path ); + static int indentTabSize( const QString &path ); + static int indentIndentSize( const QString &path ); + static bool indentKeepTabs( const QString &path ); + static bool indentAutoIndent( const QString &path ); + + static void setCompletion( bool b, const QString &path ); + static void setWordWrap( bool b, const QString &path ); + static void setParenMatching( bool b,const QString &path ); + static void setIndentTabSize( int s, const QString &path ); + static void setIndentIndentSize( int s, const QString &path ); + static void setIndentKeepTabs( bool b, const QString &path ); + static void setIndentAutoIndent( bool b, const QString &path ); + +}; + +#endif diff --git a/tools/designer/editor/editor.cpp b/tools/designer/editor/editor.cpp new file mode 100644 index 0000000..e75f052 --- /dev/null +++ b/tools/designer/editor/editor.cpp @@ -0,0 +1,251 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "editor.h" +#include "parenmatcher.h" +#include +#include +#include "conf.h" +#include +#include +#include + +Editor::Editor( const QString &fn, QWidget *parent, const char *name ) + : QTextEdit( parent, name ), hasError( FALSE ) +{ + document()->setFormatter( new QTextFormatterBreakInWords ); + if ( !fn.isEmpty() ) + load( fn ); + setHScrollBarMode( QScrollView::AlwaysOff ); + setVScrollBarMode( QScrollView::AlwaysOn ); + document()->setUseFormatCollection( FALSE ); + parenMatcher = new ParenMatcher; + connect( this, SIGNAL( cursorPositionChanged( QTextCursor * ) ), + this, SLOT( cursorPosChanged( QTextCursor * ) ) ); + cfg = new Config; + document()->addSelection( Error ); + document()->addSelection( Step ); + document()->setSelectionColor( Error, red ); + document()->setSelectionColor( Step, yellow ); + document()->setInvertSelectionText( Error, FALSE ); + document()->setInvertSelectionText( Step, FALSE ); + document()->addSelection( ParenMatcher::Match ); + document()->addSelection( ParenMatcher::Mismatch ); + document()->setSelectionColor( ParenMatcher::Match, QColor( 204, 232, 195 ) ); + document()->setSelectionColor( ParenMatcher::Mismatch, Qt::magenta ); + document()->setInvertSelectionText( ParenMatcher::Match, FALSE ); + document()->setInvertSelectionText( ParenMatcher::Mismatch, FALSE ); + + accelComment = new QAccel( this ); + accelComment->connectItem( accelComment->insertItem( ALT + Key_C ), + this, SLOT( commentSelection() ) ); + accelUncomment = new QAccel( this ); + accelUncomment->connectItem( accelUncomment->insertItem( ALT + Key_U ), + this, SLOT( uncommentSelection() ) ); + editable = TRUE; +} + +Editor::~Editor() +{ + delete cfg; + delete parenMatcher; +} + +void Editor::cursorPosChanged( QTextCursor *c ) +{ + if ( parenMatcher->match( c ) ) + repaintChanged(); + if ( hasError ) { + emit clearErrorMarker(); + hasError = FALSE; + } +} + +void Editor::load( const QString &fn ) +{ + filename = fn; + QFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) + return; + QCString txt; + txt.resize( f.size() ); + f.readBlock( txt.data(), f.size() ); + QString s( QString::fromLatin1( txt ) ); + setText( s ); +} + +void Editor::save( const QString &fn ) +{ + if ( !filename.isEmpty() ) + filename = fn; +} + +void Editor::configChanged() +{ + document()->invalidate(); + viewport()->repaint( FALSE ); +} + +void Editor::setErrorSelection( int line ) +{ + QTextParagraph *p = document()->paragAt( line ); + if ( !p ) + return; + QTextCursor c( document() ); + c.setParagraph( p ); + c.setIndex( 0 ); + document()->removeSelection( Error ); + document()->setSelectionStart( Error, c ); + c.gotoLineEnd(); + document()->setSelectionEnd( Error, c ); + hasError = TRUE; + viewport()->repaint( FALSE ); +} + +void Editor::setStepSelection( int line ) +{ + QTextParagraph *p = document()->paragAt( line ); + if ( !p ) + return; + QTextCursor c( document() ); + c.setParagraph( p ); + c.setIndex( 0 ); + document()->removeSelection( Step ); + document()->setSelectionStart( Step, c ); + c.gotoLineEnd(); + document()->setSelectionEnd( Step, c ); + viewport()->repaint( FALSE ); +} + +void Editor::clearStepSelection() +{ + document()->removeSelection( Step ); + viewport()->repaint( FALSE ); +} + +void Editor::doChangeInterval() +{ + emit intervalChanged(); + QTextEdit::doChangeInterval(); +} + +void Editor::commentSelection() +{ + QTextParagraph *start = document()->selectionStartCursor( QTextDocument::Standard ).paragraph(); + QTextParagraph *end = document()->selectionEndCursor( QTextDocument::Standard ).paragraph(); + if ( !start || !end ) + start = end = textCursor()->paragraph(); + while ( start ) { + if ( start == end && textCursor()->index() == 0 ) + break; + start->insert( 0, "//" ); + if ( start == end ) + break; + start = start->next(); + } + document()->removeSelection( QTextDocument::Standard ); + repaintChanged(); + setModified( TRUE ); +} + +void Editor::uncommentSelection() +{ + QTextParagraph *start = document()->selectionStartCursor( QTextDocument::Standard ).paragraph(); + QTextParagraph *end = document()->selectionEndCursor( QTextDocument::Standard ).paragraph(); + if ( !start || !end ) + start = end = textCursor()->paragraph(); + while ( start ) { + if ( start == end && textCursor()->index() == 0 ) + break; + while ( start->at( 0 )->c == '/' ) + start->remove( 0, 1 ); + if ( start == end ) + break; + start = start->next(); + } + document()->removeSelection( QTextDocument::Standard ); + repaintChanged(); + setModified( TRUE ); +} + +QPopupMenu *Editor::createPopupMenu( const QPoint &p ) +{ + QPopupMenu *menu = QTextEdit::createPopupMenu( p ); + menu->insertSeparator(); + menu->insertItem( tr( "C&omment Code\tAlt+C" ), this, SLOT( commentSelection() ) ); + menu->insertItem( tr( "Unco&mment Code\tAlt+U" ), this, SLOT( uncommentSelection() ) ); + return menu; +} + +bool Editor::eventFilter( QObject *o, QEvent *e ) +{ + if ( ( e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut ) && + ( o == this || o == viewport() ) ) { + accelUncomment->setEnabled( e->type() == QEvent::FocusIn ); + accelComment->setEnabled( e->type() == QEvent::FocusIn ); + } + return QTextEdit::eventFilter( o, e ); +} + +void Editor::doKeyboardAction( KeyboardAction action ) +{ + if ( !editable ) + return; + QTextEdit::doKeyboardAction( action ); +} + +void Editor::keyPressEvent( QKeyEvent *e ) +{ + if ( editable ) { + QTextEdit::keyPressEvent( e ); + return; + } + + switch ( e->key() ) { + case Key_Left: + case Key_Right: + case Key_Up: + case Key_Down: + case Key_Home: + case Key_End: + case Key_Prior: + case Key_Next: + case Key_Direction_L: + case Key_Direction_R: + QTextEdit::keyPressEvent( e ); + break; + default: + e->accept(); + break; + } +} diff --git a/tools/designer/editor/editor.h b/tools/designer/editor/editor.h new file mode 100644 index 0000000..1364bbb --- /dev/null +++ b/tools/designer/editor/editor.h @@ -0,0 +1,111 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef EDITOR_H +#define EDITOR_H + +#include + +struct Config; +class ParenMatcher; +class EditorCompletion; +class EditorBrowser; +class QAccel; + +class Editor : public QTextEdit +{ + Q_OBJECT + +public: + enum Selection { + Error = 3, + Step = 4 + }; + + Editor( const QString &fn, QWidget *parent, const char *name ); + ~Editor(); + virtual void load( const QString &fn ); + virtual void save( const QString &fn ); + QTextDocument *document() const { return QTextEdit::document(); } + void placeCursor( const QPoint &p, QTextCursor *c ) { QTextEdit::placeCursor( p, c ); } + void setDocument( QTextDocument *doc ) { QTextEdit::setDocument( doc ); } + QTextCursor *textCursor() const { return QTextEdit::textCursor(); } + void repaintChanged() { QTextEdit::repaintChanged(); } + + virtual EditorCompletion *completionManager() { return 0; } + virtual EditorBrowser *browserManager() { return 0; } + virtual void configChanged(); + + Config *config() { return cfg; } + + void setErrorSelection( int line ); + void setStepSelection( int line ); + void clearStepSelection(); + void clearSelections(); + + virtual bool supportsErrors() const { return TRUE; } + virtual bool supportsBreakPoints() const { return TRUE; } + virtual void makeFunctionVisible( QTextParagraph * ) {} + + void drawCursor( bool b ) { QTextEdit::drawCursor( b ); } + + QPopupMenu *createPopupMenu( const QPoint &p ); + bool eventFilter( QObject *o, QEvent *e ); + + void setEditable( bool b ) { editable = b; } + +protected: + void doKeyboardAction( KeyboardAction action ); + void keyPressEvent( QKeyEvent *e ); + +signals: + void clearErrorMarker(); + void intervalChanged(); + +private slots: + void cursorPosChanged( QTextCursor *c ); + void doChangeInterval(); + void commentSelection(); + void uncommentSelection(); + +protected: + ParenMatcher *parenMatcher; + QString filename; + Config *cfg; + bool hasError; + QAccel *accelComment, *accelUncomment; + bool editable; + +}; + +#endif diff --git a/tools/designer/editor/editor.pro b/tools/designer/editor/editor.pro new file mode 100644 index 0000000..dc9235f --- /dev/null +++ b/tools/designer/editor/editor.pro @@ -0,0 +1,40 @@ +TEMPLATE = lib +CONFIG += qt warn_on staticlib +CONFIG -= dll +HEADERS = editor.h \ + parenmatcher.h \ + completion.h \ + viewmanager.h \ + markerwidget.h\ + conf.h \ + browser.h \ + arghintwidget.h \ + cindent.h + +SOURCES = editor.cpp \ + parenmatcher.cpp \ + completion.cpp \ + viewmanager.cpp \ + markerwidget.cpp \ + conf.cpp \ + browser.cpp \ + arghintwidget.cpp \ + cindent.cpp \ + yyindent.cpp + +FORMS = preferences.ui + +TARGET = editor +DESTDIR = ../../../lib +VERSION = 1.0.0 + +INCLUDEPATH += $$QT_SOURCE_TREE/tools/designer/interfaces + +target.path=$$libs.path + +INSTALLS += target + +unix { + QMAKE_CFLAGS += $$QMAKE_CFLAGS_SHLIB + QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_SHLIB +} diff --git a/tools/designer/editor/markerwidget.cpp b/tools/designer/editor/markerwidget.cpp new file mode 100644 index 0000000..cabe39a --- /dev/null +++ b/tools/designer/editor/markerwidget.cpp @@ -0,0 +1,491 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "markerwidget.h" +#include "viewmanager.h" +#include +#include "editor.h" +#include +#include +#include "paragdata.h" + +static const char * error_xpm[] = { +"15 15 35 1", +" c None", +". c #FF0000", +"+ c #F50F0F", +"@ c #BF5F5F", +"# c #FF1010", +"$ c #FF7878", +"% c #FF0A0A", +"& c #FF0606", +"* c #FF1414", +"= c #FFFFFF", +"- c #FFA3A3", +"; c #FF0707", +"> c #FF0202", +", c #FF9898", +"' c #FF8888", +") c #D04747", +"! c #FFA7A7", +"~ c #FF9D9D", +"{ c #FFB1B1", +"] c #FF0C0C", +"^ c #F90A0A", +"/ c #FFB5B5", +"( c #FF0909", +"_ c #A08F8F", +": c #FFACAC", +"< c #FF0303", +"[ c #9F8F8F", +"} c #FB0606", +"| c #9F9090", +"1 c #CE4949", +"2 c #999999", +"3 c #FF1919", +"4 c #F70C0C", +"5 c #A38A8A", +"6 c #B37272", +" .... ", +" ........ ", +" .........+@ ", +" ..#$%..&$*.+ ", +" ..$=-;>,='..) ", +"...%-=!~={]..^ ", +"....;!==/(...._", +"....>~==:<....[", +"...&,=/:=!;..}|", +" ..$={( c #8894C8", +", c #AFBAC4", +"' c #95BFEC", +") c #99CBFF", +"! c #8EC3FF", +"~ c #6D95F0", +"{ c #8792CA", +"] c #9DA7C3", +"^ c #8BA2E3", +"/ c #809AE0", +"( c #8398D1", +"_ c #93A0CC", +": c #ACB3CB", +"< c #B4B9C4", +"[ c #B6BAC4", +"} c #93A4CC", +"| c #82B0F5", +"1 c #8BBCFF", +"2 c #8EC0FF", +"3 c #8FC1FF", +"4 c #6594F4", +"5 c #7381CC", +"6 c #81A7E9", +"7 c #D0F5FF", +"8 c #C1EBFF", +"9 c #AEDAFF", +"0 c #A2D1FC", +"a c #A3C8F3", +"b c #AACAE6", +"c c #B4CFE9", +"d c #ADCCF9", +"e c #84B2FF", +"f c #82B4FF", +"g c #86B7FF", +"h c #88B7FF", +"i c #83B4FF", +"j c #5F8AF3", +"k c #7585C8", +"l c #77A4F3", +"m c #ABDFFF", +"n c #9CCAFF", +"o c #96C7FF", +"p c #97C8FF", +"q c #95C5FF", +"r c #9DCCFF", +"s c #A0CDFF", +"t c #90C0FF", +"u c #82AFFF", +"v c #7FAFFF", +"w c #7DAEFF", +"x c #79AAFF", +"y c #6C9EFF", +"z c #4366EB", +"A c #6894F2", +"B c #93C6FF", +"C c #82B3FF", +"D c #7AABFF", +"E c #73A5FF", +"F c #71A3FF", +"G c #6C9DFF", +"H c #699BFF", +"I c #76A8FF", +"J c #7EB0FF", +"K c #7BADFF", +"L c #74A5FF", +"M c #608BFF", +"N c #3462FF", +"O c #2444E5", +"P c #577AE0", +"Q c #5D90FF", +"R c #4C7AFF", +"S c #3B66FF", +"T c #335CF9", +"U c #365AF1", +"V c #3858E5", +"W c #3959E0", +"X c #416CF9", +"Y c #75A5FF", +"Z c #78A9FF", +"` c #74A4FF", +" . c #6191FF", +".. c #3059FF", +"+. c #1B37F1", +"@. c #6A75C7", +"#. c #828BC1", +"$. c #4358D8", +"%. c #374BDA", +"&. c #4759CA", +"*. c #636CC4", +"=. c #8489C0", +"-. c #9DA1C1", +";. c #A3A6BF", +">. c #7486CB", +",. c #6E98F5", +"'. c #719EFF", +"). c #608DFF", +"!. c #315EFF", +"~. c #1432F4", +"{. c #5C63C8", +"]. c #B1B4B9", +"^. c #B3BABB", +"/. c #ABB4C3", +"(. c #7299E9", +"_. c #5486FF", +":. c #224EFF", +"<. c #1733F2", +"[. c #7079C5", +"}. c #5C7DE9", +"|. c #2450FF", +"1. c #1B39EC", +"2. c #7077C5", +"3. c #3A54E1", +"4. c #1E36EA", +"5. c #858CBF", +"6. c #525FCB", +"7. c #727CBC", +" ", +" . + @ ", +" # $ % & ", +" * = - ; > ", +" , ' ) ! ~ { ", +"] ^ / ( _ : < [ } | 1 2 3 4 5 ", +"6 7 8 9 0 a b c d e f g h i j k ", +"l m n o p q r s t u v u w x y z ", +"A B C D E F G H I J K D L M N O ", +"P Q R S T U V W X Y Z ` ...+.@.", +"#.$.%.&.*.=.-.;.>.,.'.).!.~.{. ", +" ].^. /.(._.:.<.[. ", +" }.|.1.2. ", +" 3.4.5. ", +" 6.7. ", +" "}; + +static const char *stack_frame_xpm[]={ +"16 16 2 1", +". c None", +"# c #00c000", +"................", +".###............", +".#####..........", +".#######........", +".#########......", +".###########....", +".#############..", +".##############.", +".##############.", +".#############..", +".###########....", +".#########......", +".#######........", +".#####..........", +".###............", +"................"}; + +static QPixmap *errorPixmap = 0; +static QPixmap *breakpointPixmap = 0; +static QPixmap *stepPixmap = 0; +static QPixmap *stackFrame = 0; + +MarkerWidget::MarkerWidget( ViewManager *parent, const char*name ) + : QWidget( parent, name, WRepaintNoErase | WStaticContents | WResizeNoErase ), viewManager( parent ) +{ + if ( !errorPixmap ) { + errorPixmap = new QPixmap( error_xpm ); + breakpointPixmap = new QPixmap( breakpoint_xpm ); + stepPixmap = new QPixmap( step_xpm ); + stackFrame = new QPixmap( stack_frame_xpm ); + } +} + +void MarkerWidget::paintEvent( QPaintEvent * ) +{ + buffer.fill( backgroundColor() ); + + QTextParagraph *p = ( (Editor*)viewManager->currentView() )->document()->firstParagraph(); + QPainter painter( &buffer ); + int yOffset = ( (Editor*)viewManager->currentView() )->contentsY(); + while ( p ) { + if ( !p->isVisible() ) { + p = p->next(); + continue; + } + if ( p->rect().y() + p->rect().height() - yOffset < 0 ) { + p = p->next(); + continue; + } + if ( p->rect().y() - yOffset > height() ) + break; + if ( !((p->paragId() + 1) % 10) ) { + painter.save(); + painter.setPen( colorGroup().dark() ); + painter.drawText( 0, p->rect().y() - yOffset, width() - 20, p->rect().height(), + Qt::AlignRight | Qt::AlignTop, QString::number( p->paragId() + 1 ) ); + painter.restore(); + } + ParagData *paragData = (ParagData*)p->extraData(); + if ( paragData ) { + switch ( paragData->marker ) { + case ParagData::Error: + painter.drawPixmap( 3, p->rect().y() + + ( p->rect().height() - errorPixmap->height() ) / 2 - + yOffset, *errorPixmap ); + break; + case ParagData::Breakpoint: + painter.drawPixmap( 3, p->rect().y() + + ( p->rect().height() - breakpointPixmap->height() ) / 2 - + yOffset, *breakpointPixmap ); + break; + default: + break; + } + switch ( paragData->lineState ) { + case ParagData::FunctionStart: + painter.setPen( colorGroup().foreground() ); + painter.setBrush( colorGroup().base() ); + painter.drawLine( width() - 11, p->rect().y() - yOffset, + width() - 11, p->rect().y() + p->rect().height() - yOffset ); + painter.drawRect( width() - 15, p->rect().y() + ( p->rect().height() - 9 ) / 2 - yOffset, 9, 9 ); + painter.drawLine( width() - 13, p->rect().y() + ( p->rect().height() - 9 ) / 2 - yOffset + 4, + width() - 9, p->rect().y() + + ( p->rect().height() - 9 ) / 2 - yOffset + 4 ); + if ( !paragData->functionOpen ) + painter.drawLine( width() - 11, + p->rect().y() + ( p->rect().height() - 9 ) / 2 - yOffset + 2, + width() - 11, + p->rect().y() + + ( p->rect().height() - 9 ) / 2 - yOffset + 6 ); + break; + case ParagData::InFunction: + painter.setPen( colorGroup().foreground() ); + painter.drawLine( width() - 11, p->rect().y() - yOffset, + width() - 11, p->rect().y() + p->rect().height() - yOffset ); + break; + case ParagData::FunctionEnd: + painter.setPen( colorGroup().foreground() ); + painter.drawLine( width() - 11, p->rect().y() - yOffset, + width() - 11, p->rect().y() + p->rect().height() - yOffset ); + painter.drawLine( width() - 11, p->rect().y() + p->rect().height() - yOffset, + width() - 7, p->rect().y() + p->rect().height() - yOffset ); + break; + default: + break; + } + if ( paragData->step ) + painter.drawPixmap( 3, p->rect().y() + + ( p->rect().height() - stepPixmap->height() ) / 2 - + yOffset, *stepPixmap ); + if ( paragData->stackFrame ) + painter.drawPixmap( 3, p->rect().y() + + ( p->rect().height() - stackFrame->height() ) / 2 - + yOffset, *stackFrame ); + } + p = p->next(); + } + painter.end(); + + bitBlt( this, 0, 0, &buffer ); +} + +void MarkerWidget::resizeEvent( QResizeEvent *e ) +{ + buffer.resize( e->size() ); + QWidget::resizeEvent( e ); +} + +void MarkerWidget::mousePressEvent( QMouseEvent *e ) +{ + if ( e->button() != LeftButton ) + return; + bool supports = ( (Editor*)viewManager->currentView() )->supportsBreakPoints(); + QTextParagraph *p = ( (Editor*)viewManager->currentView() )->document()->firstParagraph(); + int yOffset = ( (Editor*)viewManager->currentView() )->contentsY(); + while ( p ) { + if ( e->y() >= p->rect().y() - yOffset && e->y() <= p->rect().y() + p->rect().height() - yOffset ) { + QTextParagraphData *d = p->extraData(); + if ( !d ) + return; + ParagData *data = (ParagData*)d; + if ( supports && ( e->x() < width() - 15 ) ) { + if ( data->marker == ParagData::Breakpoint ) { + data->marker = ParagData::NoMarker; + } else { + bool ok = TRUE; + isBreakpointPossible( ok, ( (Editor*)viewManager->currentView() )->text(), p->paragId() ); + if ( ok ) + data->marker = ParagData::Breakpoint; + else + emit showMessage( tr( "Can't set breakpoint here!" ) ); + } + } else { + if ( data->lineState == ParagData::FunctionStart ) { + if ( data->functionOpen ) + emit collapseFunction( p ); + else + emit expandFunction( p ); + } + } + break; + } + p = p->next(); + } + doRepaint(); + emit markersChanged(); +} + +void MarkerWidget::contextMenuEvent( QContextMenuEvent *e ) +{ + QPopupMenu m( 0, "editor_breakpointsmenu" ); + + int toggleBreakPoint = 0; +// int editBreakpoints = 0; + + QTextParagraph *p = ( (Editor*)viewManager->currentView() )->document()->firstParagraph(); + int yOffset = ( (Editor*)viewManager->currentView() )->contentsY(); + bool supports = ( (Editor*)viewManager->currentView() )->supportsBreakPoints(); + while ( p && supports ) { + if ( e->y() >= p->rect().y() - yOffset && e->y() <= p->rect().y() + p->rect().height() - yOffset ) { + if ( ( (ParagData*)p->extraData() )->marker == ParagData::Breakpoint ) + toggleBreakPoint = m.insertItem( tr( "Clear Breakpoint\tF9" ) ); + else + toggleBreakPoint = m.insertItem( tr( "Set Breakpoint\tF9" ) ); +// editBreakpoints = m.insertItem( tr( "Edit Breakpoints..." ) ); + m.insertSeparator(); + break; + } + p = p->next(); + } + + const int collapseAll = m.insertItem( tr( "Collapse All" ) ); + const int expandAll = m.insertItem( tr( "Expand All" ) ); + const int collapseFunctions = m.insertItem( tr( "Collapse all Functions" ) ); + const int expandFunctions = m.insertItem( tr( "Expand all Functions" ) ); + + int res = m.exec( e->globalPos() ); + if ( res == -1) + return; + + if ( res == collapseAll ) { + emit collapse( TRUE ); + } else if ( res == collapseFunctions ) { + emit collapse( FALSE ); + } else if ( res == expandAll ) { + emit expand( TRUE ); + } else if ( res == expandFunctions ) { + emit expand( FALSE ); + } else if ( res == toggleBreakPoint ) { + if ( ( (ParagData*)p->extraData() )->marker == ParagData::Breakpoint ) { + ( (ParagData*)p->extraData() )->marker = ParagData::NoMarker; + } else { + bool ok; + isBreakpointPossible( ok, ( (Editor*)viewManager->currentView() )->text(), p->paragId() ); + if ( ok ) + ( (ParagData*)p->extraData() )->marker = ParagData::Breakpoint; + else + emit showMessage( tr( "Can't set breakpoint here!" ) ); + } +// } else if ( res == editBreakpoints ) { +// emit editBreakPoints(); + } + doRepaint(); + emit markersChanged(); +} diff --git a/tools/designer/editor/markerwidget.h b/tools/designer/editor/markerwidget.h new file mode 100644 index 0000000..f1d406e --- /dev/null +++ b/tools/designer/editor/markerwidget.h @@ -0,0 +1,75 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef MARKERWIDGET_H +#define MARKERWIDGET_H + +#include +#include + +class ViewManager; +class QTextParagraph; + +class MarkerWidget : public QWidget +{ + Q_OBJECT + +public: + MarkerWidget( ViewManager *parent, const char*name ); + +signals: + void markersChanged(); + void expandFunction( QTextParagraph *p ); + void collapseFunction( QTextParagraph *p ); + void collapse( bool all /*else only functions*/ ); + void expand( bool all /*else only functions*/ ); + void editBreakPoints(); + void isBreakpointPossible( bool &possible, const QString &code, int line ); + void showMessage( const QString &msg ); + +public slots: + void doRepaint() { repaint( FALSE ); } + +protected: + void paintEvent( QPaintEvent *e ); + void resizeEvent( QResizeEvent *e ); + void mousePressEvent( QMouseEvent *e ); + void contextMenuEvent( QContextMenuEvent *e ); + +private: + QPixmap buffer; + ViewManager *viewManager; + +}; + +#endif diff --git a/tools/designer/editor/paragdata.h b/tools/designer/editor/paragdata.h new file mode 100644 index 0000000..64bb050 --- /dev/null +++ b/tools/designer/editor/paragdata.h @@ -0,0 +1,65 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PARAGDATA_H +#define PARAGDATA_H + +#include "parenmatcher.h" +#include + +struct ParagData : public QTextParagraphData +{ +public: + enum MarkerType { NoMarker, Error, Breakpoint }; + enum LineState { FunctionStart, InFunction, FunctionEnd, Invalid }; + + ParagData() : lastLengthForCompletion( -1 ), marker( NoMarker ), + lineState( Invalid ), functionOpen( TRUE ), step( FALSE ), stackFrame( FALSE ) {} + ~ParagData() {} + void join( QTextParagraphData *data ) { + ParagData *d = (ParagData*)data; + if ( marker == NoMarker ) + marker = d->marker; + lineState = d->lineState; + } + ParenList parenList; + int lastLengthForCompletion; + MarkerType marker; + LineState lineState; + bool functionOpen; + bool step; + bool stackFrame; + +}; + +#endif diff --git a/tools/designer/editor/parenmatcher.cpp b/tools/designer/editor/parenmatcher.cpp new file mode 100644 index 0000000..ae7a3b5 --- /dev/null +++ b/tools/designer/editor/parenmatcher.cpp @@ -0,0 +1,215 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "parenmatcher.h" +#include "paragdata.h" + +#include "qtextedit.h" +#include +#include + +ParenMatcher::ParenMatcher() +{ + enabled = TRUE; +} + +bool ParenMatcher::match( QTextCursor *cursor ) +{ + if ( !enabled ) + return FALSE; + bool ret = FALSE; + + QChar c( cursor->paragraph()->at( cursor->index() )->c ); + bool ok1 = FALSE; + bool ok2 = FALSE; + if ( c == '{' || c == '(' || c == '[' ) { + ok1 = checkOpenParen( cursor ); + ret = ok1 || ret; + } else if ( cursor->index() > 0 ) { + c = cursor->paragraph()->at( cursor->index() - 1 )->c; + if ( c == '}' || c == ')' || c == ']' ) { + ok2 = checkClosedParen( cursor ); + ret = ok2 || ret; + } + } + + return ret; +} + +bool ParenMatcher::checkOpenParen( QTextCursor *cursor ) +{ + if ( !cursor->paragraph()->extraData() ) + return FALSE; + ParenList parenList = ( (ParagData*)cursor->paragraph()->extraData() )->parenList; + + Paren openParen, closedParen; + QTextParagraph *closedParenParag = cursor->paragraph(); + + int i = 0; + int ignore = 0; + bool foundOpen = FALSE; + QChar c = cursor->paragraph()->at( cursor->index() )->c; + for (;;) { + if ( !foundOpen ) { + if ( i >= (int)parenList.count() ) + goto bye; + openParen = parenList[ i ]; + if ( openParen.pos != cursor->index() ) { + ++i; + continue; + } else { + foundOpen = TRUE; + ++i; + } + } + + if ( i >= (int)parenList.count() ) { + for (;;) { + closedParenParag = closedParenParag->next(); + if ( !closedParenParag ) + goto bye; + if ( closedParenParag->extraData() && + ( (ParagData*)closedParenParag->extraData() )->parenList.count() > 0 ) { + parenList = ( (ParagData*)closedParenParag->extraData() )->parenList; + break; + } + } + i = 0; + } + + closedParen = parenList[ i ]; + if ( closedParen.type == Paren::Open ) { + ignore++; + ++i; + continue; + } else { + if ( ignore > 0 ) { + ignore--; + ++i; + continue; + } + + int id = Match; + if ( c == '{' && closedParen.chr != '}' || + c == '(' && closedParen.chr != ')' || + c == '[' && closedParen.chr != ']' ) + id = Mismatch; + cursor->document()->setSelectionStart( id, *cursor ); + int tidx = cursor->index(); + QTextParagraph *tstring = cursor->paragraph(); + cursor->setParagraph( closedParenParag ); + cursor->setIndex( closedParen.pos + 1 ); + cursor->document()->setSelectionEnd( id, *cursor ); + cursor->setParagraph( tstring ); + cursor->setIndex( tidx ); + return TRUE; + } + } + + bye: + return FALSE; +} + +bool ParenMatcher::checkClosedParen( QTextCursor *cursor ) +{ + if ( !cursor->paragraph()->extraData() ) + return FALSE; + ParenList parenList = ( (ParagData*)cursor->paragraph()->extraData() )->parenList; + + Paren openParen, closedParen; + QTextParagraph *openParenParag = cursor->paragraph(); + + int i = (int)parenList.count() - 1; + int ignore = 0; + bool foundClosed = FALSE; + QChar c = cursor->paragraph()->at( cursor->index() - 1 )->c; + for (;;) { + if ( !foundClosed ) { + if ( i < 0 ) + goto bye; + closedParen = parenList[ i ]; + if ( closedParen.pos != cursor->index() - 1 ) { + --i; + continue; + } else { + foundClosed = TRUE; + --i; + } + } + + if ( i < 0 ) { + for (;;) { + openParenParag = openParenParag->prev(); + if ( !openParenParag ) + goto bye; + if ( openParenParag->extraData() && + ( (ParagData*)openParenParag->extraData() )->parenList.count() > 0 ) { + parenList = ( (ParagData*)openParenParag->extraData() )->parenList; + break; + } + } + i = (int)parenList.count() - 1; + } + + openParen = parenList[ i ]; + if ( openParen.type == Paren::Closed ) { + ignore++; + --i; + continue; + } else { + if ( ignore > 0 ) { + ignore--; + --i; + continue; + } + + int id = Match; + if ( c == '}' && openParen.chr != '{' || + c == ')' && openParen.chr != '(' || + c == ']' && openParen.chr != '[' ) + id = Mismatch; + cursor->document()->setSelectionStart( id, *cursor ); + int tidx = cursor->index(); + QTextParagraph *tstring = cursor->paragraph(); + cursor->setParagraph( openParenParag ); + cursor->setIndex( openParen.pos ); + cursor->document()->setSelectionEnd( id, *cursor ); + cursor->setParagraph( tstring ); + cursor->setIndex( tidx ); + return TRUE; + } + } + + bye: + return FALSE; +} diff --git a/tools/designer/editor/parenmatcher.h b/tools/designer/editor/parenmatcher.h new file mode 100644 index 0000000..9bb2568 --- /dev/null +++ b/tools/designer/editor/parenmatcher.h @@ -0,0 +1,78 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PARENMATCHER_H +#define PARENMATCHER_H + +#include +#include + +class QTextCursor; + +struct Paren +{ + Paren() : type( Open ), chr( ' ' ), pos( -1 ) {} + Paren( int t, const QChar &c, int p ) : type( (Type)t ), chr( c ), pos( p ) {} + enum Type { Open, Closed }; + Type type; + QChar chr; + int pos; + + Q_DUMMY_COMPARISON_OPERATOR( Paren ) +}; + +typedef QValueList ParenList; + +class ParenMatcher +{ +public: + enum Selection { + Match = 1, + Mismatch + }; + + ParenMatcher(); + + virtual bool match( QTextCursor *c ); + + void setEnabled( bool b ) { enabled = b; } + +private: + bool checkOpenParen( QTextCursor *c ); + bool checkClosedParen( QTextCursor *c ); + + bool enabled; + +}; + +#endif diff --git a/tools/designer/editor/preferences.ui b/tools/designer/editor/preferences.ui new file mode 100644 index 0000000..5dc1d53 --- /dev/null +++ b/tools/designer/editor/preferences.ui @@ -0,0 +1,510 @@ + +PreferencesBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + PreferencesBase + + + + 0 + 0 + 362 + 396 + + + + Form1 + + + + unnamed + + + 6 + + + 6 + + + + GroupBox2 + + + Box + + + Sunken + + + S&yntax Highlighting + + + + unnamed + + + 11 + + + 6 + + + + TextLabel1 + + + &Element: + + + listElements + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + checkBold + + + &Bold + + + + + buttonColor + + + + 1 + 0 + 0 + 0 + + + + ... + + + + + comboFamily + + + true + + + + + TextLabel2 + + + &Family: + + + comboFamily + + + + + checkUnderline + + + &Underline + + + + + spinSize + + + 1 + + + + + checkItalic + + + &Italic + + + + + TextLabel4 + + + Change co&lor: + + + buttonColor + + + + + TextLabel3 + + + &Size: + + + spinSize + + + + + + + + Comment + + + + + Number + + + + + String + + + + + Type + + + + + Keyword + + + + + Preprocessor + + + + + Label + + + + + Standard + + + + listElements + + + + + TextLabel2_2 + + + &Preview: + + + editPreview + + + + + editPreview + + + Some Text + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 0 + + + + + + + + GroupBox3 + + + Optio&ns + + + + unnamed + + + 11 + + + 6 + + + + checkWordWrap + + + &Word Wrap + + + + + checkCompletion + + + Comple&tion + + + + + checkParenMatching + + + Parentheses &Matching + + + + + + + GroupBox3_2 + + + Indentation + + + + unnamed + + + 11 + + + 6 + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + spinTabSize + + + 8 + + + + + TextLabel1_2 + + + Tab Size: + + + + + spinIndentSize + + + 4 + + + + + TextLabel2_3 + + + Indent Size: + + + + + + + checkKeepTabs + + + Keep Tabs + + + true + + + + + checkAutoIndent + + + Auto Indent + + + true + + + + + + + + + spinSize + valueChanged(int) + PreferencesBase + sizeChanged(int) + + + checkBold + toggled(bool) + PreferencesBase + boldChanged(bool) + + + checkItalic + toggled(bool) + PreferencesBase + italicChanged(bool) + + + checkUnderline + toggled(bool) + PreferencesBase + underlineChanged(bool) + + + buttonColor + clicked() + PreferencesBase + colorClicked() + + + comboFamily + activated(const QString&) + PreferencesBase + familyChanged(const QString&) + + + listElements + highlighted(const QString&) + PreferencesBase + elementChanged(const QString&) + + + + listElements + editPreview + comboFamily + spinSize + checkBold + checkItalic + checkUnderline + checkWordWrap + checkCompletion + checkParenMatching + + + qmap.h + conf.h + qpalette.h + qlineedit.h + qpixmap.h + qcombobox.h + qfontdatabase.h + editor.h + qpushbutton.h + qcheckbox.h + qcolordialog.h + qsettings.h + preferences.ui.h + + + QString path; + QMap<QString, ConfigStyle> styles; + ConfigStyle currentStyle; + QString currentElement; + + + init() + destroy() + colorClicked() + reInit() + save() + updatePreview() + boldChanged( bool b ) + elementChanged( const QString & element ) + familyChanged( const QString & f ) + italicChanged( bool b ) + setColorPixmap( const QColor & c ) + setPath( const QString & p ) + sizeChanged( int s ) + underlineChanged( bool b ) + + + diff --git a/tools/designer/editor/preferences.ui.h b/tools/designer/editor/preferences.ui.h new file mode 100644 index 0000000..b175ca8 --- /dev/null +++ b/tools/designer/editor/preferences.ui.h @@ -0,0 +1,181 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +void PreferencesBase::init() +{ + QFontDatabase fdb; + comboFamily->insertStringList( fdb.families() ); + listElements->setCurrentItem( listElements->firstItem() ); + currentElement = ""; +} + +void PreferencesBase::destroy() +{ + +} + +void PreferencesBase::colorClicked() +{ + QColor c = QColorDialog::getColor( currentStyle.color, this, "editor_getcolor_dlg" ); + if ( c.isValid() ) { + currentStyle.color = c; + setColorPixmap( c ); + } +} + +void PreferencesBase::reInit() +{ + styles = Config::readStyles( path ); + currentElement = ""; + elementChanged( "Comment" ); + for ( int i = 0; i < comboFamily->count(); ++i ) { + if ( listElements->text( i ) == "Comment" ) { + listElements->setCurrentItem( i ); + break; + } + } + checkWordWrap->setChecked( Config::wordWrap( path ) ); + checkCompletion->setChecked( Config::completion( path ) ); + checkParenMatching->setChecked( Config::parenMatching( path ) ); + spinTabSize->setValue( Config::indentTabSize( path ) ); + spinIndentSize->setValue( Config::indentIndentSize( path ) ); + checkKeepTabs->setChecked( Config::indentKeepTabs( path ) ); + checkAutoIndent->setChecked( Config::indentAutoIndent( path ) ); +} + +void PreferencesBase::save() +{ + if ( !currentElement.isEmpty() ) { + styles.remove( currentElement ); + styles.insert( currentElement, currentStyle ); + currentElement = ""; + } + + QSettings settings; + Config::saveStyles( styles, path ); + Config::setWordWrap( checkWordWrap->isChecked(), path ); + Config::setCompletion( checkCompletion->isChecked(), path ); + Config::setParenMatching( checkParenMatching->isChecked(), path ); + Config::setIndentTabSize( spinTabSize->value(), path ); + Config::setIndentIndentSize( spinIndentSize->value(), path ); + Config::setIndentKeepTabs( checkKeepTabs->isChecked(), path ); + Config::setIndentAutoIndent( checkAutoIndent->isChecked(), path ); +} + +void PreferencesBase::updatePreview() +{ + editPreview->setFont( currentStyle.font ); + QPalette pal = editPreview->palette(); + pal.setColor( QPalette::Active, QColorGroup::Text, currentStyle.color ); + pal.setColor( QPalette::Active, QColorGroup::Foreground, currentStyle.color ); + editPreview->setPalette( pal ); +} + +void PreferencesBase::boldChanged( bool b ) +{ + currentStyle.font.setBold( b ); + updatePreview(); +} + +void PreferencesBase::elementChanged( const QString &element ) +{ + if ( !currentElement.isEmpty() ) { + styles.remove( currentElement ); + styles.insert( currentElement, currentStyle ); + currentElement = ""; + } + QMap::Iterator it = styles.find( element ); + if ( it == styles.end() ) + return; + ConfigStyle s = *it; + currentStyle = s; + comboFamily->lineEdit()->setText( s.font.family() ); + spinSize->setValue( s.font.pointSize() ); + checkBold->setChecked( s.font.bold() ); + checkItalic->setChecked( s.font.italic() ); + checkUnderline->setChecked( s.font.underline() ); + setColorPixmap( s.color ); + currentElement = element; + updatePreview(); +} + +void PreferencesBase::familyChanged( const QString &f ) +{ + QString oldFamily = currentStyle.font.family(); + currentStyle.font.setFamily( f ); + if ( currentElement == "Standard" ) { + for ( QMap::Iterator it = styles.begin(); it != styles.end(); ++it ) { + if ( (*it).font.family() == oldFamily ) + (*it).font.setFamily( f ); + } + } + updatePreview(); +} + +void PreferencesBase::italicChanged( bool b ) +{ + currentStyle.font.setItalic( b ); + updatePreview(); +} + +void PreferencesBase::setColorPixmap( const QColor &c ) +{ + QPixmap pm( 20, 20 ); + pm.fill( c ); + buttonColor->setPixmap( pm ); + updatePreview(); +} + +void PreferencesBase::setPath( const QString &p ) +{ + path = p; +} + +void PreferencesBase::sizeChanged( int s ) +{ + int oldSize = currentStyle.font.pointSize(); + currentStyle.font.setPointSize( s ); + if ( currentElement == "Standard" ) { + for ( QMap::Iterator it = styles.begin(); it != styles.end(); ++it ) { + if ( (*it).font.pointSize() == oldSize ) + (*it).font.setPointSize( s ); + } + } + updatePreview(); +} + +void PreferencesBase::underlineChanged( bool b ) +{ + currentStyle.font.setUnderline( b ); + updatePreview(); +} diff --git a/tools/designer/editor/viewmanager.cpp b/tools/designer/editor/viewmanager.cpp new file mode 100644 index 0000000..cc6f634 --- /dev/null +++ b/tools/designer/editor/viewmanager.cpp @@ -0,0 +1,276 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "viewmanager.h" +#include "editor.h" +#include "markerwidget.h" +#include +#include +#include "paragdata.h" +#include +#include +#include + +ViewManager::ViewManager( QWidget *parent, const char *name ) + : QWidget( parent, name ), curView( 0 ) +{ + QHBoxLayout *l = new QHBoxLayout( this ); + markerWidget = new MarkerWidget( this, "editor_markerwidget" ); + connect( markerWidget, SIGNAL( markersChanged() ), + this, SIGNAL( markersChanged() ) ); + connect( markerWidget, SIGNAL( collapseFunction( QTextParagraph * ) ), + this, SIGNAL( collapseFunction( QTextParagraph * ) ) ); + connect( markerWidget, SIGNAL( expandFunction( QTextParagraph * ) ), + this, SIGNAL( expandFunction( QTextParagraph * ) ) ); + connect( markerWidget, SIGNAL( collapse( bool ) ), + this, SIGNAL( collapse( bool ) ) ); + connect( markerWidget, SIGNAL( expand( bool ) ), + this, SIGNAL( expand( bool ) ) ); + connect( markerWidget, SIGNAL( editBreakPoints() ), + this, SIGNAL( editBreakPoints() ) ); + connect( markerWidget, SIGNAL( isBreakpointPossible( bool&, const QString &, int ) ), + this, SIGNAL( isBreakpointPossible( bool&, const QString &, int ) ) ); + connect( markerWidget, SIGNAL( showMessage( const QString & ) ), + this, SLOT( showMessage( const QString & ) ) ); + messageTimer = new QTimer( this ); + connect( messageTimer, SIGNAL( timeout() ), this, SLOT( clearStatusBar() ) ); + markerWidget->setFixedWidth( fontMetrics().width( "0000" ) + 20 ); + l->addWidget( markerWidget ); + layout = new QVBoxLayout( l ); +} + +void ViewManager::addView( QWidget *view ) +{ + layout->addWidget( view ); + curView = view; + connect( ( (Editor*)curView )->verticalScrollBar(), SIGNAL( valueChanged( int ) ), + markerWidget, SLOT( doRepaint() ) ); + connect( (Editor*)curView, SIGNAL( textChanged() ), + markerWidget, SLOT( doRepaint() ) ); + connect( (Editor*)curView, SIGNAL( clearErrorMarker() ), + this, SLOT( clearErrorMarker() ) ); + posLabel = new QLabel( this, "editor_poslabel" ); + posLabel->setAlignment( Qt::AlignVCenter | Qt::AlignRight ); + posLabel->setText( " Line: 1 Col: 1" ); + posLabel->setFrameStyle( QFrame::Sunken | QFrame::Panel ); + posLabel->setLineWidth( 1 ); + posLabel->setFixedHeight( posLabel->fontMetrics().height() ); + layout->addWidget( posLabel ); + connect( curView, SIGNAL( cursorPositionChanged( int, int ) ), + this, SLOT( cursorPositionChanged( int, int ) ) ); +} + +QWidget *ViewManager::currentView() const +{ + return curView; +} + +void ViewManager::childEvent( QChildEvent *e ) +{ + if ( e->type() == QEvent::ChildInserted && ::qt_cast(e->child()) ) + addView( (QWidget*)e->child() ); + QWidget::childEvent( e ); +} + +void ViewManager::setError( int line ) +{ + QTextParagraph *p = ( (Editor*)curView )->document()->paragAt( line ); + if ( p ) { + ( (Editor*)curView )->setErrorSelection( line ); + ( (Editor*)curView )->setCursorPosition( line, 0 ); + ( (Editor*)curView )->viewport()->setFocus(); + ( (Editor*)curView )->makeFunctionVisible( p ); + ParagData *paragData = (ParagData*)p->extraData(); + if ( !paragData ) + paragData = new ParagData; + paragData->marker = ParagData::Error; + p->setExtraData( paragData ); + markerWidget->doRepaint(); + } +} + +void ViewManager::setStep( int line ) +{ + QTextParagraph *p = ( (Editor*)curView )->document()->firstParagraph(); + while ( p ) { + if ( p->extraData() ) + ( (ParagData*)p->extraData() )->step = FALSE; + p = p->next(); + } + p = ( (Editor*)curView )->document()->paragAt( line ); + if ( p ) { + ( (Editor*)curView )->setStepSelection( line ); + ( (Editor*)curView )->setCursorPosition( line, 0 ); + ( (Editor*)curView )->viewport()->setFocus(); + ( (Editor*)curView )->makeFunctionVisible( p ); + ParagData *paragData = (ParagData*)p->extraData(); + if ( !paragData ) + paragData = new ParagData; + paragData->step = TRUE; + p->setExtraData( paragData ); + markerWidget->doRepaint(); + } +} + +void ViewManager::clearStep() +{ + ( (Editor*)curView )->clearStepSelection(); + QTextParagraph *p = ( (Editor*)curView )->document()->firstParagraph(); + while ( p ) { + if ( p->extraData() ) + ( (ParagData*)p->extraData() )->step = FALSE; + p = p->next(); + } + markerWidget->doRepaint(); +} + +void ViewManager::setStackFrame( int line ) +{ + QTextParagraph *p = ( (Editor*)curView )->document()->paragAt( line ); + if ( p ) { + ( (Editor*)curView )->sync(); + ( (Editor*)curView )->setCursorPosition( line, 0 ); + ( (Editor*)curView )->ensureCursorVisible(); + ( (Editor*)curView )->viewport()->setFocus(); + ( (Editor*)curView )->makeFunctionVisible( p ); + ParagData *paragData = (ParagData*)p->extraData(); + if ( !paragData ) + paragData = new ParagData; + paragData->stackFrame = TRUE; + p->setExtraData( paragData ); + markerWidget->doRepaint(); + } +} + +void ViewManager::clearStackFrame() +{ + QTextParagraph *p = ( (Editor*)curView )->document()->firstParagraph(); + while ( p ) { + if ( p->extraData() ) { + ( (ParagData*)p->extraData() )->stackFrame = FALSE; + if ( ( (ParagData*)p->extraData() )->marker == ParagData::Error ) + ( (ParagData*)p->extraData() )->marker = ParagData::NoMarker; + } + p = p->next(); + } + markerWidget->doRepaint(); +} + +void ViewManager::resizeEvent( QResizeEvent *e ) +{ + QWidget::resizeEvent( e ); + markerWidget->doRepaint(); +} + +void ViewManager::clearErrorMarker() +{ + QTextParagraph *p = ( (Editor*)curView )->document()->firstParagraph(); + while ( p ) { + if ( p->extraData() ) + ( (ParagData*)p->extraData() )->marker = ParagData::NoMarker; + p = p->next(); + } + markerWidget->doRepaint(); +} + +void ViewManager::setBreakPoints( const QValueList &l ) +{ + QTextParagraph *p = ( (Editor*)curView )->document()->firstParagraph(); + int i = 0; + while ( p ) { + if ( l.find( i ) != l.end() ) { + if ( !p->extraData() ) { + ParagData *data = new ParagData; + p->setExtraData( data ); + } + ParagData *data = (ParagData*)p->extraData(); + data->marker = ParagData::Breakpoint; + } else if ( p->extraData() ) { + ParagData *data = (ParagData*)p->extraData(); + data->marker = ParagData::NoMarker; + } + p = p->next(); + ++i; + } + markerWidget->doRepaint(); +} + +QValueList ViewManager::breakPoints() const +{ + QValueList l; + int i = 0; + QTextParagraph *p = ( (Editor*)curView )->document()->firstParagraph(); + while ( p ) { + if ( p->extraData() && + ( (ParagData*)p->extraData() )->marker == ParagData::Breakpoint ) + l << i; + p = p->next(); + ++i; + } + return l; +} + +void ViewManager::showMarkerWidget( bool b ) +{ + if ( b ) + markerWidget->show(); + else + markerWidget->hide(); +} + +void ViewManager::emitMarkersChanged() +{ + emit markersChanged(); +} + +void ViewManager::cursorPositionChanged( int row, int col ) +{ + posLabel->setText( QString( " Line: %1 Col: %2" ).arg( row + 1 ).arg( col + 1 ) ); +} + +void ViewManager::showMessage( const QString &msg ) +{ + int row; + int col; + ( (QTextEdit*)currentView() )->getCursorPosition( &row, &col ); + posLabel->setText( msg ); + messageTimer->start( 1000, TRUE ); +} + +void ViewManager::clearStatusBar() +{ + int row; + int col; + ( (QTextEdit*)currentView() )->getCursorPosition( &row, &col ); + posLabel->setText( QString( " Line: %1 Col: %2" ).arg( row + 1 ).arg( col + 1 ) ); +} diff --git a/tools/designer/editor/viewmanager.h b/tools/designer/editor/viewmanager.h new file mode 100644 index 0000000..72d9859 --- /dev/null +++ b/tools/designer/editor/viewmanager.h @@ -0,0 +1,100 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef VIEWMANAGER_H +#define VIEWMANAGER_H + +#include +#include + +class QChildEvent; +class MarkerWidget; +class QVBoxLayout; +class QDockArea; +class QTextParagraph; +class QLabel; +class QTimer; + +class ViewManager : public QWidget +{ + Q_OBJECT + +public: + ViewManager( QWidget *parent, const char *name ); + + void addView( QWidget *view ); + QWidget *currentView() const; + void showMarkerWidget( bool ); + + void setError( int line ); + void setStep( int line ); + void setStackFrame( int line ); + void clearStep(); + void clearStackFrame(); + void setBreakPoints( const QValueList &l ); + QValueList breakPoints() const; + + void emitMarkersChanged(); + MarkerWidget *marker_widget() const { return markerWidget; } + +signals: + void markersChanged(); + void expandFunction( QTextParagraph *p ); + void collapseFunction( QTextParagraph *p ); + void collapse( bool all /*else only functions*/ ); + void expand( bool all /*else only functions*/ ); + void editBreakPoints(); + void isBreakpointPossible( bool &possible, const QString &code, int line ); + +protected slots: + void clearErrorMarker(); + void cursorPositionChanged( int row, int col ); + void showMessage( const QString &msg ); + void clearStatusBar(); + +protected: + void childEvent( QChildEvent *e ); + void resizeEvent( QResizeEvent *e ); + +private: + QWidget *curView; + MarkerWidget *markerWidget; + QVBoxLayout *layout; + QDockArea *dockArea; + QLabel *posLabel; + QString extraText; + QTimer *messageTimer; + +}; + +#endif diff --git a/tools/designer/editor/yyindent.cpp b/tools/designer/editor/yyindent.cpp new file mode 100644 index 0000000..df9a78f --- /dev/null +++ b/tools/designer/editor/yyindent.cpp @@ -0,0 +1,1170 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +/* + This file is a self-contained interactive indenter for C++ and Qt + Script. + + The general problem of indenting a C++ program is ill posed. On the + one hand, an indenter has to analyze programs written in a + free-form formal language that is best described in terms of + tokens, not characters, not lines. On the other hand, indentation + applies to lines and white space characters matter, and otherwise + the programs to indent are formally invalid in general, as they are + begin edited. + + The approach taken here works line by line. We receive a program + consisting of N lines or more, and we want to compute the + indentation appropriate for the Nth line. Lines beyond the Nth + lines are of no concern to us, so for simplicity we pretend the + program has exactly N lines and we call the Nth line the "bottom + line". Typically, we have to indent the bottom line when it's still + empty, so we concentrate our analysis on the N - 1 lines that + precede. + + By inspecting the (N - 1)-th line, the (N - 2)-th line, ... + backwards, we determine the kind of the bottom line and indent it + accordingly. + + * The bottom line is a comment line. See + bottomLineStartsInCComment() and + indentWhenBottomLineStartsInCComment(). + * The bottom line is a continuation line. See isContinuationLine() + and indentForContinuationLine(). + * The bottom line is a standalone line. See + indentForStandaloneLine(). + + Certain tokens that influence the indentation, notably braces, are + looked for in the lines. This is done by simple string comparison, + without a real tokenizer. Confusing constructs such as comments and + string literals are removed beforehand. +*/ + +#include + +/* qmake ignore Q_OBJECT */ + +/* + The indenter avoids getting stuck in almost infinite loops by + imposing arbitrary limits on the number of lines it analyzes when + looking for a construct. + + For example, the indenter never considers more than BigRoof lines + backwards when looking for the start of a C-style comment. +*/ +static const int SmallRoof = 40; +static const int BigRoof = 400; + +/* + The indenter supports a few parameters: + + * ppHardwareTabSize is the size of a '\t' in your favorite editor. + * ppIndentSize is the size of an indentation, or software tab + size. + * ppContinuationIndentSize is the extra indent for a continuation + line, when there is nothing to align against on the previous + line. + * ppCommentOffset is the indentation within a C-style comment, + when it cannot be picked up. +*/ + +static int ppHardwareTabSize = 8; +static int ppIndentSize = 4; +static int ppContinuationIndentSize = 8; + +static const int ppCommentOffset = 2; + +void setTabSize( int size ) +{ + ppHardwareTabSize = size; +} + +void setIndentSize( int size ) +{ + ppIndentSize = size; + ppContinuationIndentSize = 2 * size; +} + +static QRegExp *literal = 0; +static QRegExp *label = 0; +static QRegExp *inlineCComment = 0; +static QRegExp *braceX = 0; +static QRegExp *iflikeKeyword = 0; + +/* + Returns the first non-space character in the string t, or + QChar::null if the string is made only of white space. +*/ +static QChar firstNonWhiteSpace( const QString& t ) +{ + int i = 0; + while ( i < (int) t.length() ) { + if ( !t[i].isSpace() ) + return t[i]; + i++; + } + return QChar::null; +} + +/* + Returns TRUE if string t is made only of white space; otherwise + returns FALSE. +*/ +static bool isOnlyWhiteSpace( const QString& t ) +{ + return firstNonWhiteSpace( t ).isNull(); +} + +/* + Assuming string t is a line, returns the column number of a given + index. Column numbers and index are identical for strings that don't + contain '\t's. +*/ +int columnForIndex( const QString& t, int index ) +{ + int col = 0; + if ( index > (int) t.length() ) + index = t.length(); + + for ( int i = 0; i < index; i++ ) { + if ( t[i] == QChar('\t') ) { + col = ( (col / ppHardwareTabSize) + 1 ) * ppHardwareTabSize; + } else { + col++; + } + } + return col; +} + +/* + Returns the indentation size of string t. +*/ +int indentOfLine( const QString& t ) +{ + return columnForIndex( t, t.find(firstNonWhiteSpace(t)) ); +} + +/* + Replaces t[k] by ch, unless t[k] is '\t'. Tab characters are better + left alone since they break the "index equals column" rule. No + provisions are taken against '\n' or '\r', which shouldn't occur in + t anyway. +*/ +static inline void eraseChar( QString& t, int k, QChar ch ) +{ + if ( t[k] != '\t' ) + t[k] = ch; +} + +/* + Removes some nefast constructs from a code line and returns the + resulting line. +*/ +static QString trimmedCodeLine( const QString& t ) +{ + QString trimmed = t; + int k; + + /* + Replace character and string literals by X's, since they may + contain confusing characters (such as '{' and ';'). "Hello!" is + replaced by XXXXXXXX. The literals are rigourously of the same + length before and after; otherwise, we would break alignment of + continuation lines. + */ + k = 0; + while ( (k = trimmed.find(*literal, k)) != -1 ) { + for ( int i = 0; i < literal->matchedLength(); i++ ) + eraseChar( trimmed, k + i, 'X' ); + k += literal->matchedLength(); + } + + /* + Replace inline C-style comments by spaces. Other comments are + handled elsewhere. + */ + k = 0; + while ( (k = trimmed.find(*inlineCComment, k)) != -1 ) { + for ( int i = 0; i < inlineCComment->matchedLength(); i++ ) + eraseChar( trimmed, k + i, ' ' ); + k += inlineCComment->matchedLength(); + } + + /* + Replace goto and switch labels by whitespace, but be careful + with this case: + + foo1: bar1; + bar2; + */ + while ( trimmed.findRev(':') != -1 && trimmed.find(*label) != -1 ) { + QString cap1 = label->cap( 1 ); + int pos1 = label->pos( 1 ); + int stop = cap1.length(); + + if ( pos1 + stop < (int) trimmed.length() && ppIndentSize < stop ) + stop = ppIndentSize; + + int i = 0; + while ( i < stop ) { + eraseChar( trimmed, pos1 + i, ' ' ); + i++; + } + while ( i < (int) cap1.length() ) { + eraseChar( trimmed, pos1 + i, ';' ); + i++; + } + } + + /* + Remove C++-style comments. + */ + k = trimmed.find( "//" ); + if ( k != -1 ) + trimmed.truncate( k ); + + return trimmed; +} + +/* + Returns '(' if the last parenthesis is opening, ')' if it is + closing, and QChar::null if there are no parentheses in t. +*/ +static inline QChar lastParen( const QString& t ) +{ + int i = t.length(); + while ( i > 0 ) { + i--; + if ( t[i] == QChar('(') || t[i] == QChar(')') ) + return t[i]; + } + return QChar::null; +} + +/* + Returns TRUE if typedIn the same as okayCh or is null; otherwise + returns FALSE. +*/ +static inline bool okay( QChar typedIn, QChar okayCh ) +{ + return typedIn == QChar::null || typedIn == okayCh; +} + +/* + The "linizer" is a group of functions and variables to iterate + through the source code of the program to indent. The program is + given as a list of strings, with the bottom line being the line to + indent. The actual program might contain extra lines, but those are + uninteresting and not passed over to us. +*/ + +struct LinizerState +{ + QString line; + int braceDepth; + bool leftBraceFollows; + + QStringList::ConstIterator iter; + bool inCComment; + bool pendingRightBrace; +}; + +static QStringList *yyProgram = 0; +static LinizerState *yyLinizerState = 0; + +// shorthands +static const QString *yyLine = 0; +static const int *yyBraceDepth = 0; +static const bool *yyLeftBraceFollows = 0; + +/* + Saves and restores the state of the global linizer. This enables + backtracking. +*/ +#define YY_SAVE() \ + LinizerState savedState = *yyLinizerState +#define YY_RESTORE() \ + *yyLinizerState = savedState + +/* + Advances to the previous line in yyProgram and update yyLine + accordingly. yyLine is cleaned from comments and other damageable + constructs. Empty lines are skipped. +*/ +static bool readLine() +{ + int k; + + yyLinizerState->leftBraceFollows = + ( firstNonWhiteSpace(yyLinizerState->line) == QChar('{') ); + + do { + if ( yyLinizerState->iter == yyProgram->begin() ) { + yyLinizerState->line = QString::null; + return FALSE; + } + + --yyLinizerState->iter; + yyLinizerState->line = *yyLinizerState->iter; + + yyLinizerState->line = trimmedCodeLine( yyLinizerState->line ); + + /* + Remove C-style comments that span multiple lines. If the + bottom line starts in a C-style comment, we are not aware + of that and eventually yyLine will contain a slash-aster. + + Notice that both if's can be executed, since + yyLinizerState->inCComment is potentially set to FALSE in + the first if. The order of the if's is also important. + */ + + if ( yyLinizerState->inCComment ) { + QString slashAster( "/*" ); + + k = yyLinizerState->line.find( slashAster ); + if ( k == -1 ) { + yyLinizerState->line = QString::null; + } else { + yyLinizerState->line.truncate( k ); + yyLinizerState->inCComment = FALSE; + } + } + + if ( !yyLinizerState->inCComment ) { + QString asterSlash( "*/" ); + + k = yyLinizerState->line.find( asterSlash ); + if ( k != -1 ) { + for ( int i = 0; i < k + 2; i++ ) + eraseChar( yyLinizerState->line, i, ' ' ); + yyLinizerState->inCComment = TRUE; + } + } + + /* + Remove preprocessor directives. + */ + k = 0; + while ( k < (int) yyLinizerState->line.length() ) { + QChar ch = yyLinizerState->line[k]; + if ( ch == QChar('#') ) { + yyLinizerState->line = QString::null; + } else if ( !ch.isSpace() ) { + break; + } + k++; + } + + /* + Remove trailing spaces. + */ + k = yyLinizerState->line.length(); + while ( k > 0 && yyLinizerState->line[k - 1].isSpace() ) + k--; + yyLinizerState->line.truncate( k ); + + /* + '}' increment the brace depth and '{' decrements it and not + the other way around, as we are parsing backwards. + */ + yyLinizerState->braceDepth += + yyLinizerState->line.contains( '}' ) - + yyLinizerState->line.contains( '{' ); + + /* + We use a dirty trick for + + } else ... + + We don't count the '}' yet, so that it's more or less + equivalent to the friendly construct + + } + else ... + */ + if ( yyLinizerState->pendingRightBrace ) + yyLinizerState->braceDepth++; + yyLinizerState->pendingRightBrace = + ( yyLinizerState->line.find(*braceX) == 0 ); + if ( yyLinizerState->pendingRightBrace ) + yyLinizerState->braceDepth--; + } while ( yyLinizerState->line.isEmpty() ); + + return TRUE; +} + +/* + Resets the linizer to its initial state, with yyLine containing the + line above the bottom line of the program. +*/ +static void startLinizer() +{ + yyLinizerState->braceDepth = 0; + yyLinizerState->inCComment = FALSE; + yyLinizerState->pendingRightBrace = FALSE; + + yyLine = &yyLinizerState->line; + yyBraceDepth = &yyLinizerState->braceDepth; + yyLeftBraceFollows = &yyLinizerState->leftBraceFollows; + + yyLinizerState->iter = yyProgram->end(); + --yyLinizerState->iter; + yyLinizerState->line = *yyLinizerState->iter; + readLine(); +} + +/* + Returns TRUE if the start of the bottom line of yyProgram (and + potentially the whole line) is part of a C-style comment; otherwise + returns FALSE. +*/ +static bool bottomLineStartsInCComment() +{ + QString slashAster( "/*" ); + QString asterSlash( "*/" ); + + /* + We could use the linizer here, but that would slow us down + terribly. We are better to trim only the code lines we need. + */ + QStringList::ConstIterator p = yyProgram->end(); + --p; // skip bottom line + + for ( int i = 0; i < BigRoof; i++ ) { + if ( p == yyProgram->begin() ) + return FALSE; + --p; + + if ( (*p).find(slashAster) != -1 || (*p).find(asterSlash) != -1 ) { + QString trimmed = trimmedCodeLine( *p ); + + if ( trimmed.find(slashAster) != -1 ) { + return TRUE; + } else if ( trimmed.find(asterSlash) != -1 ) { + return FALSE; + } + } + } + return FALSE; +} + +/* + Returns the recommended indent for the bottom line of yyProgram + assuming that it starts in a C-style comment, a condition that is + tested elsewhere. + + Essentially, we're trying to align against some text on the previous + line. +*/ +static int indentWhenBottomLineStartsInCComment() +{ + int k = yyLine->findRev( "/*" ); + if ( k == -1 ) { + /* + We found a normal text line in a comment. Align the + bottom line with the text on this line. + */ + return indentOfLine( *yyLine ); + } else { + /* + The C-style comment starts on this line. If there is + text on the same line, align with it. Otherwise, align + with the slash-aster plus a given offset. + */ + int indent = columnForIndex( *yyLine, k ); + k += 2; + while ( k < (int) yyLine->length() ) { + if ( !(*yyLine)[k].isSpace() ) + return columnForIndex( *yyLine, k ); + k++; + } + return indent + ppCommentOffset; + } +} + +/* + A function called match...() modifies the linizer state. If it + returns TRUE, yyLine is the top line of the matched construct; + otherwise, the linizer is left in an unknown state. + + A function called is...() keeps the linizer state intact. +*/ + +/* + Returns TRUE if the current line (and upwards) forms a braceless + control statement; otherwise returns FALSE. + + The first line of the following example is a "braceless control + statement": + + if ( x ) + y; +*/ +static bool matchBracelessControlStatement() +{ + int delimDepth = 0; + + if ( yyLine->endsWith("else") ) + return TRUE; + + if ( !yyLine->endsWith(")") ) + return FALSE; + + for ( int i = 0; i < SmallRoof; i++ ) { + int j = yyLine->length(); + while ( j > 0 ) { + j--; + QChar ch = (*yyLine)[j]; + + switch ( ch.unicode() ) { + case ')': + delimDepth++; + break; + case '(': + delimDepth--; + if ( delimDepth == 0 ) { + if ( yyLine->find(*iflikeKeyword) != -1 ) { + /* + We have + + if ( x ) + y + + "if ( x )" is not part of the statement + "y". + */ + return TRUE; + } + } + if ( delimDepth == -1 ) { + /* + We have + + if ( (1 + + 2) + + and not + + if ( 1 + + 2 ) + */ + return FALSE; + } + break; + case '{': + case '}': + case ';': + /* + We met a statement separator, but not where we + expected it. What follows is probably a weird + continuation line. Be careful with ';' in for, + though. + */ + if ( ch != QChar(';') || delimDepth == 0 ) + return FALSE; + } + } + + if ( !readLine() ) + break; + } + return FALSE; +} + +/* + Returns TRUE if yyLine is an unfinished line; otherwise returns + FALSE. + + In many places we'll use the terms "standalone line", "unfinished + line" and "continuation line". The meaning of these should be + evident from this code example: + + a = b; // standalone line + c = d + // unfinished line + e + // unfinished continuation line + f + // unfinished continuation line + g; // continuation line +*/ +static bool isUnfinishedLine() +{ + bool unf = FALSE; + + YY_SAVE(); + + if ( yyLine->isEmpty() ) + return FALSE; + + QChar lastCh = (*yyLine)[(int) yyLine->length() - 1]; + if ( QString("{};").find(lastCh) == -1 && !yyLine->endsWith("...") ) { + /* + It doesn't end with ';' or similar. If it's neither + "Q_OBJECT" nor "if ( x )", it must be an unfinished line. + */ + unf = ( yyLine->contains("Q_OBJECT") == 0 && + !matchBracelessControlStatement() ); + } else if ( lastCh == QChar(';') ) { + if ( lastParen(*yyLine) == QChar('(') ) { + /* + Exception: + + for ( int i = 1; i < 10; + */ + unf = TRUE; + } else if ( readLine() && yyLine->endsWith(";") && + lastParen(*yyLine) == QChar('(') ) { + /* + Exception: + + for ( int i = 1; + i < 10; + */ + unf = TRUE; + } + } + + YY_RESTORE(); + return unf; +} + +/* + Returns TRUE if yyLine is a continuation line; otherwise returns + FALSE. +*/ +static bool isContinuationLine() +{ + bool cont = FALSE; + + YY_SAVE(); + if ( readLine() ) + cont = isUnfinishedLine(); + YY_RESTORE(); + return cont; +} + +/* + Returns the recommended indent for the bottom line of yyProgram, + assuming it's a continuation line. + + We're trying to align the continuation line against some parenthesis + or other bracked left opened on a previous line, or some interesting + operator such as '='. +*/ +static int indentForContinuationLine() +{ + int braceDepth = 0; + int delimDepth = 0; + + bool leftBraceFollowed = *yyLeftBraceFollows; + + for ( int i = 0; i < SmallRoof; i++ ) { + int hook = -1; + + int j = yyLine->length(); + while ( j > 0 && hook < 0 ) { + j--; + QChar ch = (*yyLine)[j]; + + switch ( ch.unicode() ) { + case ')': + case ']': + delimDepth++; + break; + case '}': + braceDepth++; + break; + case '(': + case '[': + delimDepth--; + /* + An unclosed delimiter is a good place to align at, + at least for some styles (including Trolltech's). + */ + if ( delimDepth == -1 ) + hook = j; + break; + case '{': + braceDepth--; + /* + A left brace followed by other stuff on the same + line is typically for an enum or an initializer. + Such a brace must be treated just like the other + delimiters. + */ + if ( braceDepth == -1 ) { + if ( j < (int) yyLine->length() - 1 ) { + hook = j; + } else { + return 0; // shouldn't happen + } + } + break; + case '=': + /* + An equal sign is a very natural alignment hook + because it's usually the operator with the lowest + precedence in statements it appears in. Case in + point: + + int x = 1 + + 2; + + However, we have to beware of constructs such as + default arguments and explicit enum constant + values: + + void foo( int x = 0, + int y = 0 ); + + And not + + void foo( int x = 0, + int y = 0 ); + + These constructs are caracterized by a ',' at the + end of the unfinished lines or by unbalanced + parentheses. + */ + if ( QString("!=<>").find((*yyLine)[j - 1]) == -1 && + (*yyLine)[j + 1] != '=' ) { + if ( braceDepth == 0 && delimDepth == 0 && + j < (int) yyLine->length() - 1 && + !yyLine->endsWith(",") && + (yyLine->contains('(') == yyLine->contains(')')) ) + hook = j; + } + } + } + + if ( hook >= 0 ) { + /* + Yes, we have a delimiter or an operator to align + against! We don't really align against it, but rather + against the following token, if any. In this example, + the following token is "11": + + int x = ( 11 + + 2 ); + + If there is no such token, we use a continuation indent: + + static QRegExp foo( QString( + "foo foo foo foo foo foo foo foo foo") ); + */ + hook++; + while ( hook < (int) yyLine->length() ) { + if ( !(*yyLine)[hook].isSpace() ) + return columnForIndex( *yyLine, hook ); + hook++; + } + return indentOfLine( *yyLine ) + ppContinuationIndentSize; + } + + if ( braceDepth != 0 ) + break; + + /* + The line's delimiters are balanced. It looks like a + continuation line or something. + */ + if ( delimDepth == 0 ) { + if ( leftBraceFollowed ) { + /* + We have + + int main() + { + + or + + Bar::Bar() + : Foo( x ) + { + + The "{" should be flush left. + */ + if ( !isContinuationLine() ) + return indentOfLine( *yyLine ); + } else if ( isContinuationLine() || yyLine->endsWith(",") ) { + /* + We have + + x = a + + b + + c; + + or + + int t[] = { + 1, 2, 3, + 4, 5, 6 + + The "c;" should fall right under the "b +", and the + "4, 5, 6" right under the "1, 2, 3,". + */ + return indentOfLine( *yyLine ); + } else { + /* + We have + + stream << 1 + + 2; + + We could, but we don't, try to analyze which + operator has precedence over which and so on, to + obtain the excellent result + + stream << 1 + + 2; + + We do have a special trick above for the assignment + operator above, though. + */ + return indentOfLine( *yyLine ) + ppContinuationIndentSize; + } + } + + if ( !readLine() ) + break; + } + return 0; +} + +/* + Returns the recommended indent for the bottom line of yyProgram if + that line is standalone (or should be indented likewise). + + Indenting a standalone line is tricky, mostly because of braceless + control statements. Grossly, we are looking backwards for a special + line, a "hook line", that we can use as a starting point to indent, + and then modify the indentation level according to the braces met + along the way to that hook. + + Let's consider a few examples. In all cases, we want to indent the + bottom line. + + Example 1: + + x = 1; + y = 2; + + The hook line is "x = 1;". We met 0 opening braces and 0 closing + braces. Therefore, "y = 2;" inherits the indent of "x = 1;". + + Example 2: + + if ( x ) { + y; + + The hook line is "if ( x ) {". No matter what precedes it, "y;" has + to be indented one level deeper than the hook line, since we met one + opening brace along the way. + + Example 3: + + if ( a ) + while ( b ) { + c; + } + d; + + To indent "d;" correctly, we have to go as far as the "if ( a )". + Compare with + + if ( a ) { + while ( b ) { + c; + } + d; + + Still, we're striving to go back as little as possible to accomodate + people with irregular indentation schemes. A hook line near at hand + is much more reliable than a remote one. +*/ +static int indentForStandaloneLine() +{ + for ( int i = 0; i < SmallRoof; i++ ) { + if ( !*yyLeftBraceFollows ) { + YY_SAVE(); + + if ( matchBracelessControlStatement() ) { + /* + The situation is this, and we want to indent "z;": + + if ( x && + y ) + z; + + yyLine is "if ( x &&". + */ + return indentOfLine( *yyLine ) + ppIndentSize; + } + YY_RESTORE(); + } + + if ( yyLine->endsWith(";") || yyLine->contains('{') > 0 ) { + /* + The situation is possibly this, and we want to indent + "z;": + + while ( x ) + y; + z; + + We return the indent of "while ( x )". In place of "y;", + any arbitrarily complex compound statement can appear. + */ + + if ( *yyBraceDepth > 0 ) { + do { + if ( !readLine() ) + break; + } while ( *yyBraceDepth > 0 ); + } + + LinizerState hookState; + + while ( isContinuationLine() ) + readLine(); + hookState = *yyLinizerState; + + readLine(); + if ( *yyBraceDepth <= 0 ) { + do { + if ( !matchBracelessControlStatement() ) + break; + hookState = *yyLinizerState; + } while ( readLine() ); + } + + *yyLinizerState = hookState; + + while ( isContinuationLine() ) + readLine(); + + /* + Never trust lines containing only '{' or '}', as some + people (Richard M. Stallman) format them weirdly. + */ + if ( yyLine->stripWhiteSpace().length() > 1 ) + return indentOfLine( *yyLine ) - *yyBraceDepth * ppIndentSize; + } + + if ( !readLine() ) + return -*yyBraceDepth * ppIndentSize; + } + return 0; +} + +/* + Constructs global variables used by the indenter. +*/ +static void initializeIndenter() +{ + literal = new QRegExp( "([\"'])(?:\\\\.|[^\\\\])*\\1" ); + literal->setMinimal( TRUE ); + label = new QRegExp( + "^\\s*((?:case\\b([^:]|::)+|[a-zA-Z_0-9]+)(?:\\s+slots)?:)(?!:)" ); + inlineCComment = new QRegExp( "/\\*.*\\*/" ); + inlineCComment->setMinimal( TRUE ); + braceX = new QRegExp( "^\\s*\\}\\s*(?:else|catch)\\b" ); + iflikeKeyword = new QRegExp( "\\b(?:catch|do|for|if|while)\\b" ); + + yyLinizerState = new LinizerState; +} + +/* + Destroys global variables used by the indenter. +*/ +static void terminateIndenter() +{ + delete literal; + delete label; + delete inlineCComment; + delete braceX; + delete iflikeKeyword; + delete yyLinizerState; +} + +/* + Returns the recommended indent for the bottom line of program. + Unless null, typedIn stores the character of yyProgram that + triggered reindentation. + + This function works better if typedIn is set properly; it is + slightly more conservative if typedIn is completely wild, and + slighly more liberal if typedIn is always null. The user might be + annoyed by the liberal behavior. +*/ +int indentForBottomLine( const QStringList& program, QChar typedIn ) +{ + if ( program.isEmpty() ) + return 0; + + initializeIndenter(); + + yyProgram = new QStringList( program ); + startLinizer(); + + const QString& bottomLine = program.last(); + QChar firstCh = firstNonWhiteSpace( bottomLine ); + int indent; + + if ( bottomLineStartsInCComment() ) { + /* + The bottom line starts in a C-style comment. Indent it + smartly, unless the user has already played around with it, + in which case it's better to leave her stuff alone. + */ + if ( isOnlyWhiteSpace(bottomLine) ) { + indent = indentWhenBottomLineStartsInCComment(); + } else { + indent = indentOfLine( bottomLine ); + } + } else if ( okay(typedIn, '#') && firstCh == QChar('#') ) { + /* + Preprocessor directives go flush left. + */ + indent = 0; + } else { + if ( isUnfinishedLine() ) { + indent = indentForContinuationLine(); + } else { + indent = indentForStandaloneLine(); + } + + if ( okay(typedIn, '}') && firstCh == QChar('}') ) { + /* + A closing brace is one level more to the left than the + code it follows. + */ + indent -= ppIndentSize; + } else if ( okay(typedIn, ':') ) { + QRegExp caseLabel( + "\\s*(?:case\\b(?:[^:]|::)+" + "|(?:public|protected|private|signals|default)(?:\\s+slots)?\\s*" + ")?:.*" ); + + if ( caseLabel.exactMatch(bottomLine) ) { + /* + Move a case label (or the ':' in front of a + constructor initialization list) one level to the + left, but only if the user did not play around with + it yet. Some users have exotic tastes in the + matter, and most users probably are not patient + enough to wait for the final ':' to format their + code properly. + + We don't attempt the same for goto labels, as the + user is probably the middle of "foo::bar". (Who + uses goto, anyway?) + */ + if ( indentOfLine(bottomLine) <= indent ) + indent -= ppIndentSize; + else + indent = indentOfLine( bottomLine ); + } + } + } + delete yyProgram; + terminateIndenter(); + return QMAX( 0, indent ); +} + +#ifdef Q_TEST_YYINDENT +/* + Test driver. +*/ + +#include +#include + +#include + +static QString fileContents( const QString& fileName ) +{ + QFile f( fileName ); + if ( !f.open(IO_ReadOnly) ) { + qWarning( "yyindent error: Cannot open file '%s' for reading: %s", + fileName.latin1(), strerror(errno) ); + return QString::null; + } + + QTextStream t( &f ); + QString contents = t.read(); + f.close(); + if ( contents.isEmpty() ) + qWarning( "yyindent error: File '%s' is empty", fileName.latin1() ); + return contents; +} + +int main( int argc, char **argv ) +{ + if ( argc != 2 ) { + qWarning( "usage: yyindent file.cpp" ); + return 1; + } + + QString code = fileContents( argv[1] ); + QStringList program = QStringList::split( '\n', code, TRUE ); + QStringList p; + QString out; + + while ( !program.isEmpty() && program.last().stripWhiteSpace().isEmpty() ) + program.remove( program.fromLast() ); + + QStringList::ConstIterator line = program.begin(); + while ( line != program.end() ) { + p.push_back( *line ); + QChar typedIn = firstNonWhiteSpace( *line ); + if ( p.last().endsWith(":") ) + typedIn = ':'; + + int indent = indentForBottomLine( p, typedIn ); + + if ( !(*line).stripWhiteSpace().isEmpty() ) { + for ( int j = 0; j < indent; j++ ) + out += " "; + out += (*line).stripWhiteSpace(); + } + out += "\n"; + ++line; + } + + while ( out.endsWith("\n") ) + out.truncate( out.length() - 1 ); + + printf( "%s\n", out.latin1() ); + return 0; +} +#endif diff --git a/tools/designer/examples/addressbook/addressbook.pro b/tools/designer/examples/addressbook/addressbook.pro new file mode 100644 index 0000000..70b805a --- /dev/null +++ b/tools/designer/examples/addressbook/addressbook.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += qt warn_on release +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj +} + +SOURCES += main.cpp +FORMS = addressbook.ui addressdetails.ui search.ui +IMAGES = images/filenew.png images/fileopen.png images/filesave.png images/searchfind.png images/editcut.png +DBFILE = addressbook.db diff --git a/tools/designer/examples/addressbook/addressbook.ui b/tools/designer/examples/addressbook/addressbook.ui new file mode 100644 index 0000000..54a4303 --- /dev/null +++ b/tools/designer/examples/addressbook/addressbook.ui @@ -0,0 +1,324 @@ + +AddressBook + + + AddressBook + + + + 0 + 0 + 600 + 480 + + + + Address Book + + + + unnamed + + + 11 + + + 6 + + + + + Last Name + + + true + + + true + + + + + First Name + + + true + + + true + + + + + Phone Number + + + true + + + true + + + + + Street + + + true + + + true + + + + + City + + + true + + + true + + + + + Country + + + true + + + true + + + + + Zip Code + + + true + + + true + + + + addressView + + + Extended + + + true + + + + + + + menubar + + + + + + + + + + + + + + + + + + + toolBar + + + Tools + + + + + + + + + + + + + fileNewAction + + + filenew.png + + + New + + + &New + + + 4194382 + + + + + fileOpenAction + + + fileopen.png + + + Open + + + &Open... + + + 4194383 + + + + + fileSaveAction + + + filesave.png + + + Save + + + &Save + + + 4194387 + + + + + fileSaveAsAction + + + Save As + + + Save &As... + + + 0 + + + + + fileExitAction + + + Exit + + + E&xit + + + 0 + + + + + editFindAction + + + searchfind.png + + + Find + + + &Find... + + + 4194374 + + + + + actionDeleteAddress + + + editcut.png + + + Delete + + + + + + fileNewAction + activated() + AddressBook + fileNew() + + + fileOpenAction + activated() + AddressBook + fileOpen() + + + fileSaveAction + activated() + AddressBook + fileSave() + + + fileSaveAsAction + activated() + AddressBook + fileSaveAs() + + + fileExitAction + activated() + AddressBook + fileExit() + + + editFindAction + activated() + AddressBook + editFind() + + + actionDeleteAddress + activated() + AddressBook + deleteAddress() + + + + addressbook.ui.h + + + QString currentFileName; + + + fileNew() + insertAddress( const QString & firstName, const QString & lastName, const QString & phoneNumber, const QString & street, const QString & city, const QString & country, const QString & zipCode ) + deleteAddress() + fileOpen() + fileSave() + fileSaveAs() + fileExit() + editFind() + searchAddress( const QString & expr ) + + + + diff --git a/tools/designer/examples/addressbook/addressbook.ui.h b/tools/designer/examples/addressbook/addressbook.ui.h new file mode 100644 index 0000000..0d4bd88 --- /dev/null +++ b/tools/designer/examples/addressbook/addressbook.ui.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +#include "addressdetails.h" +#include "search.h" +#include +#include +#include +#include + +void AddressBook::fileNew() +{ + AddressDetails dia( this, 0, TRUE ); + connect( &dia, SIGNAL( newAddress( const QString &, + const QString &, + const QString &, + const QString &, + const QString &, + const QString &, + const QString & ) ), + this, SLOT( insertAddress( const QString &, + const QString &, + const QString &, + const QString &, + const QString &, + const QString &, + const QString & ) ) ); + dia.exec(); +} + +void AddressBook::insertAddress( const QString &firstName, + const QString &lastName, + const QString &phoneNumber, + const QString &street, + const QString &city, + const QString &country, + const QString &zipCode ) +{ + QListViewItem *i = new QListViewItem( addressView ); + i->setText( 0, firstName ); + i->setText( 1, lastName ); + i->setText( 2, phoneNumber ); + i->setText( 3, street ); + i->setText( 4, city ); + i->setText( 5, country ); + i->setText( 6, zipCode ); +} + +void AddressBook::deleteAddress() +{ + QListViewItemIterator it( addressView ); + while ( it.current() ) { + QListViewItem *i = it.current(); + ++it; + if ( i->isSelected() ) + delete i; + } +} + +void AddressBook::fileOpen() +{ + addressView->clear(); + QString fn = QFileDialog::getOpenFileName(); + if ( fn.isEmpty() ) + return; + currentFileName = fn; + QFile f( currentFileName ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + + while ( !ts.eof() ) { + QListViewItem *item = new QListViewItem( addressView ); + for ( int i = 0; i < 7; ++i ) + item->setText( i, ts.readLine() ); + } + +} + +void AddressBook::fileSave() +{ + if ( currentFileName.isEmpty() ) + fileSaveAs(); + QFile f( currentFileName ); + if ( !f.open( IO_WriteOnly ) ) + return; + QTextStream ts( &f ); + + QListViewItemIterator it( addressView ); + while ( it.current() ) { + for ( int i = 0; i < 7; ++i ) + ts << it.current()->text( i ) << endl; + ++it; + } + + f.close(); +} + +void AddressBook::fileSaveAs() +{ + QString fn = QFileDialog::getSaveFileName(); + if ( fn.isEmpty() ) + return; + currentFileName = fn; + fileSave(); +} + +void AddressBook::fileExit() +{ + qApp->exit(); +} + +void AddressBook::editFind() +{ + SearchDialog dia( this, 0, TRUE ); + connect( &dia, SIGNAL( searchAddress( const QString & ) ), + this, SLOT( searchAddress( const QString & ) ) ); + dia.exec(); +} + +void AddressBook::searchAddress( const QString &expr ) +{ + addressView->clearSelection(); + QListViewItemIterator it( addressView ); + while ( it.current() ) { + for ( int i = 0; i < 7; ++i ) { + if ( it.current()->text( i ).find( expr ) != -1 ) + addressView->setSelected( it.current(), TRUE ); + } + ++it; + } +} \ No newline at end of file diff --git a/tools/designer/examples/addressbook/addressdetails.ui b/tools/designer/examples/addressbook/addressdetails.ui new file mode 100644 index 0000000..d321a0c --- /dev/null +++ b/tools/designer/examples/addressbook/addressdetails.ui @@ -0,0 +1,243 @@ + +AddressDetails + + + AddressDetails + + + + 0 + 0 + 216 + 252 + + + + Enter Address + + + + unnamed + + + 11 + + + 6 + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel8 + + + Street + + + + + editStreet + + + + + editPhoneNumber + + + + + TextLabel7 + + + City + + + + + TextLabel1 + + + Last Name + + + + + TextLabel6 + + + Phone Number + + + + + editCountry + + + + + TextLabel10 + + + Zip Code + + + + + editLastName + + + + + editZipCode + + + + + TextLabel4 + + + First Name + + + + + editCity + + + + + TextLabel9 + + + Country + + + + + editFirstName + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + PushButton2 + + + OK + + + true + + + + + PushButton3 + + + Cancel + + + + + + + + + PushButton2 + clicked() + AddressDetails + okClicked() + + + PushButton3 + clicked() + AddressDetails + reject() + + + + editLastName + editFirstName + editPhoneNumber + editStreet + editCity + editCountry + editZipCode + PushButton2 + PushButton3 + + + addressdetails.ui.h + + + newAddress( const QString &, const QString &, const QString &, const QString &, const QString &, const QString &, const QString & ); + + + init() + okClicked() + + + + diff --git a/tools/designer/examples/addressbook/addressdetails.ui.h b/tools/designer/examples/addressbook/addressdetails.ui.h new file mode 100644 index 0000000..e6c1ff5 --- /dev/null +++ b/tools/designer/examples/addressbook/addressdetails.ui.h @@ -0,0 +1,24 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +void AddressDetails::init() +{ + editLastName->setFocus(); +} + +void AddressDetails::okClicked() +{ + emit newAddress( editLastName->text(), + editFirstName->text(), + editPhoneNumber->text(), + editStreet->text(), + editCity->text(), + editCountry->text(), + editZipCode->text() ); + close(); +} \ No newline at end of file diff --git a/tools/designer/examples/addressbook/images/editcut.png b/tools/designer/examples/addressbook/images/editcut.png new file mode 100644 index 0000000..9c7fb3c Binary files /dev/null and b/tools/designer/examples/addressbook/images/editcut.png differ diff --git a/tools/designer/examples/addressbook/images/filenew.png b/tools/designer/examples/addressbook/images/filenew.png new file mode 100644 index 0000000..d898107 Binary files /dev/null and b/tools/designer/examples/addressbook/images/filenew.png differ diff --git a/tools/designer/examples/addressbook/images/fileopen.png b/tools/designer/examples/addressbook/images/fileopen.png new file mode 100644 index 0000000..7e49adb Binary files /dev/null and b/tools/designer/examples/addressbook/images/fileopen.png differ diff --git a/tools/designer/examples/addressbook/images/filesave.png b/tools/designer/examples/addressbook/images/filesave.png new file mode 100644 index 0000000..77d9f50 Binary files /dev/null and b/tools/designer/examples/addressbook/images/filesave.png differ diff --git a/tools/designer/examples/addressbook/images/searchfind.png b/tools/designer/examples/addressbook/images/searchfind.png new file mode 100644 index 0000000..f18b029 Binary files /dev/null and b/tools/designer/examples/addressbook/images/searchfind.png differ diff --git a/tools/designer/examples/addressbook/main.cpp b/tools/designer/examples/addressbook/main.cpp new file mode 100644 index 0000000..9a58f60 --- /dev/null +++ b/tools/designer/examples/addressbook/main.cpp @@ -0,0 +1,11 @@ +#include +#include "addressbook.h" + +int main( int argc, char ** argv ) +{ + QApplication a( argc, argv ); + AddressBook *w = new AddressBook; + w->show(); + a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); + return a.exec(); +} diff --git a/tools/designer/examples/addressbook/search.ui b/tools/designer/examples/addressbook/search.ui new file mode 100644 index 0000000..4329048 --- /dev/null +++ b/tools/designer/examples/addressbook/search.ui @@ -0,0 +1,136 @@ + +SearchDialog + + + SearchDialog + + + + 0 + 0 + 216 + 76 + + + + Search + + + + unnamed + + + 11 + + + 6 + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel12 + + + Search + + + + + editSearch + + + + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + Spacer3 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + PushButton4 + + + Search + + + true + + + + + PushButton5 + + + Close + + + + + + + + + PushButton5 + clicked() + SearchDialog + reject() + + + PushButton4 + clicked() + SearchDialog + search() + + + + search.ui.h + + + searchAddress( const QString & ) + + + search() + + + + diff --git a/tools/designer/examples/addressbook/search.ui.h b/tools/designer/examples/addressbook/search.ui.h new file mode 100644 index 0000000..8b3a8d5 --- /dev/null +++ b/tools/designer/examples/addressbook/search.ui.h @@ -0,0 +1,13 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +void SearchDialog::search() +{ + emit searchAddress( editSearch->text() ); + close(); +} \ No newline at end of file diff --git a/tools/designer/examples/book/book.sql b/tools/designer/examples/book/book.sql new file mode 100644 index 0000000..417ef43 --- /dev/null +++ b/tools/designer/examples/book/book.sql @@ -0,0 +1,42 @@ +-- The following SQL generates the database +-- used by the 'book' example programs +-- Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +-- +-- This file is part of an example program for Qt. This example +-- program may be used, distributed and modified without limitation. + +DROP TABLE author; +DROP TABLE book; +DROP TABLE sequence; + +CREATE TABLE author +( id integer primary key, +forename varchar(40), +surname varchar(40) ); + +CREATE TABLE book +( id integer primary key, +title varchar(40), +price numeric(10,2), +authorid integer, +notes varchar(255) ); + +create index book_authorid_idx on book( authorid ); + +CREATE TABLE sequence +( tablename varchar(10), +sequence numeric); + +INSERT INTO author VALUES ( 0, 'Philip K', 'Dick' ); +INSERT INTO author VALUES ( 1, 'Robert', 'Heinlein' ); +INSERT INTO author VALUES ( 2, 'Sarah', 'Paretsky' ); + +INSERT INTO book VALUES ( 0, 'The Man Who Japed', 6.99, 0, 'A good book' ); +INSERT INTO book VALUES ( 1, 'The Man in the High Castle', 9.99, 0, 'Worth reading' ); +INSERT INTO book VALUES ( 2, 'The Number of the Beast', 8.99, 1, 'Get this!' ); +INSERT INTO book VALUES ( 3, 'Indemnity Only', 9.99, 2, 'Cool' ); +INSERT INTO book VALUES ( 4, 'Burn Marks', 9.99, 2, 'Need to make notes' ); +INSERT INTO book VALUES ( 5, 'Deadlock', 9.99, 2, 'Hmmm..' ); + +INSERT INTO sequence VALUES ( 'author', 2 ); +INSERT INTO sequence VALUES ( 'book', 5 ); diff --git a/tools/designer/examples/book/book1/book.ui b/tools/designer/examples/book/book1/book.ui new file mode 100644 index 0000000..615b3d5 --- /dev/null +++ b/tools/designer/examples/book/book1/book.ui @@ -0,0 +1,71 @@ + +BookForm +book.ui.h + + + + BookForm + + + + 0 + 0 + 584 + 472 + + + + Book + + + + unnamed + + + 11 + + + 6 + + + + + Surname + + + surname + + + + + Forename + + + forename + + + + AuthorcDataTable + + + true + + + + surname ASC + forename ASC + + + + + (default) + author + + + + + + + primeInsertAuthor( QSqlRecord * ) + + diff --git a/tools/designer/examples/book/book1/book.ui.h b/tools/designer/examples/book/book1/book.ui.h new file mode 100644 index 0000000..e658278 --- /dev/null +++ b/tools/designer/examples/book/book1/book.ui.h @@ -0,0 +1,5 @@ +void BookForm::primeInsertAuthor( QSqlRecord * ) +{ + +} + diff --git a/tools/designer/examples/book/book1/book1.pro b/tools/designer/examples/book/book1/book1.pro new file mode 100644 index 0000000..a7e1f7b --- /dev/null +++ b/tools/designer/examples/book/book1/book1.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += qt warn_on release + +SOURCES += main.cpp ../connection.cpp +FORMS = book.ui +DBFILE = book.db diff --git a/tools/designer/examples/book/book1/main.cpp b/tools/designer/examples/book/book1/main.cpp new file mode 100644 index 0000000..464ed42 --- /dev/null +++ b/tools/designer/examples/book/book1/main.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include +#include "book.h" +#include "../connection.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + if ( ! createConnections() ) + return 1; + + BookForm bookForm; + app.setMainWidget( &bookForm ); + bookForm.show(); + + return app.exec(); +} diff --git a/tools/designer/examples/book/book2/book.ui b/tools/designer/examples/book/book2/book.ui new file mode 100644 index 0000000..c66dfae --- /dev/null +++ b/tools/designer/examples/book/book2/book.ui @@ -0,0 +1,77 @@ + +BookForm +book.ui.h + + + + BookForm + + + + 0 + 0 + 576 + 468 + + + + Book + + + + unnamed + + + 11 + + + 6 + + + + + Surname + + + surname + + + + + Forename + + + forename + + + + AuthorcDataTable + + + true + + + + surname ASC + forename ASC + + + + + (default) + author + + + + + + + + AuthorcDataTable + primeInsert(QSqlRecord*) + BookForm + primeInsertAuthor(QSqlRecord*) + + primeInsertAuthor( QSqlRecord * buffer ) + + diff --git a/tools/designer/examples/book/book2/book.ui.h b/tools/designer/examples/book/book2/book.ui.h new file mode 100644 index 0000000..40b1143 --- /dev/null +++ b/tools/designer/examples/book/book2/book.ui.h @@ -0,0 +1,10 @@ +void BookForm::primeInsertAuthor( QSqlRecord * buffer ) +{ + QSqlQuery query; + query.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='author';" ); + query.exec( "SELECT sequence FROM sequence WHERE tablename='author';" ); + if ( query.next() ) { + buffer->setValue( "id", query.value( 0 ) ); + } +} + diff --git a/tools/designer/examples/book/book2/book2.pro b/tools/designer/examples/book/book2/book2.pro new file mode 100644 index 0000000..a7e1f7b --- /dev/null +++ b/tools/designer/examples/book/book2/book2.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += qt warn_on release + +SOURCES += main.cpp ../connection.cpp +FORMS = book.ui +DBFILE = book.db diff --git a/tools/designer/examples/book/book2/main.cpp b/tools/designer/examples/book/book2/main.cpp new file mode 100644 index 0000000..464ed42 --- /dev/null +++ b/tools/designer/examples/book/book2/main.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include +#include "book.h" +#include "../connection.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + if ( ! createConnections() ) + return 1; + + BookForm bookForm; + app.setMainWidget( &bookForm ); + bookForm.show(); + + return app.exec(); +} diff --git a/tools/designer/examples/book/book3/book.ui b/tools/designer/examples/book/book3/book.ui new file mode 100644 index 0000000..91e2c04 --- /dev/null +++ b/tools/designer/examples/book/book3/book.ui @@ -0,0 +1,141 @@ + +BookForm +book.ui.h + + + + BookForm + + + + 0 + 0 + 566 + 464 + + + + Book + + + + unnamed + + + 11 + + + 6 + + + + Splitter1 + + + MShape + + + MShadow + + + Vertical + + + + + Surname + + + surname + + + + + Forename + + + forename + + + + AuthorDataTable + + + true + + + + surname ASC + forename ASC + + + + + (default) + author + + + + + + + Title + + + title + + + + + Price + + + price + + + + + Notes + + + notes + + + + BookDataTable + + + true + + + + title ASC + + + + + (default) + book + + + + + + + + + AuthorDataTable + currentChanged(QSqlRecord*) + BookForm + newCurrentAuthor(QSqlRecord*) + + + AuthorDataTable + primeInsert(QSqlRecord*) + BookForm + primeInsertAuthor(QSqlRecord*) + + newCurrentAuthor( QSqlRecord * author ) + primeInsertAuthor( QSqlRecord * buffer ) + + diff --git a/tools/designer/examples/book/book3/book.ui.h b/tools/designer/examples/book/book3/book.ui.h new file mode 100644 index 0000000..b027d01 --- /dev/null +++ b/tools/designer/examples/book/book3/book.ui.h @@ -0,0 +1,16 @@ +void BookForm::newCurrentAuthor( QSqlRecord *author ) +{ + BookDataTable->setFilter( "authorid=" + author->value( "id" ).toString() ); + BookDataTable->refresh(); +} + +void BookForm::primeInsertAuthor( QSqlRecord *buffer ) +{ + QSqlQuery query; + query.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='author';" ); + query.exec( "SELECT sequence FROM sequence WHERE tablename='author';" ); + if ( query.next() ) { + buffer->setValue( "id", query.value( 0 ) ); + } +} + diff --git a/tools/designer/examples/book/book3/book3.pro b/tools/designer/examples/book/book3/book3.pro new file mode 100644 index 0000000..a7e1f7b --- /dev/null +++ b/tools/designer/examples/book/book3/book3.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += qt warn_on release + +SOURCES += main.cpp ../connection.cpp +FORMS = book.ui +DBFILE = book.db diff --git a/tools/designer/examples/book/book3/main.cpp b/tools/designer/examples/book/book3/main.cpp new file mode 100644 index 0000000..89911b1 --- /dev/null +++ b/tools/designer/examples/book/book3/main.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include +#include "book.h" +#include "../connection.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + if ( ! createConnections() ) + return 1; + + BookForm bookForm; + app.setMainWidget( &bookForm ); + bookForm.show(); + + return app.exec(); +} diff --git a/tools/designer/examples/book/book4/book.ui b/tools/designer/examples/book/book4/book.ui new file mode 100644 index 0000000..f24818c --- /dev/null +++ b/tools/designer/examples/book/book4/book.ui @@ -0,0 +1,179 @@ + +BookForm +book.ui.h + + + + BookForm + + + + 0 + 0 + 546 + 532 + + + + Book + + + + unnamed + + + 11 + + + 6 + + + + Splitter1 + + + MShape + + + MShadow + + + Vertical + + + + + Surname + + + surname + + + + + Forename + + + forename + + + + AuthorDataTable + + + true + + + + surname ASC + forename ASC + + + + + (default) + author + + + + + + + Title + + + title + + + + + Price + + + price + + + + + Notes + + + notes + + + + BookDataTable + + + true + + + + title ASC + + + + + (default) + book + + + + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + EditPushButton + + + &Edit Books + + + + + QuitPushButton + + + &Quit + + + + + + + + + AuthorDataTable + currentChanged(QSqlRecord*) + BookForm + newCurrentAuthor(QSqlRecord*) + + + AuthorDataTable + primeInsert(QSqlRecord*) + BookForm + primeInsertAuthor(QSqlRecord*) + + + QuitPushButton + clicked() + BookForm + accept() + + newCurrentAuthor( QSqlRecord * author ) + primeInsertAuthor( QSqlRecord * buffer ) + + diff --git a/tools/designer/examples/book/book4/book.ui.h b/tools/designer/examples/book/book4/book.ui.h new file mode 100644 index 0000000..a8754e9 --- /dev/null +++ b/tools/designer/examples/book/book4/book.ui.h @@ -0,0 +1,16 @@ +void BookForm::newCurrentAuthor( QSqlRecord * author ) +{ + BookDataTable->setFilter( "authorid=" + author->value( "id" ).toString() ); + BookDataTable->refresh(); +} + +void BookForm::primeInsertAuthor( QSqlRecord * buffer ) +{ + QSqlQuery query; + query.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='author';" ); + query.exec( "SELECT sequence FROM sequence WHERE tablename='author';" ); + if ( query.next() ) { + buffer->setValue( "id", query.value( 0 ) ); + } +} + diff --git a/tools/designer/examples/book/book4/book4.pro b/tools/designer/examples/book/book4/book4.pro new file mode 100644 index 0000000..a7e1f7b --- /dev/null +++ b/tools/designer/examples/book/book4/book4.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += qt warn_on release + +SOURCES += main.cpp ../connection.cpp +FORMS = book.ui +DBFILE = book.db diff --git a/tools/designer/examples/book/book4/main.cpp b/tools/designer/examples/book/book4/main.cpp new file mode 100644 index 0000000..2688b18 --- /dev/null +++ b/tools/designer/examples/book/book4/main.cpp @@ -0,0 +1,29 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include +#include "book.h" +#include "../connection.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + if ( ! createConnections() ) + return 1; + + BookForm bookForm; + app.setMainWidget( &bookForm ); + bookForm.show(); + + return app.exec(); +} + + diff --git a/tools/designer/examples/book/book5/book.ui b/tools/designer/examples/book/book5/book.ui new file mode 100644 index 0000000..b27cb94 --- /dev/null +++ b/tools/designer/examples/book/book5/book.ui @@ -0,0 +1,188 @@ + +BookForm +qdatabrowser.h +editbook.h +book.ui.h + + + + BookForm + + + + 0 + 0 + 530 + 524 + + + + Book + + + + unnamed + + + 11 + + + 6 + + + + Splitter1 + + + MShape + + + MShadow + + + Vertical + + + + + Surname + + + surname + + + + + Forename + + + forename + + + + AuthorDataTable + + + true + + + + surname ASC + forename ASC + + + + + (default) + author + + + + + + + Title + + + title + + + + + Price + + + price + + + + + Notes + + + notes + + + + BookDataTable + + + true + + + + title ASC + + + + + (default) + book + + + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + EditPushButton + + + &Edit Books + + + + + QuitPushButton + + + &Quit + + + + + + + + + QuitPushButton + clicked() + BookForm + accept() + + + EditPushButton + clicked() + BookForm + editClicked() + + + AuthorDataTable + primeInsert(QSqlRecord*) + BookForm + primeInsertAuthor(QSqlRecord*) + + + AuthorDataTable + currentChanged(QSqlRecord*) + BookForm + newCurrentAuthor(QSqlRecord*) + + editClicked() + newCurrentAuthor( QSqlRecord * author ) + primeInsertAuthor( QSqlRecord * buffer ) + + diff --git a/tools/designer/examples/book/book5/book.ui.h b/tools/designer/examples/book/book5/book.ui.h new file mode 100644 index 0000000..576af61 --- /dev/null +++ b/tools/designer/examples/book/book5/book.ui.h @@ -0,0 +1,23 @@ +void BookForm::editClicked() +{ + EditBookForm *dialog = new EditBookForm( this, "Edit Book Form", TRUE ); + dialog->exec(); + delete dialog; +} + +void BookForm::newCurrentAuthor( QSqlRecord *author ) +{ + BookDataTable->setFilter( "authorid=" + author->value( "id" ).toString() ); + BookDataTable->refresh(); +} + +void BookForm::primeInsertAuthor( QSqlRecord *buffer ) +{ + QSqlQuery query; + query.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='author';" ); + query.exec( "SELECT sequence FROM sequence WHERE tablename='author';" ); + if ( query.next() ) { + buffer->setValue( "id", query.value( 0 ) ); + } +} + diff --git a/tools/designer/examples/book/book5/book5.pro b/tools/designer/examples/book/book5/book5.pro new file mode 100644 index 0000000..030db5f --- /dev/null +++ b/tools/designer/examples/book/book5/book5.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += qt warn_on release + +SOURCES += main.cpp ../connection.cpp +FORMS = book.ui editbook.ui +DBFILE = book.db diff --git a/tools/designer/examples/book/book5/editbook.ui b/tools/designer/examples/book/book5/editbook.ui new file mode 100644 index 0000000..088b3a3 --- /dev/null +++ b/tools/designer/examples/book/book5/editbook.ui @@ -0,0 +1,291 @@ + +EditBookForm + + + EditBookForm + + + + 0 + 0 + 568 + 301 + + + + Edit Books + + + + unnamed + + + 11 + + + 6 + + + + BookDataBrowser + + + + title ASC + + + + + (default) + book + + + + false + + + + unnamed + + + 11 + + + 6 + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + labelPrice + + + Price + + + + + labelTitle + + + Title + + + + + QLineEditTitle + + + + + + + (default) + book + title + + + + + + QLineEditPrice + + + + (default) + book + price + + + + + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + PushButtonFirst + + + |< &First + + + + + PushButtonPrev + + + << &Prev + + + + + PushButtonNext + + + &Next >> + + + + + PushButtonLast + + + &Last >| + + + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + PushButtonInsert + + + &Insert + + + + + PushButtonUpdate + + + &Update + + + + + PushButtonDelete + + + &Delete + + + + + PushButtonClose + + + &Close + + + + + + + + + + + PushButtonFirst + clicked() + BookDataBrowser + first() + + + BookDataBrowser + firstRecordAvailable( bool ) + PushButtonFirst + setEnabled(bool) + + + PushButtonPrev + clicked() + BookDataBrowser + prev() + + + BookDataBrowser + prevRecordAvailable( bool ) + PushButtonPrev + setEnabled(bool) + + + PushButtonNext + clicked() + BookDataBrowser + next() + + + BookDataBrowser + nextRecordAvailable( bool ) + PushButtonNext + setEnabled(bool) + + + PushButtonLast + clicked() + BookDataBrowser + last() + + + BookDataBrowser + lastRecordAvailable( bool ) + PushButtonLast + setEnabled(bool) + + + PushButtonInsert + clicked() + BookDataBrowser + insert() + + + PushButtonUpdate + clicked() + BookDataBrowser + update() + + + PushButtonDelete + clicked() + BookDataBrowser + del() + + + + editbook.ui.h + + + init() + destroy() + + + diff --git a/tools/designer/examples/book/book5/editbook.ui.h b/tools/designer/examples/book/book5/editbook.ui.h new file mode 100644 index 0000000..4a8a636 --- /dev/null +++ b/tools/designer/examples/book/book5/editbook.ui.h @@ -0,0 +1,10 @@ +void EditBookForm::init() +{ + +} + +void EditBookForm::destroy() +{ + +} + diff --git a/tools/designer/examples/book/book5/main.cpp b/tools/designer/examples/book/book5/main.cpp new file mode 100644 index 0000000..464ed42 --- /dev/null +++ b/tools/designer/examples/book/book5/main.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include +#include "book.h" +#include "../connection.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + if ( ! createConnections() ) + return 1; + + BookForm bookForm; + app.setMainWidget( &bookForm ); + bookForm.show(); + + return app.exec(); +} diff --git a/tools/designer/examples/book/book6/book.ui b/tools/designer/examples/book/book6/book.ui new file mode 100644 index 0000000..e3ede50 --- /dev/null +++ b/tools/designer/examples/book/book6/book.ui @@ -0,0 +1,189 @@ + +BookForm +qsqlrecord.h +editbook.h +qdatabrowser.h +book.ui.h + + + + BookForm + + + + 0 + 0 + 494 + 506 + + + + Book + + + + unnamed + + + 11 + + + 6 + + + + Splitter1 + + + MShape + + + MShadow + + + Vertical + + + + + Surname + + + surname + + + + + Forename + + + forename + + + + AuthorDataTable + + + true + + + + surname ASC + forename ASC + + + + + (default) + author + + + + + + + Title + + + title + + + + + Price + + + price + + + + + Notes + + + notes + + + + BookDataTable + + + true + + + + title ASC + + + + + (default) + book + + + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + EditPushButton + + + &Edit Books + + + + + QuitPushButton + + + &Quit + + + + + + + + + QuitPushButton + clicked() + BookForm + accept() + + + EditPushButton + clicked() + BookForm + editClicked() + + + AuthorDataTable + primeInsert(QSqlRecord*) + BookForm + primeInsertAuthor(QSqlRecord*) + + + AuthorDataTable + currentChanged(QSqlRecord*) + BookForm + newCurrentAuthor(QSqlRecord*) + + editClicked() + newCurrentAuthor( QSqlRecord * author ) + primeInsertAuthor( QSqlRecord * buffer ) + + diff --git a/tools/designer/examples/book/book6/book.ui.h b/tools/designer/examples/book/book6/book.ui.h new file mode 100644 index 0000000..f41103d --- /dev/null +++ b/tools/designer/examples/book/book6/book.ui.h @@ -0,0 +1,33 @@ +void BookForm::editClicked() +{ + EditBookForm *dialog = new EditBookForm( this, "Edit Book Form", TRUE ); + QSqlCursor cur( "book" ); + dialog->BookDataBrowser->setSqlCursor( &cur ); + dialog->BookDataBrowser->setFilter( BookDataTable->filter() ); + dialog->BookDataBrowser->setSort(QSqlIndex::fromStringList( + BookDataTable->sort(), &cur ) ); + dialog->BookDataBrowser->refresh(); + int i = BookDataTable->currentRow(); + if ( i == -1 ) i = 0; // Always use the first row + dialog->BookDataBrowser->seek( i ); + dialog->exec(); + delete dialog; + BookDataTable->refresh(); +} + +void BookForm::newCurrentAuthor( QSqlRecord * author ) +{ + BookDataTable->setFilter( "authorid=" + author->value( "id" ).toString() ); + BookDataTable->refresh(); +} + +void BookForm::primeInsertAuthor( QSqlRecord * buffer ) +{ + QSqlQuery query; + query.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='author';" ); + query.exec( "SELECT sequence FROM sequence WHERE tablename='author';" ); + if ( query.next() ) { + buffer->setValue( "id", query.value( 0 ) ); + } +} + diff --git a/tools/designer/examples/book/book6/book6.pro b/tools/designer/examples/book/book6/book6.pro new file mode 100644 index 0000000..030db5f --- /dev/null +++ b/tools/designer/examples/book/book6/book6.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += qt warn_on release + +SOURCES += main.cpp ../connection.cpp +FORMS = book.ui editbook.ui +DBFILE = book.db diff --git a/tools/designer/examples/book/book6/editbook.ui b/tools/designer/examples/book/book6/editbook.ui new file mode 100644 index 0000000..2f7acd1 --- /dev/null +++ b/tools/designer/examples/book/book6/editbook.ui @@ -0,0 +1,300 @@ + +EditBookForm +qsqlrecord.h +editbook.ui.h +class QSqlRecord; + + + + EditBookForm + + + + 0 + 0 + 536 + 285 + + + + Edit Books + + + + unnamed + + + 11 + + + 6 + + + + BookDataBrowser + + + + title ASC + + + + + (default) + book + + + + false + + + + unnamed + + + 11 + + + 6 + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + labelPrice + + + Price + + + + + labelTitle + + + Title + + + + + QLineEditTitle + + + + (default) + book + title + + + + + + QLineEditPrice + + + + (default) + book + price + + + + + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + PushButtonFirst + + + |< &First + + + + + PushButtonPrev + + + << &Prev + + + + + PushButtonNext + + + &Next >> + + + + + PushButtonLast + + + &Last >| + + + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + PushButtonInsert + + + &Insert + + + + + PushButtonUpdate + + + &Update + + + true + + + + + PushButtonDelete + + + &Delete + + + + + PushButtonClose + + + &Close + + + + + + + + + + + PushButtonFirst + clicked() + BookDataBrowser + first() + + + BookDataBrowser + firstRecordAvailable( bool ) + PushButtonFirst + setEnabled(bool) + + + PushButtonPrev + clicked() + BookDataBrowser + prev() + + + BookDataBrowser + prevRecordAvailable( bool ) + PushButtonPrev + setEnabled(bool) + + + PushButtonNext + clicked() + BookDataBrowser + next() + + + BookDataBrowser + nextRecordAvailable( bool ) + PushButtonNext + setEnabled(bool) + + + PushButtonLast + clicked() + BookDataBrowser + last() + + + BookDataBrowser + lastRecordAvailable( bool ) + PushButtonLast + setEnabled(bool) + + + PushButtonInsert + clicked() + BookDataBrowser + insert() + + + PushButtonUpdate + clicked() + BookDataBrowser + update() + + + PushButtonDelete + clicked() + BookDataBrowser + del() + + + BookDataBrowser + primeInsert(QSqlRecord*) + EditBookForm + primeInsertBook(QSqlRecord*) + + + PushButtonClose + clicked() + EditBookForm + accept() + + primeInsertBook( QSqlRecord * buffer ) + + diff --git a/tools/designer/examples/book/book6/editbook.ui.h b/tools/designer/examples/book/book6/editbook.ui.h new file mode 100644 index 0000000..eb76ac3 --- /dev/null +++ b/tools/designer/examples/book/book6/editbook.ui.h @@ -0,0 +1,10 @@ +void EditBookForm::primeInsertBook( QSqlRecord * buffer ) +{ + QSqlQuery query; + query.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='book';" ); + query.exec( "SELECT sequence FROM sequence WHERE tablename='book';" ); + if ( query.next() ) { + buffer->setValue( "id", query.value( 0 ) ); + } +} + diff --git a/tools/designer/examples/book/book6/main.cpp b/tools/designer/examples/book/book6/main.cpp new file mode 100644 index 0000000..464ed42 --- /dev/null +++ b/tools/designer/examples/book/book6/main.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include +#include "book.h" +#include "../connection.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + if ( ! createConnections() ) + return 1; + + BookForm bookForm; + app.setMainWidget( &bookForm ); + bookForm.show(); + + return app.exec(); +} diff --git a/tools/designer/examples/book/book7/book.ui b/tools/designer/examples/book/book7/book.ui new file mode 100644 index 0000000..b3c2869 --- /dev/null +++ b/tools/designer/examples/book/book7/book.ui @@ -0,0 +1,189 @@ + +BookForm +qsqlrecord.h +editbook.h +qdatabrowser.h +book.ui.h + + + + BookForm + + + + 0 + 0 + 490 + 504 + + + + Book + + + + unnamed + + + 11 + + + 6 + + + + Splitter1 + + + MShape + + + MShadow + + + Vertical + + + + + Surname + + + surname + + + + + Forename + + + forename + + + + AuthorDataTable + + + true + + + + surname ASC + forename ASC + + + + + (default) + author + + + + + + + Title + + + title + + + + + Price + + + price + + + + + Notes + + + notes + + + + BookDataTable + + + true + + + + title ASC + + + + + (default) + book + + + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + EditPushButton + + + &Edit Books + + + + + QuitPushButton + + + &Quit + + + + + + + + + QuitPushButton + clicked() + BookForm + accept() + + + EditPushButton + clicked() + BookForm + editClicked() + + + AuthorDataTable + primeInsert(QSqlRecord*) + BookForm + primeInsertAuthor(QSqlRecord*) + + + AuthorDataTable + currentChanged(QSqlRecord*) + BookForm + newCurrentAuthor(QSqlRecord*) + + editClicked() + newCurrentAuthor( QSqlRecord * author ) + primeInsertAuthor( QSqlRecord * buffer ) + + diff --git a/tools/designer/examples/book/book7/book.ui.h b/tools/designer/examples/book/book7/book.ui.h new file mode 100644 index 0000000..de754b1 --- /dev/null +++ b/tools/designer/examples/book/book7/book.ui.h @@ -0,0 +1,33 @@ +void BookForm::editClicked() +{ + EditBookForm *dialog = new EditBookForm( this, "Edit Book Form", TRUE ); + QSqlCursor cur( "book" ); + dialog->BookDataBrowser->setSqlCursor( &cur ); + dialog->BookDataBrowser->setFilter( BookDataTable->filter() ); + dialog->BookDataBrowser->setSort(QSqlIndex::fromStringList( + BookDataTable->sort(), &cur ) ); + dialog->BookDataBrowser->refresh(); + int i = BookDataTable->currentRow(); + if ( i == -1 ) i = 0; // Always use the first row + dialog->BookDataBrowser->seek( i ); + dialog->exec(); + delete dialog; + BookDataTable->refresh(); +} + +void BookForm::newCurrentAuthor( QSqlRecord *author ) +{ + BookDataTable->setFilter( "authorid=" + author->value( "id" ).toString() ); + BookDataTable->refresh(); +} + +void BookForm::primeInsertAuthor( QSqlRecord *buffer ) +{ + QSqlQuery query; + query.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='author';" ); + query.exec( "SELECT sequence FROM sequence WHERE tablename='author';" ); + if ( query.next() ) { + buffer->setValue( "id", query.value( 0 ) ); + } +} + diff --git a/tools/designer/examples/book/book7/book7.pro b/tools/designer/examples/book/book7/book7.pro new file mode 100644 index 0000000..22c7e9b --- /dev/null +++ b/tools/designer/examples/book/book7/book7.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += qt warn_on release +SOURCES += main.cpp ../connection.cpp +FORMS = book.ui editbook.ui +DBFILE = book.db diff --git a/tools/designer/examples/book/book7/editbook.ui b/tools/designer/examples/book/book7/editbook.ui new file mode 100644 index 0000000..85df2ba --- /dev/null +++ b/tools/designer/examples/book/book7/editbook.ui @@ -0,0 +1,384 @@ + +EditBookForm +qsqlrecord.h +editbook.ui.h +class QSqlRecord; + + + + EditBookForm + + + + 0 + 0 + 528 + 305 + + + + Edit Books + + + + unnamed + + + 11 + + + 6 + + + + BookDataBrowser + + + + title ASC + + + + + (default) + book + + + + true + + + + unnamed + + + 11 + + + 6 + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + labelPrice + + + Price + + + + + labelTitle + + + Title + + + + + QLineEditTitle + + + + (default) + book + title + + + + + + QLineEditPrice + + + + (default) + book + price + + + + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + PushButtonInsert + + + &Insert + + + + + PushButtonUpdate + + + &Update + + + true + + + + + PushButtonDelete + + + &Delete + + + + + PushButtonClose + + + &Close + + + + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + PushButtonFirst + + + |< &First + + + + + PushButtonPrev + + + << &Prev + + + + + PushButtonNext + + + &Next >> + + + + + PushButtonLast + + + &Last >| + + + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + Author + + + + + ComboBoxAuthor + + + + 7 + 0 + 0 + 0 + + + + + (default) + author_view + name + + + + + + + + + + + + PushButtonFirst + clicked() + BookDataBrowser + first() + + + BookDataBrowser + firstRecordAvailable( bool ) + PushButtonFirst + setEnabled(bool) + + + PushButtonPrev + clicked() + BookDataBrowser + prev() + + + BookDataBrowser + prevRecordAvailable( bool ) + PushButtonPrev + setEnabled(bool) + + + PushButtonNext + clicked() + BookDataBrowser + next() + + + BookDataBrowser + nextRecordAvailable( bool ) + PushButtonNext + setEnabled(bool) + + + PushButtonLast + clicked() + BookDataBrowser + last() + + + BookDataBrowser + lastRecordAvailable( bool ) + PushButtonLast + setEnabled(bool) + + + PushButtonInsert + clicked() + BookDataBrowser + insert() + + + PushButtonUpdate + clicked() + BookDataBrowser + update() + + + PushButtonDelete + clicked() + BookDataBrowser + del() + + + PushButtonClose + clicked() + EditBookForm + accept() + + + BookDataBrowser + primeUpdate(QSqlRecord*) + EditBookForm + primeUpdateBook(QSqlRecord*) + + + BookDataBrowser + beforeUpdate(QSqlRecord*) + EditBookForm + beforeUpdateBook(QSqlRecord*) + + + BookDataBrowser + beforeInsert(QSqlRecord*) + EditBookForm + beforeUpdateBook(QSqlRecord*) + + + BookDataBrowser + primeInsert(QSqlRecord*) + EditBookForm + primeInsertBook(QSqlRecord*) + + + BookDataBrowser + primeInsert(QSqlRecord*) + EditBookForm + primeInsertBook(QSqlRecord*) + + init() + beforeUpdateBook( QSqlRecord * buffer ) + primeInsertBook( QSqlRecord * buffer ) + primeUpdateBook( QSqlRecord * buffer ) + + + QLineEditTitle + QLineEditPrice + ComboBoxAuthor + PushButtonFirst + PushButtonPrev + PushButtonNext + PushButtonLast + PushButtonInsert + PushButtonUpdate + PushButtonDelete + PushButtonClose + + diff --git a/tools/designer/examples/book/book7/editbook.ui.h b/tools/designer/examples/book/book7/editbook.ui.h new file mode 100644 index 0000000..f955312 --- /dev/null +++ b/tools/designer/examples/book/book7/editbook.ui.h @@ -0,0 +1,42 @@ +void EditBookForm::init() +{ + QSqlQuery query( "SELECT surname FROM author ORDER BY surname;" ); + while ( query.next() ) + ComboBoxAuthor->insertItem( query.value( 0 ).toString()); +} + +void EditBookForm::beforeUpdateBook( QSqlRecord * buffer ) +{ + QSqlQuery query( "SELECT id FROM author WHERE surname ='" + + ComboBoxAuthor->currentText() + "';" ); + if ( query.next() ) + buffer->setValue( "authorid", query.value( 0 ) ); +} + +void EditBookForm::primeInsertBook( QSqlRecord * buffer ) +{ + QSqlQuery query; + query.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='book';" ); + query.exec( "SELECT sequence FROM sequence WHERE tablename='book';" ); + if ( query.next() ) { + buffer->setValue( "id", query.value( 0 ) ); + } +} + +void EditBookForm::primeUpdateBook( QSqlRecord * buffer ) +{ + // Who is this book's author? + QSqlQuery query( "SELECT surname FROM author WHERE id='" + + buffer->value( "authorid" ).toString() + "';" ); + QString author = ""; + if ( query.next() ) + author = query.value( 0 ).toString(); + // Set the ComboBox to the right author + for ( int i = 0; i < ComboBoxAuthor->count(); i++ ) { + if ( ComboBoxAuthor->text( i ) == author ) { + ComboBoxAuthor->setCurrentItem( i ) ; + break; + } + } +} + diff --git a/tools/designer/examples/book/book7/main.cpp b/tools/designer/examples/book/book7/main.cpp new file mode 100644 index 0000000..464ed42 --- /dev/null +++ b/tools/designer/examples/book/book7/main.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include +#include "book.h" +#include "../connection.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + if ( ! createConnections() ) + return 1; + + BookForm bookForm; + app.setMainWidget( &bookForm ); + bookForm.show(); + + return app.exec(); +} diff --git a/tools/designer/examples/book/book8/book.ui b/tools/designer/examples/book/book8/book.ui new file mode 100644 index 0000000..b3c2869 --- /dev/null +++ b/tools/designer/examples/book/book8/book.ui @@ -0,0 +1,189 @@ + +BookForm +qsqlrecord.h +editbook.h +qdatabrowser.h +book.ui.h + + + + BookForm + + + + 0 + 0 + 490 + 504 + + + + Book + + + + unnamed + + + 11 + + + 6 + + + + Splitter1 + + + MShape + + + MShadow + + + Vertical + + + + + Surname + + + surname + + + + + Forename + + + forename + + + + AuthorDataTable + + + true + + + + surname ASC + forename ASC + + + + + (default) + author + + + + + + + Title + + + title + + + + + Price + + + price + + + + + Notes + + + notes + + + + BookDataTable + + + true + + + + title ASC + + + + + (default) + book + + + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + EditPushButton + + + &Edit Books + + + + + QuitPushButton + + + &Quit + + + + + + + + + QuitPushButton + clicked() + BookForm + accept() + + + EditPushButton + clicked() + BookForm + editClicked() + + + AuthorDataTable + primeInsert(QSqlRecord*) + BookForm + primeInsertAuthor(QSqlRecord*) + + + AuthorDataTable + currentChanged(QSqlRecord*) + BookForm + newCurrentAuthor(QSqlRecord*) + + editClicked() + newCurrentAuthor( QSqlRecord * author ) + primeInsertAuthor( QSqlRecord * buffer ) + + diff --git a/tools/designer/examples/book/book8/book.ui.h b/tools/designer/examples/book/book8/book.ui.h new file mode 100644 index 0000000..6c8a2b5 --- /dev/null +++ b/tools/designer/examples/book/book8/book.ui.h @@ -0,0 +1,33 @@ +void BookForm::editClicked() +{ + EditBookForm *dialog = new EditBookForm( this, "Edit Book Form", TRUE ); + QSqlCursor cur( "book" ); + dialog->BookDataBrowser->setSqlCursor( &cur ); + dialog->BookDataBrowser->setFilter( BookDataTable->filter() ); + dialog->BookDataBrowser->setSort(QSqlIndex::fromStringList( + BookDataTable->sort(), &cur ) ); + dialog->BookDataBrowser->refresh(); + int i = BookDataTable->currentRow(); + if ( i == -1 ) i = 0; // Always use the first row + dialog->BookDataBrowser->seek( i ); + dialog->exec(); + delete dialog; + BookDataTable->refresh(); +} + +void BookForm::newCurrentAuthor( QSqlRecord *author ) +{ + BookDataTable->setFilter( "authorid=" + author->value( "id" ).toString() ); + BookDataTable->refresh(); +} + +void BookForm::primeInsertAuthor( QSqlRecord *buffer ) +{ + QSqlQuery q; + q.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='author';" ); + q.exec( "SELECT sequence FROM sequence WHERE tablename='author';" ); + if ( q.next() ) { + buffer->setValue( "id", q.value( 0 ) ); + } +} + diff --git a/tools/designer/examples/book/book8/book8.pro b/tools/designer/examples/book/book8/book8.pro new file mode 100644 index 0000000..e4bdf75 --- /dev/null +++ b/tools/designer/examples/book/book8/book8.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +LANGUAGE = C++ + +SOURCES += main.cpp ../connection.cpp +FORMS = book.ui editbook.ui +CONFIG += qt warn_on release +DBFILE = book.db diff --git a/tools/designer/examples/book/book8/editbook.ui b/tools/designer/examples/book/book8/editbook.ui new file mode 100644 index 0000000..17d378b --- /dev/null +++ b/tools/designer/examples/book/book8/editbook.ui @@ -0,0 +1,386 @@ + +EditBookForm +qsqlrecord.h +editbook.ui.h +class QSqlRecord; +QMap<QString,int> authorMap; + + + + EditBookForm + + + + 0 + 0 + 520 + 369 + + + + Edit Books + + + + unnamed + + + 11 + + + 6 + + + + BookDataBrowser + + + + title ASC + + + + + (default) + book + + + + true + + + + unnamed + + + 11 + + + 6 + + + + Layout2 + + + + unnamed + + + 0 + + + 6 + + + + labelPrice + + + Price + + + + + labelTitle + + + Title + + + + + QLineEditTitle + + + + (default) + book + title + + + + + + QLineEditPrice + + + + (default) + book + price + + + + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + PushButtonInsert + + + &Insert + + + + + PushButtonUpdate + + + &Update + + + true + + + + + PushButtonDelete + + + &Delete + + + + + PushButtonClose + + + &Close + + + + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + PushButtonFirst + + + |< &First + + + + + PushButtonPrev + + + << &Prev + + + + + PushButtonNext + + + &Next >> + + + + + PushButtonLast + + + &Last >| + + + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + Author + + + + + ComboBoxAuthor + + + + 7 + 0 + 0 + 0 + + + + + (default) + author_view + name + + + + + + + + + + + + PushButtonFirst + clicked() + BookDataBrowser + first() + + + BookDataBrowser + firstRecordAvailable( bool ) + PushButtonFirst + setEnabled(bool) + + + PushButtonPrev + clicked() + BookDataBrowser + prev() + + + BookDataBrowser + prevRecordAvailable( bool ) + PushButtonPrev + setEnabled(bool) + + + PushButtonNext + clicked() + BookDataBrowser + next() + + + BookDataBrowser + nextRecordAvailable( bool ) + PushButtonNext + setEnabled(bool) + + + PushButtonLast + clicked() + BookDataBrowser + last() + + + BookDataBrowser + lastRecordAvailable( bool ) + PushButtonLast + setEnabled(bool) + + + PushButtonInsert + clicked() + BookDataBrowser + insert() + + + PushButtonUpdate + clicked() + BookDataBrowser + update() + + + PushButtonDelete + clicked() + BookDataBrowser + del() + + + PushButtonClose + clicked() + EditBookForm + accept() + + + BookDataBrowser + primeUpdate(QSqlRecord*) + EditBookForm + primeUpdateBook(QSqlRecord*) + + + BookDataBrowser + beforeUpdate(QSqlRecord*) + EditBookForm + beforeUpdateBook(QSqlRecord*) + + + BookDataBrowser + beforeInsert(QSqlRecord*) + EditBookForm + beforeUpdateBook(QSqlRecord*) + + + BookDataBrowser + primeInsert(QSqlRecord*) + EditBookForm + primeInsertBook(QSqlRecord*) + + + BookDataBrowser + primeInsert(QSqlRecord*) + EditBookForm + primeInsertBook(QSqlRecord*) + + init() + beforeUpdateBook( QSqlRecord * buffer ) + mapAuthor( const QString & name, int & id, bool populate ) + primeInsertBook( QSqlRecord * buffer ) + primeUpdateBook( QSqlRecord * buffer ) + + + QLineEditTitle + QLineEditPrice + ComboBoxAuthor + PushButtonFirst + PushButtonPrev + PushButtonNext + PushButtonLast + PushButtonInsert + PushButtonUpdate + PushButtonDelete + PushButtonClose + + diff --git a/tools/designer/examples/book/book8/editbook.ui.h b/tools/designer/examples/book/book8/editbook.ui.h new file mode 100644 index 0000000..1bac1a8 --- /dev/null +++ b/tools/designer/examples/book/book8/editbook.ui.h @@ -0,0 +1,47 @@ +void EditBookForm::init() +{ + QSqlQuery query( "SELECT surname, id FROM author ORDER BY surname;" ); + while ( query.next() ) { + ComboBoxAuthor->insertItem( query.value( 0 ).toString() ); + int id = query.value( 1 ).toInt(); + mapAuthor( query.value( 0 ).toString(), id, TRUE ); + } +} + +void EditBookForm::beforeUpdateBook( QSqlRecord * buffer ) +{ + int id; + mapAuthor( ComboBoxAuthor->currentText(), id, FALSE ); + buffer->setValue( "authorid", id ); +} + +void EditBookForm::mapAuthor( const QString & name, int & id, bool populate ) +{ + if ( populate ) + authorMap[ name ] = id; + else + id = authorMap[ name ]; +} + +void EditBookForm::primeInsertBook( QSqlRecord * buffer ) +{ + QSqlQuery q; + q.exec( "UPDATE sequence SET sequence = sequence + 1 WHERE tablename='book';" ); + q.exec( "SELECT sequence FROM sequence WHERE tablename='book';" ); + if ( q.next() ) { + buffer->setValue( "id", q.value( 0 ) ); + } +} + +void EditBookForm::primeUpdateBook( QSqlRecord * buffer ) +{ + int id = buffer->value( "authorid" ).toInt(); + for ( int i = 0; i < ComboBoxAuthor->count(); i++ ) { + QString author = ComboBoxAuthor->text( i ); + if ( authorMap.contains( author ) && authorMap[author] == id ) { + ComboBoxAuthor->setCurrentItem( i ) ; + break; + } + } +} + diff --git a/tools/designer/examples/book/book8/main.cpp b/tools/designer/examples/book/book8/main.cpp new file mode 100644 index 0000000..464ed42 --- /dev/null +++ b/tools/designer/examples/book/book8/main.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include +#include "book.h" +#include "../connection.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + if ( ! createConnections() ) + return 1; + + BookForm bookForm; + app.setMainWidget( &bookForm ); + bookForm.show(); + + return app.exec(); +} diff --git a/tools/designer/examples/book/connection.cpp b/tools/designer/examples/book/connection.cpp new file mode 100644 index 0000000..710f50c --- /dev/null +++ b/tools/designer/examples/book/connection.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ +#include +#include "connection.h" + +bool createConnections() +{ + // create the default database connection + QSqlDatabase *defaultDB = QSqlDatabase::addDatabase( DB_BOOKS_DRIVER ); + defaultDB->setDatabaseName( DB_BOOKS ); + defaultDB->setUserName( DB_BOOKS_USER ); + defaultDB->setPassword( DB_BOOKS_PASSWD ); + defaultDB->setHostName( DB_BOOKS_HOST ); + if ( ! defaultDB->open() ) { + qWarning( "Failed to open books database: " + + defaultDB->lastError().driverText() ); + qWarning( defaultDB->lastError().databaseText() ); + return FALSE; + } + + QSqlQuery q(QString::null, defaultDB); + q.exec("CREATE TABLE author ( id integer primary key, " + "forename varchar(40), surname varchar(40) )"); + q.exec("CREATE TABLE book ( id integer primary key, " + "title varchar(40), price numeric(10,2), authorid integer, notes varchar(255) )"); + + q.exec("CREATE TABLE sequence ( tablename varchar(10), sequence numeric)"); + + q.exec("INSERT INTO author VALUES ( 0, 'Philip K', 'Dick' )"); + q.exec("INSERT INTO author VALUES ( 1, 'Robert', 'Heinlein' )"); + q.exec("INSERT INTO author VALUES ( 2, 'Sarah', 'Paretsky' )"); + + q.exec("INSERT INTO book VALUES (0, 'The Man Who Japed', 6.99, 0, 'A good book' )"); + q.exec("INSERT INTO book VALUES (1, 'The Man in the High Castle', 9.99, 0, 'Worth reading' )"); + q.exec("INSERT INTO book VALUES ( 2, 'The Number of the Beast', 8.99, 1, 'Get this!' )"); + q.exec("INSERT INTO book VALUES ( 3, 'Indemnity Only', 9.99, 2, 'Cool' )"); + q.exec("INSERT INTO book VALUES ( 4, 'Burn Marks', 9.99, 2, 'Need to make notes' )"); + q.exec("INSERT INTO book VALUES ( 5, 'Deadlock', 9.99, 2, 'Hmmm..' )"); + + q.exec("INSERT INTO sequence VALUES ( 'author', 2 )"); + q.exec("INSERT INTO sequence VALUES ( 'book', 5 )"); + + return TRUE; +} + + diff --git a/tools/designer/examples/book/connection.h b/tools/designer/examples/book/connection.h new file mode 100644 index 0000000..9768c73 --- /dev/null +++ b/tools/designer/examples/book/connection.h @@ -0,0 +1,18 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +// Add your own connection parameters here +#define DB_BOOKS_DRIVER "QSQLITE" +#define DB_BOOKS ":memory:" +#define DB_BOOKS_USER "" +#define DB_BOOKS_PASSWD "" +#define DB_BOOKS_HOST "" + +bool createConnections(); + diff --git a/tools/designer/examples/colortool/colornameform.ui b/tools/designer/examples/colortool/colornameform.ui new file mode 100644 index 0000000..566cd8d --- /dev/null +++ b/tools/designer/examples/colortool/colornameform.ui @@ -0,0 +1,168 @@ + +ColorNameForm + + + ColorNameForm + + + + 0 + 0 + 348 + 105 + + + + Color Tool -- Color Name + + + + unnamed + + + + colorLabel + + + + 80 + 0 + + + + + + + editraise.png + + + true + + + + + Layout4 + + + + unnamed + + + + Layout1 + + + + unnamed + + + + TextLabel2 + + + &Name + + + colorLineEdit + + + + + colorLineEdit + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 0 + + + + + + Layout4 + + + + unnamed + + + + Spacer3 + + + Horizontal + + + Expanding + + + + 0 + 11 + + + + + + okPushButton + + + OK + + + true + + + + + cancelPushButton + + + Cancel + + + + + + + + + + + cancelPushButton + clicked() + ColorNameForm + reject() + + + okPushButton + clicked() + ColorNameForm + validate() + + + + colornameform.ui.h + + + validate() + + + setColors( const QMap<QString, QColor> & colors ) + + + + diff --git a/tools/designer/examples/colortool/colornameform.ui.h b/tools/designer/examples/colortool/colornameform.ui.h new file mode 100644 index 0000000..24c9d71 --- /dev/null +++ b/tools/designer/examples/colortool/colornameform.ui.h @@ -0,0 +1,27 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions use Qt Designer which will +** update this file, preserving your code. Create an init() function in place +** of a constructor, and a destroy() function in place of a destructor. +*****************************************************************************/ +#include +#include +#include + +QMap m_colors; + +void ColorNameForm::setColors( const QMap& colors ) +{ + m_colors = colors; +} + +void ColorNameForm::validate() +{ + QString name = colorLineEdit->text(); + if ( ! name.isEmpty() && + ( m_colors.isEmpty() || ! m_colors.contains( name ) ) ) + accept(); + else + colorLineEdit->selectAll(); +} diff --git a/tools/designer/examples/colortool/colortool.pro b/tools/designer/examples/colortool/colortool.pro new file mode 100644 index 0000000..af22965 --- /dev/null +++ b/tools/designer/examples/colortool/colortool.pro @@ -0,0 +1,27 @@ +TEMPLATE = app +LANGUAGE = C++ + +SOURCES += main.cpp +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj +} +FORMS = mainform.ui \ + colornameform.ui \ + findform.ui \ + optionsform.ui +IMAGES = images/filenew.png \ + images/fileopen.png \ + images/filesave.png \ + images/editcut.png \ + images/editcopy.png \ + images/searchfind.png \ + images/tabwidget.png \ + images/table.png \ + images/iconview.png \ + images/richtextedit.png \ + images/widgetstack.png \ + images/editraise.png +CONFIG += qt warn_on release +DBFILE = colortool.db diff --git a/tools/designer/examples/colortool/findform.ui b/tools/designer/examples/colortool/findform.ui new file mode 100644 index 0000000..aaf7ca9 --- /dev/null +++ b/tools/designer/examples/colortool/findform.ui @@ -0,0 +1,141 @@ + +FindForm + + + FindForm + + + + 0 + 0 + 301 + 99 + + + + Color Tool -- Find Color + + + + unnamed + + + + Layout11 + + + + unnamed + + + + TextLabel3 + + + &Look for + + + findLineEdit + + + + + findLineEdit + + + + + + + Spacer4 + + + Vertical + + + Expanding + + + + 20 + 0 + + + + + + Layout10 + + + + unnamed + + + + Spacer7 + + + Horizontal + + + Expanding + + + + 0 + 9 + + + + + + findPushButton + + + &Find + + + true + + + + + closePushButton + + + Close + + + + + + + + + closePushButton + clicked() + FindForm + accept() + + + findPushButton + clicked() + FindForm + find() + + + + findform.ui.h + + + lookfor(const QString&) + + + find() + + + notfound() + + + + diff --git a/tools/designer/examples/colortool/findform.ui.h b/tools/designer/examples/colortool/findform.ui.h new file mode 100644 index 0000000..87eafae --- /dev/null +++ b/tools/designer/examples/colortool/findform.ui.h @@ -0,0 +1,18 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions use Qt Designer which will +** update this file, preserving your code. Create an init() function in place +** of a constructor, and a destroy() function in place of a destructor. +*****************************************************************************/ + + +void FindForm::find() +{ + emit lookfor( findLineEdit->text() ); +} + +void FindForm::notfound() +{ + findLineEdit->selectAll(); +} diff --git a/tools/designer/examples/colortool/images/editcopy.png b/tools/designer/examples/colortool/images/editcopy.png new file mode 100644 index 0000000..abfe86e Binary files /dev/null and b/tools/designer/examples/colortool/images/editcopy.png differ diff --git a/tools/designer/examples/colortool/images/editcut.png b/tools/designer/examples/colortool/images/editcut.png new file mode 100644 index 0000000..2d179bc Binary files /dev/null and b/tools/designer/examples/colortool/images/editcut.png differ diff --git a/tools/designer/examples/colortool/images/editraise.png b/tools/designer/examples/colortool/images/editraise.png new file mode 100644 index 0000000..0241568 Binary files /dev/null and b/tools/designer/examples/colortool/images/editraise.png differ diff --git a/tools/designer/examples/colortool/images/filenew.png b/tools/designer/examples/colortool/images/filenew.png new file mode 100644 index 0000000..9853d97 Binary files /dev/null and b/tools/designer/examples/colortool/images/filenew.png differ diff --git a/tools/designer/examples/colortool/images/fileopen.png b/tools/designer/examples/colortool/images/fileopen.png new file mode 100644 index 0000000..85dab43 Binary files /dev/null and b/tools/designer/examples/colortool/images/fileopen.png differ diff --git a/tools/designer/examples/colortool/images/filesave.png b/tools/designer/examples/colortool/images/filesave.png new file mode 100644 index 0000000..21309aa Binary files /dev/null and b/tools/designer/examples/colortool/images/filesave.png differ diff --git a/tools/designer/examples/colortool/images/iconview.png b/tools/designer/examples/colortool/images/iconview.png new file mode 100644 index 0000000..d755399 Binary files /dev/null and b/tools/designer/examples/colortool/images/iconview.png differ diff --git a/tools/designer/examples/colortool/images/richtextedit.png b/tools/designer/examples/colortool/images/richtextedit.png new file mode 100644 index 0000000..9f75c25 Binary files /dev/null and b/tools/designer/examples/colortool/images/richtextedit.png differ diff --git a/tools/designer/examples/colortool/images/searchfind.png b/tools/designer/examples/colortool/images/searchfind.png new file mode 100644 index 0000000..8f7d8ad Binary files /dev/null and b/tools/designer/examples/colortool/images/searchfind.png differ diff --git a/tools/designer/examples/colortool/images/table.png b/tools/designer/examples/colortool/images/table.png new file mode 100644 index 0000000..4491b6e Binary files /dev/null and b/tools/designer/examples/colortool/images/table.png differ diff --git a/tools/designer/examples/colortool/images/tabwidget.png b/tools/designer/examples/colortool/images/tabwidget.png new file mode 100644 index 0000000..3a16044 Binary files /dev/null and b/tools/designer/examples/colortool/images/tabwidget.png differ diff --git a/tools/designer/examples/colortool/images/widgetstack.png b/tools/designer/examples/colortool/images/widgetstack.png new file mode 100644 index 0000000..7b5f234 Binary files /dev/null and b/tools/designer/examples/colortool/images/widgetstack.png differ diff --git a/tools/designer/examples/colortool/main.cpp b/tools/designer/examples/colortool/main.cpp new file mode 100644 index 0000000..31b2586 --- /dev/null +++ b/tools/designer/examples/colortool/main.cpp @@ -0,0 +1,10 @@ +#include +#include "mainform.h" + +int main( int argc, char ** argv ) +{ + QApplication a( argc, argv ); + MainForm *w = new MainForm; + w->show(); + return a.exec(); +} diff --git a/tools/designer/examples/colortool/mainform.ui b/tools/designer/examples/colortool/mainform.ui new file mode 100644 index 0000000..6c89bac --- /dev/null +++ b/tools/designer/examples/colortool/mainform.ui @@ -0,0 +1,601 @@ + +MainForm + + + MainForm + + + + 0 + 0 + 600 + 480 + + + + Color Tool + + + + unnamed + + + + colorWidgetStack + + + NoFrame + + + Plain + + + + tablePage + + + 0 + + + + unnamed + + + + + Name + + + + + Hex + + + + + Web + + + + colorTable + + + 0 + + + 3 + + + true + + + + + + + iconsPage + + + 1 + + + + unnamed + + + + colorIconView + + + 100 + + + Adjust + + + + + + + + + + menubar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + toolBar + + + Tools + + + + + + + + + + + + + + + + + + + + fileNewAction + + + filenew.png + + + New + + + &New + + + Ctrl+N + + + + + fileOpenAction + + + fileopen.png + + + Open + + + &Open... + + + Ctrl+O + + + + + fileSaveAction + + + filesave.png + + + Save + + + &Save + + + Ctrl+S + + + + + fileSaveAsAction + + + Save As + + + Save &As... + + + + + + + + fileExitAction + + + Exit + + + E&xit + + + + + + + + editCutAction + + + editcut.png + + + Delete + + + &Delete + + + Ctrl+X + + + + + editCopyAction + + + editcopy.png + + + Copy + + + &Copy + + + Ctrl+C + + + + + editFindAction + + + searchfind.png + + + Find + + + &Find... + + + Ctrl+F + + + + + helpContentsAction + + + Contents + + + &Contents... + + + + + + + + helpIndexAction + + + Index + + + &Index... + + + + + + + + helpAboutAction + + + About + + + &About + + + + + + + + optionsAction + + + tabwidget.png + + + Options + + + &Options... + + + + + viewActionGroup + + + View + + + View + + + false + + + + viewTableAction + + + true + + + true + + + table.png + + + View Table + + + View &Table + + + View Table (Ctrl+T) + + + Ctrl+T + + + + + viewIconsAction + + + true + + + iconview.png + + + View Icons + + + View &Icons + + + View Icons (Ctrl+I) + + + Ctrl+I + + + + + + editAddAction + + + widgetstack.png + + + Add + + + &Add... + + + Ctrl+A + + + + + + fileNewAction + activated() + MainForm + fileNew() + + + fileOpenAction + activated() + MainForm + fileOpen() + + + fileSaveAction + activated() + MainForm + fileSave() + + + fileSaveAsAction + activated() + MainForm + fileSaveAs() + + + fileExitAction + activated() + MainForm + fileExit() + + + editCutAction + activated() + MainForm + editCut() + + + editCopyAction + activated() + MainForm + editCopy() + + + editFindAction + activated() + MainForm + editFind() + + + helpIndexAction + activated() + MainForm + helpIndex() + + + helpContentsAction + activated() + MainForm + helpContents() + + + helpAboutAction + activated() + MainForm + helpAbout() + + + colorTable + currentChanged(int,int) + MainForm + changedTableColor(int,int) + + + colorIconView + currentChanged(QIconViewItem*) + MainForm + changedIconColor(QIconViewItem*) + + + viewActionGroup + selected(QAction*) + MainForm + changeView(QAction*) + + + editAddAction + activated() + MainForm + editAdd() + + + optionsAction + activated() + MainForm + editOptions() + + + colorWidgetStack + aboutToShow(int) + MainForm + aboutToShow() + + + + findform.h + qsettings.h + qradiobutton.h + qcheckbox.h + colornameform.h + qcolordialog.h + qregexp.h + qfile.h + qfiledialog.h + qapplication.h + qcolor.h + qstring.h + qpainter.h + qstatusbar.h + qmessagebox.h + qclipboard.h + qlabel.h + qlineedit.h + optionsform.h + mainform.ui.h + + + class QString; + class QColor; + + + QStringList m_comments; + QString m_filename; + bool m_changed; + bool m_table_dirty; + bool m_icons_dirty; + int m_clip_as; + bool m_show_web; + QClipboard *clipboard; + FindForm *findForm; + QMap<QString,QColor> m_colors; + + + fileNew() + fileOpen() + fileSave() + fileSaveAs() + closeEvent( QCloseEvent * ) + fileExit() + editCut() + editCopy() + editFind() + lookfor( const QString & text ) + helpIndex() + helpContents() + helpAbout() + changedTableColor( int row, int ) + changedIconColor( QIconViewItem * item ) + changeView( QAction * action ) + editAdd() + editOptions() + aboutToShow() + + + init() + clearData( bool fillWithDefaults ) + populate() + colorSwatch( const QColor color ) + load( const QString & filename ) + okToClear() + changedColor( const QString & name ) + isWebColor( QColor color ) + loadSettings() + saveSettings() + + + + diff --git a/tools/designer/examples/colortool/mainform.ui.h b/tools/designer/examples/colortool/mainform.ui.h new file mode 100644 index 0000000..1ed2622 --- /dev/null +++ b/tools/designer/examples/colortool/mainform.ui.h @@ -0,0 +1,585 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions use Qt Designer which will +** update this file, preserving your code. Create an init() function in place +** of a constructor, and a destroy() function in place of a destructor. +*****************************************************************************/ + + +const int CLIP_AS_HEX = 0; +const int CLIP_AS_NAME = 1; +const int CLIP_AS_RGB = 2; +const int COL_NAME = 0; +const int COL_HEX = 1; +const int COL_WEB = 2; +const QString WINDOWS_REGISTRY = "/QtExamples"; +const QString APP_KEY = "/ColorTool/"; + +void MainForm::init() +{ + clipboard = QApplication::clipboard(); + if ( clipboard->supportsSelection() ) + clipboard->setSelectionMode( TRUE ); + + findForm = 0; + loadSettings(); + m_filename = ""; + m_changed = FALSE; + m_table_dirty = TRUE; + m_icons_dirty = TRUE; + clearData( TRUE ); +} + +void MainForm::clearData( bool fillWithDefaults ) +{ + setCaption( "Color Tool" ); + + m_colors.clear(); + m_comments.clear(); + + if ( fillWithDefaults ) { + m_colors["black"] = Qt::black; + m_colors["blue"] = Qt::blue; + m_colors["cyan"] = Qt::cyan; + m_colors["darkblue"] = Qt::darkBlue; + m_colors["darkcyan"] = Qt::darkCyan; + m_colors["darkgray"] = Qt::darkGray; + m_colors["darkgreen"] = Qt::darkGreen; + m_colors["darkmagenta"] = Qt::darkMagenta; + m_colors["darkred"] = Qt::darkRed; + m_colors["darkyellow"] = Qt::darkYellow; + m_colors["gray"] = Qt::gray; + m_colors["green"] = Qt::green; + m_colors["lightgray"] = Qt::lightGray; + m_colors["magenta"] = Qt::magenta; + m_colors["red"] = Qt::red; + m_colors["white"] = Qt::white; + m_colors["yellow"] = Qt::yellow; + } + + populate(); +} + +void MainForm::populate() +{ + if ( m_table_dirty ) { + for ( int r = 0; r < colorTable->numRows(); ++r ) { + for ( int c = 0; c < colorTable->numCols(); ++c ) { + colorTable->clearCell( r, c ); + } + } + + colorTable->setNumRows( m_colors.count() ); + if ( ! m_colors.isEmpty() ) { + QPixmap pixmap( 22, 22 ); + int row = 0; + QMap::ConstIterator it; + for ( it = m_colors.constBegin(); it != m_colors.constEnd(); ++it ) { + QColor color = it.data(); + pixmap.fill( color ); + colorTable->setText( row, COL_NAME, it.key() ); + colorTable->setPixmap( row, COL_NAME, pixmap ); + colorTable->setText( row, COL_HEX, color.name().upper() ); + if ( m_show_web ) { + QCheckTableItem *item = new QCheckTableItem( colorTable, "" ); + item->setChecked( isWebColor( color ) ); + colorTable->setItem( row, COL_WEB, item ); + } + row++; + } + colorTable->setCurrentCell( 0, 0 ); + } + colorTable->adjustColumn( COL_NAME ); + colorTable->adjustColumn( COL_HEX ); + if ( m_show_web ) { + colorTable->showColumn( COL_WEB ); + colorTable->adjustColumn( COL_WEB ); + } + else + colorTable->hideColumn( COL_WEB ); + m_table_dirty = FALSE; + } + + if ( m_icons_dirty ) { + colorIconView->clear(); + + QMap::ConstIterator it; + for ( it = m_colors.constBegin(); it != m_colors.constEnd(); ++it ) + (void) new QIconViewItem( colorIconView, it.key(), + colorSwatch( it.data() ) ); + m_icons_dirty = FALSE; + } +} + +QPixmap MainForm::colorSwatch( const QColor color ) +{ + QPixmap pixmap( 80, 80 ); + pixmap.fill( white ); + QPainter painter; + painter.begin( &pixmap ); + painter.setPen( NoPen ); + painter.setBrush( color ); + painter.drawEllipse( 0, 0, 80, 80 ); + painter.end(); + return pixmap; +} + +void MainForm::fileNew() +{ + if ( okToClear() ) { + m_filename = ""; + m_changed = FALSE; + m_table_dirty = TRUE; + m_icons_dirty = TRUE; + clearData( FALSE ); + } +} + +void MainForm::fileOpen() +{ + if ( ! okToClear() ) + return; + + QString filename = QFileDialog::getOpenFileName( + QString::null, "Colors (*.txt)", this, + "file open", "Color Tool -- File Open" ); + if ( ! filename.isEmpty() ) + load( filename ); + else + statusBar()->message( "File Open abandoned", 2000 ); +} + +void MainForm::fileSave() +{ + if ( m_filename.isEmpty() ) { + fileSaveAs(); + return; + } + + QFile file( m_filename ); + if ( file.open( IO_WriteOnly ) ) { + QTextStream stream( &file ); + if ( ! m_comments.isEmpty() ) + stream << m_comments.join( "\n" ) << "\n"; + QMap::ConstIterator it; + for ( it = m_colors.constBegin(); it != m_colors.constEnd(); ++it ) { + QColor color = it.data(); + stream << QString( "%1 %2 %3\t\t%4" ). + arg( color.red(), 3 ). + arg( color.green(), 3 ). + arg( color.blue(), 3 ). + arg( it.key() ) << "\n"; + } + file.close(); + setCaption( QString( "Color Tool -- %1" ).arg( m_filename ) ); + statusBar()->message( QString( "Saved %1 colors to '%2'" ). + arg( m_colors.count() ). + arg( m_filename ), 3000 ); + m_changed = FALSE; + } + else + statusBar()->message( QString( "Failed to save '%1'" ). + arg( m_filename ), 3000 ); + +} + +void MainForm::fileSaveAs() +{ + QString filename = QFileDialog::getSaveFileName( + QString::null, "Colors (*.txt)", this, + "file save as", "Color Tool -- File Save As" ); + if ( ! filename.isEmpty() ) { + int ans = 0; + if ( QFile::exists( filename ) ) + ans = QMessageBox::warning( + this, "Color Tool -- Overwrite File", + QString( "Overwrite\n'%1'?" ). + arg( filename ), + "&Yes", "&No", QString::null, 1, 1 ); + if ( ans == 0 ) { + m_filename = filename; + fileSave(); + return; + } + } + statusBar()->message( "Saving abandoned", 2000 ); +} + +void MainForm::load( const QString& filename ) +{ + clearData( FALSE ); + m_filename = filename; + QRegExp regex( "^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)\\s+(\\S+.*)$" ); + QFile file( filename ); + if ( file.open( IO_ReadOnly ) ) { + statusBar()->message( QString( "Loading '%1'..." ). + arg( filename ) ); + QTextStream stream( &file ); + QString line; + while ( ! stream.eof() ) { + line = stream.readLine(); + if ( regex.search( line ) == -1 ) + m_comments += line; + else + m_colors[regex.cap( 4 )] = QColor( + regex.cap( 1 ).toInt(), + regex.cap( 2 ).toInt(), + regex.cap( 3 ).toInt() ); + } + file.close(); + m_filename = filename; + setCaption( QString( "Color Tool -- %1" ).arg( m_filename ) ); + statusBar()->message( QString( "Loaded '%1'" ). + arg( m_filename ), 3000 ); + QWidget *visible = colorWidgetStack->visibleWidget(); + m_icons_dirty = ! ( m_table_dirty = ( visible == tablePage ) ); + populate(); + m_icons_dirty = ! ( m_table_dirty = ( visible != tablePage ) ); + m_changed = FALSE; + } + else + statusBar()->message( QString( "Failed to load '%1'" ). + arg( m_filename ), 3000 ); +} + + +bool MainForm::okToClear() +{ + if ( m_changed ) { + QString msg; + if ( m_filename.isEmpty() ) + msg = "Unnamed colors "; + else + msg = QString( "Colors '%1'\n" ).arg( m_filename ); + msg += QString( "has been changed." ); + int ans = QMessageBox::information( + this, + "Color Tool -- Unsaved Changes", + msg, "&Save", "Cancel", "&Abandon", + 0, 1 ); + if ( ans == 0 ) + fileSave(); + else if ( ans == 1 ) + return FALSE; + } + + return TRUE; +} + +void MainForm::closeEvent( QCloseEvent * ) +{ + fileExit(); +} + +void MainForm::fileExit() +{ + if ( okToClear() ) { + saveSettings(); + QApplication::exit( 0 ); + } +} + +void MainForm::editCut() +{ + QString name; + QWidget *visible = colorWidgetStack->visibleWidget(); + statusBar()->message( QString( "Deleting '%1'" ).arg( name ) ); + + if ( visible == tablePage && colorTable->numRows() ) { + int row = colorTable->currentRow(); + name = colorTable->text( row, 0 ); + colorTable->removeRow( colorTable->currentRow() ); + if ( row < colorTable->numRows() ) + colorTable->setCurrentCell( row, 0 ); + else if ( colorTable->numRows() ) + colorTable->setCurrentCell( colorTable->numRows() - 1, 0 ); + m_icons_dirty = TRUE; + } + else if ( visible == iconsPage && colorIconView->currentItem() ) { + QIconViewItem *item = colorIconView->currentItem(); + name = item->text(); + if ( colorIconView->count() == 1 ) + colorIconView->clear(); + else { + QIconViewItem *current = item->nextItem(); + if ( ! current ) + current = item->prevItem(); + delete item; + if ( current ) + colorIconView->setCurrentItem( current ); + colorIconView->arrangeItemsInGrid(); + } + m_table_dirty = TRUE; + } + + if ( ! name.isNull() ) { + m_colors.remove( name ); + m_changed = TRUE; + statusBar()->message( QString( "Deleted '%1'" ).arg( name ), 5000 ); + } + else + statusBar()->message( QString( "Failed to delete '%1'" ).arg( name ), 5000 ); +} + +void MainForm::editCopy() +{ + QString text; + QWidget *visible = colorWidgetStack->visibleWidget(); + + if ( visible == tablePage && colorTable->numRows() ) { + int row = colorTable->currentRow(); + text = colorTable->text( row, 0 ); + } + else if ( visible == iconsPage && colorIconView->currentItem() ) { + QIconViewItem *item = colorIconView->currentItem(); + text = item->text(); + } + if ( ! text.isNull() ) { + QColor color = m_colors[text]; + switch ( m_clip_as ) { + case CLIP_AS_HEX: text = color.name(); break; + case CLIP_AS_NAME: break; + case CLIP_AS_RGB: + text = QString( "%1,%2,%3" ). + arg( color.red() ). + arg( color.green() ). + arg( color.blue() ); + break; + } + clipboard->setText( text ); + statusBar()->message( "Copied '" + text + "' to the clipboard" ); + } +} + +void MainForm::editFind() +{ + if ( ! findForm ) { + findForm = new FindForm( this ); + connect( findForm, SIGNAL( lookfor(const QString&) ), + this, SLOT( lookfor(const QString&) ) ); + } + findForm->show(); +} + +void MainForm::lookfor( const QString& text ) +{ + if ( text.isEmpty() ) + return; + QString ltext = text.lower(); + QWidget *visible = colorWidgetStack->visibleWidget(); + bool found = FALSE; + + if ( visible == tablePage && colorTable->numRows() ) { + int row = colorTable->currentRow(); + for ( int i = row + 1; i < colorTable->numRows(); ++i ) + if ( colorTable->text( i, 0 ).lower().contains( ltext ) ) { + colorTable->setCurrentCell( i, 0 ); + colorTable->clearSelection(); + colorTable->selectRow( i ); + found = TRUE; + break; + } + if ( ! found ) + colorTable->setCurrentCell( row, 0 ); + + } + else if ( visible == iconsPage ) { + QIconViewItem *start = colorIconView->currentItem(); + for ( QIconViewItem *item = start->nextItem(); item; item = item->nextItem() ) + if ( item->text().lower().contains( ltext ) ) { + colorIconView->setCurrentItem( item ); + colorIconView->ensureItemVisible( item ); + found = TRUE; + break; + } + if ( ! found && start ) + colorIconView->setCurrentItem( start ); + } + if ( ! found ) { + statusBar()->message( QString( "Could not find '%1' after here" ). + arg( text ) ); + findForm->notfound(); + } +} + + + +void MainForm::helpIndex() +{ + +} + +void MainForm::helpContents() +{ + +} + +void MainForm::helpAbout() +{ + +} + + +void MainForm::changedTableColor( int row, int ) +{ + changedColor( colorTable->text( row, COL_NAME ) ); +} + +void MainForm::changedIconColor( QIconViewItem *item ) +{ + changedColor( item->text() ); +} + +void MainForm::changedColor( const QString& name ) +{ + QColor color = m_colors[name]; + int r = color.red(); + int g = color.green(); + int b = color.blue(); + statusBar()->message( QString( "%1 \"%2\" (%3,%4,%5)%6 {%7 %8 %9}" ). + arg( name ). + arg( color.name().upper() ). + arg( r ).arg( g ).arg( b ). + arg( isWebColor( color ) ? " web" : "" ). + arg( r / 255.0, 1, 'f', 3 ). + arg( g / 255.0, 1, 'f', 3 ). + arg( b / 255.0, 1, 'f', 3 ) + ); +} + + +void MainForm::changeView(QAction* action) +{ + if ( action == viewTableAction ) + colorWidgetStack->raiseWidget( tablePage ); + else + colorWidgetStack->raiseWidget( iconsPage ); +} + +bool MainForm::isWebColor( QColor color ) +{ + int r = color.red(); + int g = color.green(); + int b = color.blue(); + + return ( ( r == 0 || r == 51 || r == 102 || + r == 153 || r == 204 || r == 255 ) && + ( g == 0 || g == 51 || g == 102 || + g == 153 || g == 204 || g == 255 ) && + ( b == 0 || b == 51 || b == 102 || + b == 153 || b == 204 || b == 255 ) ); +} + + +void MainForm::editAdd() +{ + QColor color = white; + if ( ! m_colors.isEmpty() ) { + QWidget *visible = colorWidgetStack->visibleWidget(); + if ( visible == tablePage ) + color = colorTable->text( colorTable->currentRow(), + colorTable->currentColumn() ); + else + color = colorIconView->currentItem()->text(); + } + color = QColorDialog::getColor( color, this ); + if ( color.isValid() ) { + QPixmap pixmap( 80, 10 ); + pixmap.fill( color ); + ColorNameForm *colorForm = new ColorNameForm( this, "color", TRUE ); + colorForm->setColors( m_colors ); + colorForm->colorLabel->setPixmap( pixmap ); + if ( colorForm->exec() ) { + QString name = colorForm->colorLineEdit->text(); + m_colors[name] = color; + QPixmap pixmap( 22, 22 ); + pixmap.fill( color ); + int row = colorTable->currentRow(); + colorTable->insertRows( row, 1 ); + colorTable->setText( row, COL_NAME, name ); + colorTable->setPixmap( row, COL_NAME, pixmap ); + colorTable->setText( row, COL_HEX, color.name().upper() ); + if ( m_show_web ) { + QCheckTableItem *item = new QCheckTableItem( colorTable, "" ); + item->setChecked( isWebColor( color ) ); + colorTable->setItem( row, COL_WEB, item ); + } + colorTable->setCurrentCell( row, 0 ); + + (void) new QIconViewItem( colorIconView, name, + colorSwatch( color ) ); + m_changed = TRUE; + } + } +} + +void MainForm::editOptions() +{ + OptionsForm *options = new OptionsForm( this, "options", TRUE ); + switch ( m_clip_as ) { + case CLIP_AS_HEX: + options->hexRadioButton->setChecked( TRUE ); + break; + case CLIP_AS_NAME: + options->nameRadioButton->setChecked( TRUE ); + break; + case CLIP_AS_RGB: + options->rgbRadioButton->setChecked( TRUE ); + break; + } + options->webCheckBox->setChecked( m_show_web ); + + if ( options->exec() ) { + if ( options->hexRadioButton->isChecked() ) + m_clip_as = CLIP_AS_HEX; + else if ( options->nameRadioButton->isChecked() ) + m_clip_as = CLIP_AS_NAME; + else if ( options->rgbRadioButton->isChecked() ) + m_clip_as = CLIP_AS_RGB; + m_table_dirty = m_show_web != + options->webCheckBox->isChecked(); + m_show_web = options->webCheckBox->isChecked(); + + populate(); + } +} + +void MainForm::loadSettings() +{ + QSettings settings; + settings.insertSearchPath( QSettings::Windows, WINDOWS_REGISTRY ); + int windowWidth = settings.readNumEntry( APP_KEY + "WindowWidth", 550 ); + int windowHeight = settings.readNumEntry( APP_KEY + "WindowHeight", 500 ); + int windowX = settings.readNumEntry( APP_KEY + "WindowX", 0 ); + int windowY = settings.readNumEntry( APP_KEY + "WindowY", 0 ); + m_clip_as = settings.readNumEntry( APP_KEY + "ClipAs", CLIP_AS_HEX ); + m_show_web = settings.readBoolEntry( APP_KEY + "ShowWeb", TRUE ); + if ( ! settings.readBoolEntry( APP_KEY + "View", TRUE ) ) { + colorWidgetStack->raiseWidget( iconsPage ); + viewIconsAction->setOn( TRUE ); + } + + resize( windowWidth, windowHeight ); + move( windowX, windowY ); +} + +void MainForm::saveSettings() +{ + QSettings settings; + settings.insertSearchPath( QSettings::Windows, WINDOWS_REGISTRY ); + settings.writeEntry( APP_KEY + "WindowWidth", width() ); + settings.writeEntry( APP_KEY + "WindowHeight", height() ); + settings.writeEntry( APP_KEY + "WindowX", x() ); + settings.writeEntry( APP_KEY + "WindowY", y() ); + settings.writeEntry( APP_KEY + "ClipAs", m_clip_as ); + settings.writeEntry( APP_KEY + "ShowWeb", m_show_web ); + settings.writeEntry( APP_KEY + "View", + colorWidgetStack->visibleWidget() == tablePage ); +} + + +void MainForm::aboutToShow() +{ + populate(); +} diff --git a/tools/designer/examples/colortool/optionsform.ui b/tools/designer/examples/colortool/optionsform.ui new file mode 100644 index 0000000..96d74dc --- /dev/null +++ b/tools/designer/examples/colortool/optionsform.ui @@ -0,0 +1,153 @@ + +OptionsForm + + + OptionsForm + + + + 0 + 0 + 306 + 226 + + + + Color Tool -- Options + + + + unnamed + + + + GroupBox2 + + + Table View + + + + unnamed + + + + webCheckBox + + + Indicate &Web Colors + + + true + + + + + + + ButtonGroup1 + + + Copy to Clipboard As + + + + unnamed + + + + hexRadioButton + + + &Hex, e.g. #AB347F + + + true + + + + + nameRadioButton + + + &Name, e.g. light blue + + + + + rgbRadioButton + + + &RGB, e.g. 51,255,102 + + + + + + + Layout5 + + + + unnamed + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 0 + 10 + + + + + + okPushButton + + + OK + + + true + + + + + cancelPushButton + + + Cancel + + + + + + + + + okPushButton + clicked() + OptionsForm + accept() + + + cancelPushButton + clicked() + OptionsForm + reject() + + + + optionsform.ui.h + + + + diff --git a/tools/designer/examples/colortool/optionsform.ui.h b/tools/designer/examples/colortool/optionsform.ui.h new file mode 100644 index 0000000..f17a035 --- /dev/null +++ b/tools/designer/examples/colortool/optionsform.ui.h @@ -0,0 +1,7 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions use Qt Designer which will +** update this file, preserving your code. Create an init() function in place +** of a constructor, and a destroy() function in place of a destructor. +*****************************************************************************/ diff --git a/tools/designer/examples/credit/credit.pro b/tools/designer/examples/credit/credit.pro new file mode 100644 index 0000000..4dc246d --- /dev/null +++ b/tools/designer/examples/credit/credit.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +LANGUAGE = C++ +TARGET = credit + +SOURCES += main.cpp +HEADERS += creditform.h +SOURCES += creditform.cpp +FORMS = creditformbase.ui +CONFIG += qt warn_on release +DBFILE = credit.db +IMAGEFILE = images.cpp diff --git a/tools/designer/examples/credit/creditform.cpp b/tools/designer/examples/credit/creditform.cpp new file mode 100644 index 0000000..e49fafb --- /dev/null +++ b/tools/designer/examples/credit/creditform.cpp @@ -0,0 +1,20 @@ +#include +#include +#include "creditform.h" + +CreditForm::CreditForm( QWidget* parent, const char* name, + bool modal, WFlags fl ) + : CreditFormBase( parent, name, modal, fl ) +{ + setAmount(); +} + +CreditForm::~CreditForm() { /* NOOP */ } + +void CreditForm::setAmount() +{ + if ( stdRadioButton->isChecked() ) + amountSpinBox->setValue( amountSpinBox->maxValue() / 2 ); + else if ( noneRadioButton->isChecked() ) + amountSpinBox->setValue( amountSpinBox->minValue() ); +} diff --git a/tools/designer/examples/credit/creditform.h b/tools/designer/examples/credit/creditform.h new file mode 100644 index 0000000..ffcec14 --- /dev/null +++ b/tools/designer/examples/credit/creditform.h @@ -0,0 +1,12 @@ +#include "creditformbase.h" + +class CreditForm : public CreditFormBase +{ + Q_OBJECT +public: + CreditForm( QWidget* parent = 0, const char* name = 0, + bool modal = FALSE, WFlags fl = 0 ); + ~CreditForm(); +public slots: + void setAmount(); +}; diff --git a/tools/designer/examples/credit/creditformbase.cpp b/tools/designer/examples/credit/creditformbase.cpp new file mode 100644 index 0000000..46d5adc --- /dev/null +++ b/tools/designer/examples/credit/creditformbase.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'creditformbase.ui' +** +** Created: Fri Aug 10 09:48:16 2001 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#include "creditformbase.h" + +#include // first for gcc 2.7.2 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "creditformbase.ui.h" +#include +#include + +static QPixmap uic_load_pixmap_CreditFormBase( const QString &name ) +{ + const QMimeSource *m = QMimeSourceFactory::defaultFactory()->data( name ); + if ( !m ) + return QPixmap(); + QPixmap pix; + QImageDrag::decode( m, pix ); + return pix; +} +/* + * Constructs a CreditFormBase which is a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +CreditFormBase::CreditFormBase( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "CreditFormBase" ); + resize( 276, 224 ); + setCaption( trUtf8( "Credit Rating", "" ) ); + CreditFormBaseLayout = new QVBoxLayout( this ); + CreditFormBaseLayout->setSpacing( 6 ); + CreditFormBaseLayout->setMargin( 11 ); + + creditButtonGroup = new QButtonGroup( this, "creditButtonGroup" ); + creditButtonGroup->setTitle( trUtf8( "Credit Rating", "" ) ); + creditButtonGroup->setColumnLayout(0, Qt::Vertical ); + creditButtonGroup->layout()->setSpacing( 0 ); + creditButtonGroup->layout()->setMargin( 0 ); + creditButtonGroupLayout = new QVBoxLayout( creditButtonGroup->layout() ); + creditButtonGroupLayout->setAlignment( Qt::AlignTop ); + creditButtonGroupLayout->setSpacing( 6 ); + creditButtonGroupLayout->setMargin( 11 ); + + stdRadioButton = new QRadioButton( creditButtonGroup, "stdRadioButton" ); + stdRadioButton->setText( trUtf8( "&Standard", "" ) ); + stdRadioButton->setChecked( TRUE ); + creditButtonGroupLayout->addWidget( stdRadioButton ); + + noneRadioButton = new QRadioButton( creditButtonGroup, "noneRadioButton" ); + noneRadioButton->setText( trUtf8( "&None", "" ) ); + creditButtonGroupLayout->addWidget( noneRadioButton ); + + specialRadioButton = new QRadioButton( creditButtonGroup, "specialRadioButton" ); + specialRadioButton->setText( trUtf8( "Sp&ecial", "" ) ); + creditButtonGroupLayout->addWidget( specialRadioButton ); + CreditFormBaseLayout->addWidget( creditButtonGroup ); + + amountSpinBox = new QSpinBox( this, "amountSpinBox" ); + amountSpinBox->setEnabled( FALSE ); + amountSpinBox->setPrefix( trUtf8( "$ ", "" ) ); + amountSpinBox->setButtonSymbols( QSpinBox::UpDownArrows ); + amountSpinBox->setMaxValue( 100000 ); + amountSpinBox->setLineStep( 10000 ); + CreditFormBaseLayout->addWidget( amountSpinBox ); + + Layout4 = new QHBoxLayout; + Layout4->setSpacing( 6 ); + Layout4->setMargin( 0 ); + QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + Layout4->addItem( spacer ); + + okPushButton = new QPushButton( this, "okPushButton" ); + okPushButton->setText( trUtf8( "OK", "" ) ); + okPushButton->setDefault( TRUE ); + Layout4->addWidget( okPushButton ); + QSpacerItem* spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + Layout4->addItem( spacer_2 ); + + cancelPushButton = new QPushButton( this, "cancelPushButton" ); + cancelPushButton->setText( trUtf8( "Cancel", "" ) ); + Layout4->addWidget( cancelPushButton ); + QSpacerItem* spacer_3 = new QSpacerItem( 20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + Layout4->addItem( spacer_3 ); + CreditFormBaseLayout->addLayout( Layout4 ); + + + + + + // signals and slots connections + connect( okPushButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( cancelPushButton, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( creditButtonGroup, SIGNAL( clicked(int) ), this, SLOT( setAmount() ) ); + connect( specialRadioButton, SIGNAL( toggled(bool) ), amountSpinBox, SLOT( setEnabled(bool) ) ); +} + +/* + * Destroys the object and frees any allocated resources + */ +CreditFormBase::~CreditFormBase() +{ + // no need to delete child widgets, Qt does it all for us +} + diff --git a/tools/designer/examples/credit/creditformbase.h b/tools/designer/examples/credit/creditformbase.h new file mode 100644 index 0000000..6d5e934 --- /dev/null +++ b/tools/designer/examples/credit/creditformbase.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'creditformbase.ui' +** +** Created: Fri Aug 10 09:48:10 2001 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#ifndef CREDITFORMBASE_H +#define CREDITFORMBASE_H + +#include +#include +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QButtonGroup; +class QPushButton; +class QRadioButton; +class QSpinBox; + +class CreditFormBase : public QDialog +{ + Q_OBJECT + +public: + CreditFormBase( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CreditFormBase(); + + QButtonGroup* creditButtonGroup; + QRadioButton* stdRadioButton; + QRadioButton* noneRadioButton; + QRadioButton* specialRadioButton; + QSpinBox* amountSpinBox; + QPushButton* okPushButton; + QPushButton* cancelPushButton; + + +public slots: + virtual void setAmount(); + +protected: + QVBoxLayout* CreditFormBaseLayout; + QVBoxLayout* creditButtonGroupLayout; + QHBoxLayout* Layout4; +}; + +#endif // CREDITFORMBASE_H diff --git a/tools/designer/examples/credit/creditformbase.ui b/tools/designer/examples/credit/creditformbase.ui new file mode 100644 index 0000000..4421885 --- /dev/null +++ b/tools/designer/examples/credit/creditformbase.ui @@ -0,0 +1,212 @@ + +CreditFormBase +creditformbase.ui.h + + + + + CreditFormBase + + + + 0 + 0 + 276 + 224 + + + + Credit Rating + + + + unnamed + + + 11 + + + 6 + + + + creditButtonGroup + + + Credit Rating + + + + unnamed + + + 11 + + + 6 + + + + stdRadioButton + + + &Standard + + + true + + + + + noneRadioButton + + + &None + + + + + specialRadioButton + + + Sp&ecial + + + + + + + amountSpinBox + + + false + + + $ + + + UpDownArrows + + + 100000 + + + 10000 + + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okPushButton + + + OK + + + true + + + + + Spacer1_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + cancelPushButton + + + Cancel + + + + + Spacer1_3 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + + + okPushButton + clicked() + CreditFormBase + accept() + + + cancelPushButton + clicked() + CreditFormBase + reject() + + + creditButtonGroup + clicked(int) + CreditFormBase + setAmount() + + + specialRadioButton + toggled(bool) + amountSpinBox + setEnabled(bool) + + setAmount() + + diff --git a/tools/designer/examples/credit/creditformbase.ui.h b/tools/designer/examples/credit/creditformbase.ui.h new file mode 100644 index 0000000..6cf4faa --- /dev/null +++ b/tools/designer/examples/credit/creditformbase.ui.h @@ -0,0 +1,5 @@ +void CreditFormBase::setAmount() +{ + +} + diff --git a/tools/designer/examples/credit/main.cpp b/tools/designer/examples/credit/main.cpp new file mode 100644 index 0000000..dde1daa --- /dev/null +++ b/tools/designer/examples/credit/main.cpp @@ -0,0 +1,25 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include "creditform.h" + + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + CreditForm creditForm; + app.setMainWidget( &creditForm ); + creditForm.show(); + + return app.exec(); +} + + diff --git a/tools/designer/examples/filechooser/plugin/plugin.cpp b/tools/designer/examples/filechooser/plugin/plugin.cpp new file mode 100644 index 0000000..9408cac --- /dev/null +++ b/tools/designer/examples/filechooser/plugin/plugin.cpp @@ -0,0 +1,95 @@ +#include "plugin.h" +#include "../widget/filechooser.h" + +static const char *filechooser_pixmap[] = { + "22 22 8 1", + " c Gray100", + ". c Gray97", + "X c #4f504f", + "o c #00007f", + "O c Gray0", + "+ c none", + "@ c Gray0", + "# c Gray0", + "++++++++++++++++++++++", + "++++++++++++++++++++++", + "++++++++++++++++++++++", + "++++++++++++++++++++++", + "+OOOOOOOOOOOOOOOOOOOO+", + "OOXXXXXXXXXXXXXXXXXXOO", + "OXX. OO OO O", + "OX. oo O O", + "OX. oo O .O", + "OX ooo oooo O O", + "OX oo oo oo O O", + "OX oooo oo oo O O", + "OX oo oo oo oo O O", + "OX oo oo oo oo O O", + "OX oooo oooo O O", + "OX OO OO O", + "OO..................OO", + "+OOOOOOOOOOOOOOOOOOOO+", + "++++++++++++++++++++++", + "++++++++++++++++++++++", + "++++++++++++++++++++++", + "++++++++++++++++++++++" +}; + +CustomWidgetPlugin::CustomWidgetPlugin() +{ +} + +QStringList CustomWidgetPlugin::keys() const +{ + QStringList list; + list << "FileChooser"; + return list; +} + +QWidget* CustomWidgetPlugin::create( const QString &key, QWidget* parent, const char* name ) +{ + if ( key == "FileChooser" ) + return new FileChooser( parent, name ); + return 0; +} + +QString CustomWidgetPlugin::group( const QString& feature ) const +{ + if ( feature == "FileChooser" ) + return "Input"; + return QString::null; +} + +QIconSet CustomWidgetPlugin::iconSet( const QString& ) const +{ + return QIconSet( QPixmap( filechooser_pixmap ) ); +} + +QString CustomWidgetPlugin::includeFile( const QString& feature ) const +{ + if ( feature == "FileChooser" ) + return "filechooser.h"; + return QString::null; +} + +QString CustomWidgetPlugin::toolTip( const QString& feature ) const +{ + if ( feature == "FileChooser" ) + return "File Chooser Widget"; + return QString::null; +} + +QString CustomWidgetPlugin::whatsThis( const QString& feature ) const +{ + if ( feature == "FileChooser" ) + return "A widget to choose a file or directory"; + return QString::null; +} + +bool CustomWidgetPlugin::isContainer( const QString& ) const +{ + return FALSE; +} + + +Q_EXPORT_PLUGIN( CustomWidgetPlugin ) diff --git a/tools/designer/examples/filechooser/plugin/plugin.h b/tools/designer/examples/filechooser/plugin/plugin.h new file mode 100644 index 0000000..a465c29 --- /dev/null +++ b/tools/designer/examples/filechooser/plugin/plugin.h @@ -0,0 +1,16 @@ +#include + +class CustomWidgetPlugin : public QWidgetPlugin +{ +public: + CustomWidgetPlugin(); + + QStringList keys() const; + QWidget* create( const QString &classname, QWidget* parent = 0, const char* name = 0 ); + QString group( const QString& ) const; + QIconSet iconSet( const QString& ) const; + QString includeFile( const QString& ) const; + QString toolTip( const QString& ) const; + QString whatsThis( const QString& ) const; + bool isContainer( const QString& ) const; +}; diff --git a/tools/designer/examples/filechooser/plugin/plugin.pro b/tools/designer/examples/filechooser/plugin/plugin.pro new file mode 100644 index 0000000..012f185 --- /dev/null +++ b/tools/designer/examples/filechooser/plugin/plugin.pro @@ -0,0 +1,14 @@ +TEMPLATE = lib +LANGUAGE = C++ +TARGET = filechooser + +SOURCES += plugin.cpp ../widget/filechooser.cpp +HEADERS += plugin.h ../widget/filechooser.h +DESTDIR = ../../../../../plugins/designer + +target.path=$$plugins.path + +INSTALLS += target +CONFIG += qt warn_on release plugin +INCLUDEPATH += $$QT_SOURCE_TREE/tools/designer/interfaces +DBFILE = plugin.db diff --git a/tools/designer/examples/filechooser/widget/filechooser.cpp b/tools/designer/examples/filechooser/widget/filechooser.cpp new file mode 100644 index 0000000..4575bd4 --- /dev/null +++ b/tools/designer/examples/filechooser/widget/filechooser.cpp @@ -0,0 +1,62 @@ +#include "filechooser.h" +#include +#include +#include +#include + +FileChooser::FileChooser( QWidget *parent, const char *name ) + : QWidget( parent, name ), md( File ) +{ + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->setMargin( 0 ); + + lineEdit = new QLineEdit( this, "filechooser_lineedit" ); + layout->addWidget( lineEdit ); + + connect( lineEdit, SIGNAL( textChanged( const QString & ) ), + this, SIGNAL( fileNameChanged( const QString & ) ) ); + + button = new QPushButton( "...", this, "filechooser_button" ); + button->setFixedWidth( button->fontMetrics().width( " ... " ) ); + layout->addWidget( button ); + + connect( button, SIGNAL( clicked() ), + this, SLOT( chooseFile() ) ); + + setFocusProxy( lineEdit ); +} + +void FileChooser::setMode( Mode m ) +{ + md = m; +} + +FileChooser::Mode FileChooser::mode() const +{ + return md; +} + +void FileChooser::setFileName( const QString &fn ) +{ + lineEdit->setText( fn ); +} + +QString FileChooser::fileName() const +{ + return lineEdit->text(); +} + +void FileChooser::chooseFile() +{ + QString fn; + if ( mode() == File ) + fn = QFileDialog::getOpenFileName( lineEdit->text(), QString::null, this ); + else + fn = QFileDialog::getExistingDirectory( lineEdit->text(),this ); + + if ( !fn.isEmpty() ) { + lineEdit->setText( fn ); + emit fileNameChanged( fn ); + } +} + diff --git a/tools/designer/examples/filechooser/widget/filechooser.h b/tools/designer/examples/filechooser/widget/filechooser.h new file mode 100644 index 0000000..23272c0 --- /dev/null +++ b/tools/designer/examples/filechooser/widget/filechooser.h @@ -0,0 +1,48 @@ +#ifndef FILECHOOSER_H +#define FILECHOOSER_H + +#include +#include + +class QLineEdit; +class QPushButton; + +#ifdef FILECHOOSER_IS_WIDGET +#undef QT_WIDGET_PLUGIN_EXPORT +#define QT_WIDGET_PLUGIN_EXPORT +#endif + +class QT_WIDGET_PLUGIN_EXPORT FileChooser : public QWidget +{ + Q_OBJECT + + Q_ENUMS( Mode ) + Q_PROPERTY( Mode mode READ mode WRITE setMode ) + Q_PROPERTY( QString fileName READ fileName WRITE setFileName ) + +public: + FileChooser( QWidget *parent = 0, const char *name = 0); + + enum Mode { File, Directory }; + + QString fileName() const; + Mode mode() const; + +public slots: + void setFileName( const QString &fn ); + void setMode( Mode m ); + +signals: + void fileNameChanged( const QString & ); + +private slots: + void chooseFile(); + +private: + QLineEdit *lineEdit; + QPushButton *button; + Mode md; + +}; + +#endif diff --git a/tools/designer/examples/filechooser/widget/filechooser.pro b/tools/designer/examples/filechooser/widget/filechooser.pro new file mode 100644 index 0000000..20ea787 --- /dev/null +++ b/tools/designer/examples/filechooser/widget/filechooser.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +LANGUAGE = C++ +TARGET = filechooser + +SOURCES += filechooser.cpp main.cpp +HEADERS += filechooser.h +CONFIG += qt warn_on release +DBFILE = filechooser.db +DEFINES += FILECHOOSER_IS_WIDGET diff --git a/tools/designer/examples/filechooser/widget/main.cpp b/tools/designer/examples/filechooser/widget/main.cpp new file mode 100644 index 0000000..cc39053 --- /dev/null +++ b/tools/designer/examples/filechooser/widget/main.cpp @@ -0,0 +1,10 @@ +#include +#include "filechooser.h" + +int main( int argc, char ** argv ) +{ + QApplication a( argc, argv ); + FileChooser *fc = new FileChooser; + fc->show(); + return a.exec(); +} diff --git a/tools/designer/examples/metric/main.cpp b/tools/designer/examples/metric/main.cpp new file mode 100644 index 0000000..6490b58 --- /dev/null +++ b/tools/designer/examples/metric/main.cpp @@ -0,0 +1,12 @@ +#include +#include "metric.h" + +int main( int argc, char ** argv ) +{ + QApplication a( argc, argv ); + ConversionForm *w = new ConversionForm; + w->show(); + a.setMainWidget( w ); + a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); + return a.exec(); +} diff --git a/tools/designer/examples/metric/metric.pro b/tools/designer/examples/metric/metric.pro new file mode 100644 index 0000000..3dfc3fd --- /dev/null +++ b/tools/designer/examples/metric/metric.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +LANGUAGE = C++ + +SOURCES += main.cpp +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj +} +FORMS = metric.ui +CONFIG += qt warn_on release +DBFILE = metric.db diff --git a/tools/designer/examples/metric/metric.ui b/tools/designer/examples/metric/metric.ui new file mode 100644 index 0000000..b0c9166 --- /dev/null +++ b/tools/designer/examples/metric/metric.ui @@ -0,0 +1,366 @@ + +ConversionForm + + + ConversionForm + + + + 0 + 0 + 320 + 217 + + + + Metric Conversion + + + true + + + + unnamed + + + + Layout4 + + + + unnamed + + + + Layout3 + + + + unnamed + + + + Spacer3 + + + Horizontal + + + Expanding + + + + 0 + 20 + + + + + + decimalsSpinBox + + + 6 + + + 3 + + + + + + + + Kilometers + + + + + Meters + + + + + Centimeters + + + + + Millimeters + + + + fromComboBox + + + + + TextLabel4 + + + Result: + + + + + TextLabel2 + + + Convert &From: + + + fromComboBox + + + + + TextLabel3 + + + Convert &To: + + + toComboBox + + + + + TextLabel1_2 + + + &Decimals: + + + decimalsSpinBox + + + + + TextLabel1 + + + Enter &Number: + + + numberLineEdit + + + + + resultLineEdit + + + + 255 + 255 + 0 + + + + + 1 + + + + WinPanel + + + Sunken + + + + + + AlignVCenter|AlignRight + + + + + numberLineEdit + + + + 1 + + + + AlignRight + + + + + + Miles + + + + + Yards + + + + + Feet + + + + + Inches + + + + toComboBox + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 0 + + + + + + Layout3 + + + + unnamed + + + + clearButton + + + &Clear + + + + + calculateButton + + + Calculate + + + true + + + + + Spacer27 + + + Horizontal + + + Expanding + + + + 0 + 20 + + + + + + quitButton + + + &Quit + + + + + + + + + clearButton + clicked() + numberLineEdit + clear() + + + quitButton + clicked() + ConversionForm + close() + + + calculateButton + clicked() + ConversionForm + convert() + + + clearButton + clicked() + resultLineEdit + clear() + + + decimalsSpinBox + valueChanged(int) + ConversionForm + convert() + + + fromComboBox + activated(int) + ConversionForm + convert() + + + toComboBox + activated(int) + ConversionForm + convert() + + + clearButton + released() + numberLineEdit + setFocus() + + + calculateButton + clicked() + numberLineEdit + setFocus() + + + + numberLineEdit + fromComboBox + toComboBox + decimalsSpinBox + clearButton + calculateButton + quitButton + + + metric.ui.h + + + convert() + + + init() + + + + diff --git a/tools/designer/examples/metric/metric.ui.h b/tools/designer/examples/metric/metric.ui.h new file mode 100644 index 0000000..ba66022 --- /dev/null +++ b/tools/designer/examples/metric/metric.ui.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions respectively slots use +** Qt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + +#include + +void ConversionForm::init() +{ + numberLineEdit->setValidator( new QDoubleValidator( numberLineEdit ) ); + numberLineEdit->setText( "10" ); + convert(); + numberLineEdit->selectAll(); +} + +void ConversionForm::convert() +{ + enum MetricUnits { + Kilometers, + Meters, + Centimeters, + Millimeters + }; + enum OldUnits { + Miles, + Yards, + Feet, + Inches + }; + + // Retrieve the input + double input = numberLineEdit->text().toDouble(); + double scaledInput = input; + + // internally convert the input to millimeters + switch ( fromComboBox->currentItem() ) { + case Kilometers: + scaledInput *= 1000000; + break; + case Meters: + scaledInput *= 1000; + break; + case Centimeters: + scaledInput *= 10; + break; + } + + //convert to inches + double result = scaledInput * 0.0393701; + + switch ( toComboBox->currentItem() ) { + case Miles: + result /= 63360; + break; + case Yards: + result /= 36; + break; + case Feet: + result /= 12; + break; + } + + // set the result + int decimals = decimalsSpinBox->value(); + resultLineEdit->setText( QString::number( result, 'f', decimals ) ); + numberLineEdit->setText( QString::number( input, 'f', decimals ) ); +} + diff --git a/tools/designer/examples/multiclip/main.cpp b/tools/designer/examples/multiclip/main.cpp new file mode 100644 index 0000000..7f3aeb1 --- /dev/null +++ b/tools/designer/examples/multiclip/main.cpp @@ -0,0 +1,25 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include "multiclip.h" + + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + MulticlipForm clippingForm; + app.setMainWidget( &clippingForm ); + clippingForm.show(); + + return app.exec(); +} + + diff --git a/tools/designer/examples/multiclip/multiclip.pro b/tools/designer/examples/multiclip/multiclip.pro new file mode 100644 index 0000000..f9391cb --- /dev/null +++ b/tools/designer/examples/multiclip/multiclip.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +LANGUAGE = C++ +TARGET = multiclip + +SOURCES += main.cpp +FORMS = multiclip.ui +CONFIG += qt warn_on release +DBFILE = multiclip.db +IMAGEFILE = images.cpp diff --git a/tools/designer/examples/multiclip/multiclip.ui b/tools/designer/examples/multiclip/multiclip.ui new file mode 100644 index 0000000..47bbd2f --- /dev/null +++ b/tools/designer/examples/multiclip/multiclip.ui @@ -0,0 +1,206 @@ + +MulticlipForm +qclipboard.h +qapplication.h +multiclip.ui.h +QClipboard *cb; + + + + + MulticlipForm + + + + 0 + 0 + 585 + 472 + + + + Multiclip + + + + unnamed + + + 11 + + + 6 + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + Current Clipping + + + + + currentLineEdit + + + + + + + Layout19 + + + + unnamed + + + 0 + + + 6 + + + + addPushButton + + + &Add Clipping + + + + + Spacer4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + quitPushButton + + + &Quit + + + + + TextLabel3 + + + Length + + + + + TextLabel2 + + + Previous Clippings + + + + + autoCheckBox + + + A&uto Add Clippings + + + + + lengthLCDNumber + + + + + deletePushButton + + + &Delete Clipping + + + + + clippingsListBox + + + + + copyPushButton + + + &Copy Previous + + + + + + + + + quitPushButton + clicked() + MulticlipForm + accept() + + + addPushButton + clicked() + MulticlipForm + addClipping() + + + copyPushButton + pressed() + MulticlipForm + copyPrevious() + + + deletePushButton + clicked() + MulticlipForm + deleteClipping() + + addClipping() + dataChanged() + deleteClipping() + init() + selectionChanged() + copyPrevious() + clippingChanged( const QString & clipping ) + + + currentLineEdit + clippingsListBox + autoCheckBox + addPushButton + copyPushButton + deletePushButton + quitPushButton + + diff --git a/tools/designer/examples/multiclip/multiclip.ui.h b/tools/designer/examples/multiclip/multiclip.ui.h new file mode 100644 index 0000000..e4d7fc1 --- /dev/null +++ b/tools/designer/examples/multiclip/multiclip.ui.h @@ -0,0 +1,70 @@ +void MulticlipForm::addClipping() +{ + QString text = currentLineEdit->text(); + if ( ! text.isEmpty() ) { + lengthLCDNumber->display( (int)text.length() ); + int i = 0; + for ( ; i < (int)clippingsListBox->count(); i++ ) { + if ( clippingsListBox->text( i ) == text ) { + i = -1; // Do not add duplicates + break; + } + } + if ( i != -1 ) + clippingsListBox->insertItem( text, 0 ); + } +} + +void MulticlipForm::dataChanged() +{ + QString text; + text = cb->text(); + clippingChanged( text ); + if ( autoCheckBox->isChecked() ) + addClipping(); +} + +void MulticlipForm::deleteClipping() +{ + clippingChanged( "" ); + clippingsListBox->removeItem( clippingsListBox->currentItem() ); +} + +void MulticlipForm::init() +{ + lengthLCDNumber->setBackgroundColor( darkBlue ); + currentLineEdit->setFocus(); + + cb = qApp->clipboard(); + connect( cb, SIGNAL( dataChanged() ), SLOT( dataChanged() ) ); + if ( cb->supportsSelection() ) + connect( cb, SIGNAL( selectionChanged() ), SLOT( selectionChanged() ) ); + + dataChanged(); +} + +void MulticlipForm::selectionChanged() +{ + cb->setSelectionMode( TRUE ); + dataChanged(); + cb->setSelectionMode( FALSE ); +} + +void MulticlipForm::copyPrevious() +{ + if ( clippingsListBox->currentItem() != -1 ) { + cb->setText( clippingsListBox->currentText() ); + if ( cb->supportsSelection() ) { + cb->setSelectionMode( TRUE ); + cb->setText( clippingsListBox->currentText() ); + cb->setSelectionMode( FALSE ); + } + } +} + +void MulticlipForm::clippingChanged( const QString & clipping ) +{ + currentLineEdit->setText( clipping ); + lengthLCDNumber->display( (int)clipping.length() ); +} + diff --git a/tools/designer/examples/opengl/glwidget.cpp b/tools/designer/examples/opengl/glwidget.cpp new file mode 100644 index 0000000..72692a3 --- /dev/null +++ b/tools/designer/examples/opengl/glwidget.cpp @@ -0,0 +1,170 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "glwidget.h" + +/*! + Create a GLWidget widget +*/ + +GLWidget::GLWidget( QWidget* parent, const char* name ) + : QGLWidget( parent, name ) +{ + xrot = yrot = zrot = 25; // default object rotation + scale_ = 1.25; // default object scale + object = 0; +} + +/*! + Release allocated resources +*/ + +GLWidget::~GLWidget() +{ + glDeleteLists( object, 1 ); +} + + +/*! + Paint the box. The actual openGL commands for drawing the box are + performed here. +*/ + +void GLWidget::paintGL() +{ + glClear( GL_COLOR_BUFFER_BIT ); + + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -10.0 ); + glScalef( scale_, scale_, scale_ ); + + glRotatef( xrot, 1.0, 0.0, 0.0 ); + glRotatef( yrot, 0.0, 1.0, 0.0 ); + glRotatef( zrot, 0.0, 0.0, 1.0 ); + + glCallList( object ); +} + +/*! + Set up the OpenGL rendering state, and define display list +*/ + +void GLWidget::initializeGL() +{ + qglClearColor( black ); // Let OpenGL clear to black + object = makeObject(); // Generate an OpenGL display list + glShadeModel( GL_FLAT ); +} + + + +/*! + Set up the OpenGL view port, matrix mode, etc. +*/ + +void GLWidget::resizeGL( int w, int h ) +{ + glViewport( 0, 0, (GLint)w, (GLint)h ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 ); + glMatrixMode( GL_MODELVIEW ); +} + + +/*! + Generate an OpenGL display list for the object to be shown, i.e. the box +*/ + +GLuint GLWidget::makeObject() +{ + GLuint list; + + list = glGenLists( 1 ); + + glNewList( list, GL_COMPILE ); + + qglColor( white ); // Shorthand for glColor3f or glIndex + + glLineWidth( 2.0 ); + + glBegin( GL_LINE_LOOP ); + glVertex3f( 1.0f, 0.5f, -0.4f ); + glVertex3f( 1.0f, -0.5f, -0.4f ); + glVertex3f( -1.0f, -0.5f, -0.4f ); + glVertex3f( -1.0f, 0.5f, -0.4f ); + glEnd(); + + glBegin( GL_LINE_LOOP ); + glVertex3f( 1.0f, 0.5f, 0.4f ); + glVertex3f( 1.0f, -0.5f, 0.4f ); + glVertex3f( -1.0f, -0.5f, 0.4f ); + glVertex3f( -1.0f, 0.5f, 0.4f ); + glEnd(); + + glBegin( GL_LINES ); + glVertex3f( 1.0f, 0.5f, -0.4f ); glVertex3f( 1.0f, 0.5f, 0.4f ); + glVertex3f( 1.0f, -0.5f, -0.4f ); glVertex3f( 1.0f, -0.5f, 0.4f ); + glVertex3f( -1.0f, -0.5f, -0.4f ); glVertex3f( -1.0f, -0.5f, 0.4f ); + glVertex3f( -1.0f, 0.5f, -0.4f ); glVertex3f( -1.0f, 0.5f, 0.4f ); + glEnd(); + + glEndList(); + + return list; +} + +void GLWidget::setXRot( double x ) +{ + xrot = x; + update(); +} + +void GLWidget::setYRot( double y ) +{ + yrot = y; + update(); +} + +void GLWidget::setZRot( double z ) +{ + zrot = z; + update(); +} + +void GLWidget::setScale( double s ) +{ + scale_ = s; + update(); +} diff --git a/tools/designer/examples/opengl/glwidget.h b/tools/designer/examples/opengl/glwidget.h new file mode 100644 index 0000000..fd34d4a --- /dev/null +++ b/tools/designer/examples/opengl/glwidget.h @@ -0,0 +1,75 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef GLWIDGET_H +#define GLWIDGET_H + +#include + +class GLWidget : public QGLWidget +{ + Q_OBJECT + Q_PROPERTY( double xRot READ xRot WRITE setXRot ) + Q_PROPERTY( double yRot READ yRot WRITE setYRot ) + Q_PROPERTY( double zRot READ zRot WRITE setZRot ) + Q_PROPERTY( double scale READ scale WRITE setScale ) + +public: + GLWidget( QWidget* parent, const char* name ); + ~GLWidget(); + + double xRot() const { return xrot; } + double yRot() const { return yrot; } + double zRot() const { return zrot; } + double scale() const { return scale_; } + +public slots: + void setXRot( double ); + void setYRot( double ); + void setZRot( double ); + void setScale( double ); + +protected: + void initializeGL(); + void paintGL(); + void resizeGL( int w, int h ); + + virtual GLuint makeObject(); + +private: + GLuint object; + GLfloat xrot, yrot, zrot, scale_; +}; + +#endif diff --git a/tools/designer/examples/opengl/main.cpp b/tools/designer/examples/opengl/main.cpp new file mode 100644 index 0000000..3b6bd29 --- /dev/null +++ b/tools/designer/examples/opengl/main.cpp @@ -0,0 +1,305 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +#include +#include + +#include "glwidget.h" + +/* XPM */ +static char * cube_xmp[] = { +"48 48 104 2", +" c None", +". c #30C230C22081", +"X c #30C230C230C2", +"o c #30C2410330C2", +"O c #410330C24103", +"+ c #410341034103", +"@ c #514451445144", +"# c #514461855144", +"$ c #618551446185", +"% c #618561856185", +"& c #71C671C671C6", +"* c #71C6820771C6", +"= c #965882078617", +"- c #861792488617", +"; c #965892489658", +": c #9658A2899658", +"> c #9E79A2899E79", +", c #AEBAAEBA9E79", +"< c #AEBAAEBAAEBA", +"1 c #AEBABEFBAEBA", +"2 c #BEFBBEFBBEFB", +"3 c #CF3CBEFBCF3C", +"4 c #CF3CCF3CCF3C", +"5 c #DF7DCF3CCF3C", +"6 c #DF7DDF7DCF3C", +"7 c #DF7DDF7DDF7D", +"8 c #EFBEDF7DDF7D", +"9 c #DF7DEFBEDF7D", +"0 c #EFBEDF7DEFBE", +"q c #EFBEEFBEDF7D", +"w c #208130C22081", +"e c #410351445144", +"r c #514451446185", +"t c #71C6618571C6", +"y c #861771C68617", +"u c #9E7992489E79", +"i c #9E79AEBA9E79", +"p c #BEFBAEBABEFB", +"a c #BEFBCF3CBEFB", +"s c #BEFBCF3CCF3C", +"d c #CF3CCF3CDF7D", +"f c #CF3CDF7DCF3C", +"g c #DF7DDF7DEFBE", +"h c #208120812081", +"j c #30C2208130C2", +"k c #410330C230C2", +"l c #4103410330C2", +"z c #410351444103", +"x c #618551445144", +"c c #618561855144", +"v c #618571C66185", +"b c #861771C671C6", +"n c #8617820771C6", +"m c #965882079658", +"M c #9E7992489658", +"N c #AEBAA289AEBA", +"B c #BEFBAEBAAEBA", +"V c #DF7DCF3CDF7D", +"C c #CF3CDF7DDF7D", +"Z c #208120811040", +"A c #965892488617", +"S c #104020812081", +"D c #861782078617", +"F c #861792489658", +"G c #965892489E79", +"H c #104020811040", +"J c #208110402081", +"K c #30C220812081", +"L c #BEFBBEFBCF3C", +"P c #104010401040", +"I c #208110401040", +"U c #618571C671C6", +"Y c #71C671C68617", +"T c #71C682078617", +"R c #CF3CBEFBBEFB", +"E c #CF3CCF3CBEFB", +"W c #000010401040", +"Q c #104010402081", +"! c #9E79AEBAAEBA", +"~ c #104010400000", +"^ c #AEBAA2899E79", +"/ c #71C671C66185", +"( c #000010400000", +") c #000000000000", +"_ c #104000001040", +"` c #2081208130C2", +"' c #9658A2899E79", +"] c #104000000000", +"[ c #000000001040", +"{ c #30C241034103", +"} c #9E79A289AEBA", +"| c #AEBABEFBBEFB", +" . c #514461856185", +".. c #9E79A2899658", +"X. c #71C661856185", +"o. c #30C230C24103", +"O. c #514441035144", +"+. c #514451444103", +"@. c #410341035144", +"#. c #AEBAAEBABEFB", +"$. c #208130C230C2", +"%. c #6185618571C6", +"&. c #514441034103", +"*. c #861782079658", +" . X o O + @ # $ % & * = - ; : > , < 1 2 2 3 4 5 6 7 7 8 9 0 q ", +" w X X O + @ e r % t & y - ; : u i < < p a 3 s d f 7 7 g 9 0 9 ; ", +" h j X k l + z x c t v b n m ; M > N < B 2 2 a 3 4 V 6 7 7 0 9 m ; ", +" h h w X f d f d f V f V f 7 f 7 C 7 f V f V f d f V f 7 9 g 9 m ; ; ", +" Z h w j - 4 4 5 4 5 4 5 4 V f V 6 V f V f V 4 5 4 5 4 V 7 7 7 m A ; ; ", +" S h h j - D s 4 4 4 4 4 4 4 4 d f V f d f d 4 d 4 4 4 V C 7 7 m - ; F G ", +" H J Z K * D D m ; M 5 4 V 7 = D m - ; ; ", +" H h S h * y D L F ; : 4 f V C D D m a ; ; G ", +" P I H J & b n 2 2 m A M 3 4 5 f y D = 2 2 A ; ; ", +" P P H J U Y & p 1 2 - ; : 4 4 d f y T D 1 p 1 ; F G ", +" P P H J % t & < < < m ; u R E 4 f b * y B < < A ; ; ", +" W P P Q % t v < ! < - ; : L a 4 4 & * y < < ! ; ; G ", +" ~ P ~ I c $ % > ^ > m ; M 2 2 3 4 t / b ^ i ^ ; M ; ", +" ( P W P # $ % > > > F ; : p a 3 s t U & > > > ; ; G ", +" ) _ ( _ @ $ # M ; u m ; u p 2 2 a % v t M ; u ; M ; ", +" ( _ ( P P P H h h ` w X o : ; F F ; : & * D - G ' > i < 1 2 a % v t : ; F ; : u ", +" ) ] ( _ ~ P P I Z h w j X O m - m ; ; M & y - m ; > i N < 2 2 $ c % m - m ; M : ", +") [ ( _ W P P Q H h h j X O { D D - F G : y T m ; u > } < p | r .% D D - G : u ", +"V f 5 4 5 f V f V f V f V f V y * y m ; u f 5 f V f 5 4 V f x @ $ y * y : u ..", +"4 d f 4 f d f d 4 d f V f V f U & U F G : d f d f d f 4 4 d @ r # U & U G : > ", +"3 4 3 E 4 E 4 4 3 4 4 4 5 4 5 t v X.; ; u 4 4 4 4 E 4 E 3 4 @ @ x t v X.; u ..", +"a 4 a o.{ + .% v ; G > 3 a 4 e @ # .% v u ' > ", +"3 2 3 X O o $ # $ ; ; u 2 3 2 O.+.@ $ # $ : u > ", +"a 2 a X o + @ @ @ ; u ' 2 2 2 z @ @ @ @ @ u > } ", +"p < p X k l O.z O.; : u 1 p < O.+.@ O.z O...> i ", +"1 < 1 o.o + @.z @.; G > #.1 < z O.@ + @.z > > } ", +"N , N X O o l + o ; ; u 1 1 1 O.+.@ O l + : u > ", +"i } i o.o + O o o.; u o + z @ # % v } i } e @ @ } < #.| L a 4 f V o o.o G ' > ", +"> ..u o O + . X . ; o O + O.@ $ % & u u ..@ @ x , < 1 2 2 3 4 5 6 X . X ; u ..", +"' u : O + + j $.j $.o.{ O.e r % %.U G : u @ r # < < p 2 3 s d f 7 $.j $.u : u ", +"; A M l + + h j . K h j h K h h h h ; ; A x @ $ h h h h h K h j 6 7 7 0 : u ..", +"- m - + { @. h h w %.w h h h h h S h S m - m # r # h S h S h h h f 7 9 g F G : ", +"y D D l + + Z h h t % h Z J Z J Z J Z J D y D x # $ H J Z J Z J f V 7 7 - M ; ", +"* y * + z O. S h h & U t y * y @ $ . 4 d C 7 - m ; ", +"& / b l + + P J Z y & t & & / x c $ E 5 4 V n = D ", +"v %.v + z O. H J H D * & & v %.# % . a 4 f V * D - ", +"X.% % + &.z P P H D n y c $ % $ c $ a 3 4 V * y D ", +"# $ # + z @ P P H J m - D $ # $ # $ % 2 3 4 d * y T ", +"@ @ x + + z W P P Q m D m @ @ @ $ c % 2 R E 4 & b * ", +"z O.e + z @ P ~ I ; ; *. @ z O. .% % L s 4 U & * ", +"&.+ &.l &.+.W P M ; m + &.+ $ c X.2 3 v t & ", +"{ + { @.z O._ u ' ; + { + .$ % 3 v t & ", +"O o k + O.P P P H h h ` w X o l + z @ c X./ b n m ; u o O o $ % % % t v ", +"$.X $.@._ ~ P P I Z h w j X O + + @ # % v & * D - ; : X $.X .% v %.v ", +"j . j _ W P P Q H h h j X O { + &.@ $ c t & y D m ; > . j . % c X.% ", +"w j w ` w j w ` w ` h ` h h S h h h h ` h ` w ` w j w ` w j .% % ", +"h h K h h h h h h h J h J H J Z J H J h h h h h h h J h h h $ % ", +"S h h h H h S h S h S h H Q H J H Q H h H h S h S h S h S h . "}; + + +class OpenGLWidgetInterface : public WidgetInterface +{ +public: + OpenGLWidgetInterface(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface ** ); + Q_REFCOUNT; + + QStringList featureList() const; + + QWidget* create( const QString &classname, QWidget* parent = 0, const char* name = 0 ); + QString group( const QString& ) const; + QIconSet iconSet( const QString& ) const; + QString includeFile( const QString& ) const; + QString toolTip( const QString& ) const; + QString whatsThis( const QString& ) const; + bool isContainer( const QString& ) const; + +private: + QObjectCleanupHandler objects; +}; + +OpenGLWidgetInterface::OpenGLWidgetInterface() +{ +} + +QStringList OpenGLWidgetInterface::featureList() const +{ + QStringList list; + + list << "GLWidget"; + + return list; +} + +QWidget* OpenGLWidgetInterface::create( const QString &description, QWidget* parent, const char* name ) +{ + QWidget* w = 0; + + if ( description == "GLWidget" ) + w = new GLWidget( parent, name ); + + objects.add( w ); + return w; +} + +QString OpenGLWidgetInterface::group( const QString &description ) const +{ + if ( description == "GLWidget" ) + return "Views"; + return QString::null; +} + +QIconSet OpenGLWidgetInterface::iconSet( const QString &description ) const +{ + if ( description == "GLWidget" ) + return QIconSet( (const char**)cube_xmp ); + return QIconSet(); +} + +QString OpenGLWidgetInterface::includeFile( const QString &description ) const +{ + if ( description == "GLWidget" ) + return "glwidget.h"; + return QString::null; +} + +QString OpenGLWidgetInterface::toolTip( const QString &description ) const +{ + if ( description == "GLWidget" ) + return QT_TR_NOOP("OpenGL Widget"); + return QString::null; +} + +QString OpenGLWidgetInterface::whatsThis( const QString &description ) const +{ + if ( description == "GLWidget" ) + return "A widget for OpenGL rendering"; + return QString::null; +} + +bool OpenGLWidgetInterface::isContainer( const QString& ) const +{ + return FALSE; +} + +QRESULT OpenGLWidgetInterface::queryInterface( const QUuid& uuid, QUnknownInterface **iface ) +{ + *iface = 0; + + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( uuid == IID_Widget ) + *iface = (WidgetInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +Q_EXPORT_COMPONENT() +{ + Q_CREATE_INSTANCE( OpenGLWidgetInterface ); +} diff --git a/tools/designer/examples/opengl/opengl.pro b/tools/designer/examples/opengl/opengl.pro new file mode 100644 index 0000000..d28eb32 --- /dev/null +++ b/tools/designer/examples/opengl/opengl.pro @@ -0,0 +1,11 @@ +TEMPLATE = lib +CONFIG += qt warn_on release plugin +HEADERS = glwidget.h +SOURCES = main.cpp \ + glwidget.cpp +DESTDIR = ../../../../plugins/designer +INCLUDEPATH += ../../interfaces + +TARGET = glwidget +target.path += $$plugins.path/designer +INSTALLS += target diff --git a/tools/designer/examples/receiver1/main.cpp b/tools/designer/examples/receiver1/main.cpp new file mode 100644 index 0000000..fd2cf20 --- /dev/null +++ b/tools/designer/examples/receiver1/main.cpp @@ -0,0 +1,24 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include "mainform.h" + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + MainForm *mainForm = new MainForm; + app.setMainWidget( mainForm ); + mainForm->show(); + + return app.exec(); +} + + diff --git a/tools/designer/examples/receiver1/mainform.ui b/tools/designer/examples/receiver1/mainform.ui new file mode 100644 index 0000000..abe714f --- /dev/null +++ b/tools/designer/examples/receiver1/mainform.ui @@ -0,0 +1,87 @@ + +MainForm + + + MainForm + + + + 0 + 0 + 389 + 115 + + + + Main Form + + + + unnamed + + + 11 + + + 6 + + + + quitPushButton + + + &Quit + + + + + creditPushButton + + + &Credit Dialog + + + + + TextLabel1 + + + Credit Rating + + + + + ratingTextLabel + + + Unrated + + + + + + + creditPushButton + clicked() + MainForm + creditDialog() + + + quitPushButton + clicked() + MainForm + accept() + + + + qspinbox.h + qwidgetfactory.h + mainform.ui.h + + + init() + destroy() + creditDialog() + + + diff --git a/tools/designer/examples/receiver1/mainform.ui.h b/tools/designer/examples/receiver1/mainform.ui.h new file mode 100644 index 0000000..5318e2e --- /dev/null +++ b/tools/designer/examples/receiver1/mainform.ui.h @@ -0,0 +1,25 @@ +void MainForm::init() +{ + +} + +void MainForm::destroy() +{ + +} + +void MainForm::creditDialog() +{ + QDialog *creditForm = (QDialog *) + QWidgetFactory::create( "../credit/creditformbase.ui" ); + // Set up the dynamic dialog here + + if ( creditForm->exec() ) { + // The user accepted, act accordingly + QSpinBox *amount = (QSpinBox *) creditForm->child( "amountSpinBox", "QSpinBox" ); + if ( amount ) + ratingTextLabel->setText( amount->text() ); + } + delete creditForm; +} + diff --git a/tools/designer/examples/receiver1/receiver.pro b/tools/designer/examples/receiver1/receiver.pro new file mode 100644 index 0000000..0758559 --- /dev/null +++ b/tools/designer/examples/receiver1/receiver.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +LANGUAGE = C++ +TARGET = receiver + +CONFIG += qt warn_on release +INCLUDEPATH += $$QT_SOURCE_TREE/tools/designer/uilib +LIBS += -lqui +SOURCES += main.cpp +IMAGEFILE = images.cpp +FORMS = mainform.ui +DBFILE = receiver.db diff --git a/tools/designer/examples/receiver2/main.cpp b/tools/designer/examples/receiver2/main.cpp new file mode 100644 index 0000000..8c76ef2 --- /dev/null +++ b/tools/designer/examples/receiver2/main.cpp @@ -0,0 +1,25 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include "mainform.h" + + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + MainForm *mainForm = new MainForm; + app.setMainWidget( mainForm ); + mainForm->show(); + + return app.exec(); +} + + diff --git a/tools/designer/examples/receiver2/mainform.ui b/tools/designer/examples/receiver2/mainform.ui new file mode 100644 index 0000000..690f185 --- /dev/null +++ b/tools/designer/examples/receiver2/mainform.ui @@ -0,0 +1,82 @@ + +MainForm +qwidgetfactory.h +qspinbox.h +receiver.h +mainform.ui.h + + + + MainForm + + + + 0 + 0 + 373 + 107 + + + + Main Form + + + + unnamed + + + 11 + + + 6 + + + + quitPushButton + + + &Quit + + + + + creditPushButton + + + &Credit Dialog + + + + + TextLabel1 + + + Credit Rating + + + + + ratingTextLabel + + + Unrated + + + + + + + creditPushButton + clicked() + MainForm + creditDialog() + + + quitPushButton + clicked() + MainForm + accept() + + creditDialog() + + diff --git a/tools/designer/examples/receiver2/mainform.ui.h b/tools/designer/examples/receiver2/mainform.ui.h new file mode 100644 index 0000000..3cc3b69 --- /dev/null +++ b/tools/designer/examples/receiver2/mainform.ui.h @@ -0,0 +1,20 @@ +void MainForm::creditDialog() +{ + Receiver *receiver = new Receiver; + QDialog *creditForm = (QDialog *) + QWidgetFactory::create( "../credit/creditformbase.ui", receiver ); + receiver->setParent( creditForm ); + + // Set up the dynamic dialog here + + if ( creditForm->exec() ) { + // The user accepted, act accordingly + QSpinBox *amount = (QSpinBox *) creditForm->child( "amountSpinBox", "QSpinBox" ); + if ( amount ) + ratingTextLabel->setText( amount->text() ); + } + + delete receiver; + delete creditForm; +} + diff --git a/tools/designer/examples/receiver2/receiver.cpp b/tools/designer/examples/receiver2/receiver.cpp new file mode 100644 index 0000000..1f66d0b --- /dev/null +++ b/tools/designer/examples/receiver2/receiver.cpp @@ -0,0 +1,29 @@ +#include +#include +#include "receiver.h" + +void Receiver::setParent( QDialog *parent ) +{ + p = parent; + setAmount(); +} + +void Receiver::setAmount() +{ + QSpinBox *amount = + (QSpinBox *) p->child( "amountSpinBox", "QSpinBox" ); + + QRadioButton *radio = + (QRadioButton *) p->child( "stdRadioButton", "QRadioButton" ); + if ( radio && radio->isChecked() ) { + if ( amount ) + amount->setValue( amount->maxValue() / 2 ); + return; + } + + radio = + (QRadioButton *) p->child( "noneRadioButton", "QRadioButton" ); + if ( radio && radio->isChecked() ) + if ( amount ) + amount->setValue( amount->minValue() ); +} diff --git a/tools/designer/examples/receiver2/receiver.h b/tools/designer/examples/receiver2/receiver.h new file mode 100644 index 0000000..34b80e9 --- /dev/null +++ b/tools/designer/examples/receiver2/receiver.h @@ -0,0 +1,13 @@ +#include +#include + +class Receiver : public QObject +{ + Q_OBJECT +public: + void setParent( QDialog *parent ); +public slots: + void setAmount(); +private: + QDialog *p; +}; diff --git a/tools/designer/examples/receiver2/receiver.pro b/tools/designer/examples/receiver2/receiver.pro new file mode 100644 index 0000000..5c7bf79 --- /dev/null +++ b/tools/designer/examples/receiver2/receiver.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +LANGUAGE = C++ +TARGET = receiver + +CONFIG += qt warn_on release +INCLUDEPATH += $$QT_SOURCE_TREE/tools/designer/uilib +LIBS += -lqui +SOURCES += main.cpp receiver.cpp +HEADERS += receiver.h +FORMS = mainform.ui +DBFILE = receiver.db +IMAGEFILE = images.cpp diff --git a/tools/designer/examples/richedit/images/editcopy.png b/tools/designer/examples/richedit/images/editcopy.png new file mode 100644 index 0000000..abfe86e Binary files /dev/null and b/tools/designer/examples/richedit/images/editcopy.png differ diff --git a/tools/designer/examples/richedit/images/editcut.png b/tools/designer/examples/richedit/images/editcut.png new file mode 100644 index 0000000..2d179bc Binary files /dev/null and b/tools/designer/examples/richedit/images/editcut.png differ diff --git a/tools/designer/examples/richedit/images/editpaste.png b/tools/designer/examples/richedit/images/editpaste.png new file mode 100644 index 0000000..356ee55 Binary files /dev/null and b/tools/designer/examples/richedit/images/editpaste.png differ diff --git a/tools/designer/examples/richedit/images/filenew.png b/tools/designer/examples/richedit/images/filenew.png new file mode 100644 index 0000000..9853d97 Binary files /dev/null and b/tools/designer/examples/richedit/images/filenew.png differ diff --git a/tools/designer/examples/richedit/images/fileopen.png b/tools/designer/examples/richedit/images/fileopen.png new file mode 100644 index 0000000..85dab43 Binary files /dev/null and b/tools/designer/examples/richedit/images/fileopen.png differ diff --git a/tools/designer/examples/richedit/images/filesave.png b/tools/designer/examples/richedit/images/filesave.png new file mode 100644 index 0000000..21309aa Binary files /dev/null and b/tools/designer/examples/richedit/images/filesave.png differ diff --git a/tools/designer/examples/richedit/images/redo.png b/tools/designer/examples/richedit/images/redo.png new file mode 100644 index 0000000..857d093 Binary files /dev/null and b/tools/designer/examples/richedit/images/redo.png differ diff --git a/tools/designer/examples/richedit/images/textbold.png b/tools/designer/examples/richedit/images/textbold.png new file mode 100644 index 0000000..c51e5c0 Binary files /dev/null and b/tools/designer/examples/richedit/images/textbold.png differ diff --git a/tools/designer/examples/richedit/images/textcenter.png b/tools/designer/examples/richedit/images/textcenter.png new file mode 100644 index 0000000..032a9bb Binary files /dev/null and b/tools/designer/examples/richedit/images/textcenter.png differ diff --git a/tools/designer/examples/richedit/images/textitalic.png b/tools/designer/examples/richedit/images/textitalic.png new file mode 100644 index 0000000..b725b43 Binary files /dev/null and b/tools/designer/examples/richedit/images/textitalic.png differ diff --git a/tools/designer/examples/richedit/images/textleft.png b/tools/designer/examples/richedit/images/textleft.png new file mode 100644 index 0000000..4ef081f Binary files /dev/null and b/tools/designer/examples/richedit/images/textleft.png differ diff --git a/tools/designer/examples/richedit/images/textright.png b/tools/designer/examples/richedit/images/textright.png new file mode 100644 index 0000000..a9b2b55 Binary files /dev/null and b/tools/designer/examples/richedit/images/textright.png differ diff --git a/tools/designer/examples/richedit/images/textunder.png b/tools/designer/examples/richedit/images/textunder.png new file mode 100644 index 0000000..5093509 Binary files /dev/null and b/tools/designer/examples/richedit/images/textunder.png differ diff --git a/tools/designer/examples/richedit/images/undo.png b/tools/designer/examples/richedit/images/undo.png new file mode 100644 index 0000000..9346c6c Binary files /dev/null and b/tools/designer/examples/richedit/images/undo.png differ diff --git a/tools/designer/examples/richedit/main.cpp b/tools/designer/examples/richedit/main.cpp new file mode 100644 index 0000000..a5a0d6d --- /dev/null +++ b/tools/designer/examples/richedit/main.cpp @@ -0,0 +1,25 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include +#include "richedit.h" + + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + EditorForm richeditForm; + app.setMainWidget( &richeditForm ); + richeditForm.show(); + + return app.exec(); +} + + diff --git a/tools/designer/examples/richedit/richedit.pro b/tools/designer/examples/richedit/richedit.pro new file mode 100644 index 0000000..bcc3d4d --- /dev/null +++ b/tools/designer/examples/richedit/richedit.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = richedit +LANGUAGE = C++ + +CONFIG += qt warn_on release +SOURCES += main.cpp +IMAGEFILE = images.cpp +FORMS = richedit.ui +IMAGES = images/editcopy.png images/editcut.png images/editpaste.png images/filenew.png images/fileopen.png images/filesave.png images/redo.png images/textbold.png images/textcenter.png images/textitalic.png images/textleft.png images/textright.png images/textunder.png images/undo.png +DBFILE = richedit.db diff --git a/tools/designer/examples/richedit/richedit.ui b/tools/designer/examples/richedit/richedit.ui new file mode 100644 index 0000000..2ae033f --- /dev/null +++ b/tools/designer/examples/richedit/richedit.ui @@ -0,0 +1,612 @@ + +EditorForm +qfile.h +qfontdatabase.h +qmessagebox.h +qapplication.h +qfiledialog.h +qtextstream.h +richedit.ui.h +QString fileName; + + + + + EditorForm + + + + 0 + 0 + 646 + 436 + + + + Rich Edit + + + + unnamed + + + 11 + + + 6 + + + + textEdit + + + + 7 + 7 + 0 + 0 + + + + RichText + + + + + + + menubar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + toolBar + + + Tools + + + + + + + + + + + + + + Toolbar + + + Toolbar + + + + + + + + + + + + fontComboBox + + + + + SpinBox2 + + + 6 + + + 10 + + + + + + + + fileNewAction + + + filenew.png + + + New + + + &New + + + 4194382 + + + + + fileOpenAction + + + fileopen.png + + + Open + + + &Open... + + + 4194383 + + + + + fileSaveAction + + + filesave.png + + + Save + + + &Save + + + 4194387 + + + + + fileSaveAsAction + + + Save As + + + Save &As... + + + 0 + + + + + fileExitAction + + + Exit + + + E&xit + + + 0 + + + + + editUndoAction + + + undo.png + + + Undo + + + &Undo + + + 4194394 + + + + + editRedoAction + + + redo.png + + + Redo + + + &Redo + + + 4194393 + + + + + editCutAction + + + editcut.png + + + Cut + + + &Cut + + + 4194392 + + + + + editCopyAction + + + editcopy.png + + + Copy + + + C&opy + + + 4194371 + + + + + editPasteAction + + + editpaste.png + + + Paste + + + &Paste + + + 4194390 + + + + + helpContentsAction + + + Contents + + + &Contents... + + + 0 + + + + + helpIndexAction + + + Index + + + &Index... + + + 0 + + + + + helpAboutAction + + + About + + + &About + + + 0 + + + + + boldAction + + + true + + + textbold.png + + + bold + + + &Bold + + + 272629826 + + + + + italicAction + + + true + + + textitalic.png + + + italic + + + &Italic + + + 272629833 + + + + + underlineAction + + + true + + + textunder.png + + + underline + + + &Underline + + + 272629845 + + + + + alignActionGroup + + + align + + + false + + + + leftAlignAction + + + true + + + textleft.png + + + left + + + &Left + + + 272629836 + + + + + rightAlignAction + + + true + + + textright.png + + + right + + + &Right + + + 272629842 + + + + + centerAlignAction + + + true + + + textcenter.png + + + center + + + &Center + + + + + + + fileNewAction + activated() + EditorForm + fileNew() + + + fileOpenAction + activated() + EditorForm + fileOpen() + + + fileSaveAction + activated() + EditorForm + fileSave() + + + fileSaveAsAction + activated() + EditorForm + fileSaveAs() + + + fileExitAction + activated() + EditorForm + fileExit() + + + helpIndexAction + activated() + EditorForm + helpIndex() + + + helpContentsAction + activated() + EditorForm + helpContents() + + + helpAboutAction + activated() + EditorForm + helpAbout() + + + SpinBox2 + valueChanged(int) + textEdit + setPointSize(int) + + + editCutAction + activated() + textEdit + cut() + + + editPasteAction + activated() + textEdit + paste() + + + editCopyAction + activated() + textEdit + copy() + + + editRedoAction + activated() + textEdit + redo() + + + editUndoAction + activated() + textEdit + undo() + + + alignActionGroup + selected(QAction*) + EditorForm + changeAlignment(QAction*) + + + underlineAction + toggled(bool) + textEdit + setUnderline(bool) + + + italicAction + toggled(bool) + textEdit + setItalic(bool) + + + boldAction + toggled(bool) + textEdit + setBold(bool) + + + fontComboBox + activated(const QString&) + textEdit + setFamily(const QString&) + + + fontComboBox + activated(const QString&) + textEdit + setFocus() + + init() + fileExit() + fileNew() + fileOpen() + fileSave() + fileSaveAs() + helpAbout() + helpContents() + helpIndex() + changeAlignment( QAction * align ) + saveAndContinue( const QString & action ) + + diff --git a/tools/designer/examples/richedit/richedit.ui.h b/tools/designer/examples/richedit/richedit.ui.h new file mode 100644 index 0000000..761848e --- /dev/null +++ b/tools/designer/examples/richedit/richedit.ui.h @@ -0,0 +1,120 @@ +void EditorForm::init() +{ + textEdit->setFocus(); + + QFontDatabase fonts; + fontComboBox->insertStringList( fonts.families() ); + QString font = textEdit->family(); + font = font.lower(); + for ( int i = 0 ; i < fontComboBox->count(); i++ ) { + if ( font == fontComboBox->text( i ) ) { + fontComboBox->setCurrentItem( i ); + break; + } + } +} + +void EditorForm::fileExit() +{ + if ( saveAndContinue( "Exit" ) ) + qApp->exit(); +} + +void EditorForm::fileNew() +{ + if ( saveAndContinue( "New" ) ) + textEdit->clear(); +} + +void EditorForm::fileOpen() +{ + if ( saveAndContinue( "Open" ) ) { + QString fn( QFileDialog::getOpenFileName( + QString::null, + "Rich Text Files (*.htm*)", this ) ); + if ( !fn.isEmpty() ) { + fileName = fn; + QFile file( fileName ); + if ( file.open( IO_ReadOnly ) ) { + QTextStream ts( &file ); + textEdit->setText( ts.read() ); + } + } + } +} + +void EditorForm::fileSave() +{ + if ( fileName.isEmpty() ) { + fileSaveAs(); + } else { + QFile f( fileName ); + if ( f.open( IO_WriteOnly ) ) { + QTextStream ts( &f ); + ts << textEdit->text(); + textEdit->setModified( FALSE ); + } + } +} + +void EditorForm::fileSaveAs() +{ + QString fn = QFileDialog::getSaveFileName( + "", "Rich Text Files (*.htm*)", this ); + if ( !fn.isEmpty() ) { + fileName = fn; + fileSave(); + } +} + +void EditorForm::helpAbout() +{ + +} + +void EditorForm::helpContents() +{ + +} + +void EditorForm::helpIndex() +{ + +} + +void EditorForm::changeAlignment(QAction * align) +{ + if ( align == leftAlignAction ) + textEdit->setAlignment( Qt::AlignLeft ); + else if ( align == rightAlignAction ) + textEdit->setAlignment( Qt::AlignRight ); + else if ( align == centerAlignAction ) + textEdit->setAlignment( Qt::AlignCenter ); +} + +int EditorForm::saveAndContinue(const QString & action) +{ + int continueAction = 1; + + if ( textEdit->isModified() ) { + switch( QMessageBox::information( + this, "Rich Edit", + "The document contains unsaved changes.\n" + "Do you want to save the changes?", + "&Save", "&Don't Save", "&Cancel " + action, + 0, // Enter == button 0 + 2 ) ) { // Escape == button 2 + case 0: // Save; continue + fileSave(); + break; + case 1: // Do not save; continue + break; + case 2: // Cancel + continueAction = 0; + break; + } + } + + return continueAction; +} + diff --git a/tools/designer/examples/sizeaware/main.cpp b/tools/designer/examples/sizeaware/main.cpp new file mode 100644 index 0000000..f8cd6ac --- /dev/null +++ b/tools/designer/examples/sizeaware/main.cpp @@ -0,0 +1,11 @@ +#include +#include "sizeaware.h" + +int main( int argc, char ** argv ) +{ + QApplication app( argc, argv ); + SizeAware *sizeaware = new SizeAware( 0, 0, TRUE ); + sizeaware->exec(); + sizeaware->destroy(); + return 0; +} diff --git a/tools/designer/examples/sizeaware/sizeaware.cpp b/tools/designer/examples/sizeaware/sizeaware.cpp new file mode 100644 index 0000000..1510a15 --- /dev/null +++ b/tools/designer/examples/sizeaware/sizeaware.cpp @@ -0,0 +1,38 @@ +#include "sizeaware.h" +#include + + +SizeAware::SizeAware( QDialog *parent, const char *name, bool modal ) + : QDialog( parent, name, modal ) +{ + if ( company().isEmpty() ) + setCompany( "UnknownCompany" ); + if ( settingsFile().isEmpty() ) + setSettingsFile( "UnknownFile" ); + + QSettings settings; + settings.insertSearchPath( QSettings::Windows, "/" + company() ); + settings.insertSearchPath( QSettings::Unix, "/Opt/" + company() + "/share" ); + int width = settings.readNumEntry( "/" + settingsFile() + "/width", 640 ); + int height = settings.readNumEntry( "/" + settingsFile() + "/height", 480 ); + resize( width, height ); +} + + +SizeAware::~SizeAware() +{ + // NOOP +} + +void SizeAware::destroy() +{ + QSettings settings; + settings.insertSearchPath( QSettings::Windows, "/" + company() ); + settings.insertSearchPath( QSettings::Unix, "/Opt/" + company() + "/share" ); + settings.writeEntry( "/" + settingsFile() + "/width", width() ); + settings.writeEntry( "/" + settingsFile() + "/height", height() ); + close( TRUE ); +} + + + diff --git a/tools/designer/examples/sizeaware/sizeaware.h b/tools/designer/examples/sizeaware/sizeaware.h new file mode 100644 index 0000000..efa9357 --- /dev/null +++ b/tools/designer/examples/sizeaware/sizeaware.h @@ -0,0 +1,23 @@ +#ifndef SIZEAWARE_H +#define SIZEAWARE_H +#include + +class SizeAware : public QDialog +{ + Q_OBJECT + Q_PROPERTY( QString company READ company WRITE setCompany ) + Q_PROPERTY( QString settingsFile READ settingsFile WRITE setSettingsFile ) +public: + SizeAware( QDialog *parent = 0, const char *name = 0, bool modal = FALSE ); + ~SizeAware(); + void setCompany( QString company ) { m_company = company; } + QString company() const { return m_company; } + void setSettingsFile( QString settingsFile ) { m_settingsFile = settingsFile; } + QString settingsFile() const { return m_settingsFile; } +public slots: + void destroy(); +private: + QString m_company; + QString m_settingsFile; +}; +#endif diff --git a/tools/designer/examples/sizeaware/sizeaware.pro b/tools/designer/examples/sizeaware/sizeaware.pro new file mode 100644 index 0000000..c223ed7 --- /dev/null +++ b/tools/designer/examples/sizeaware/sizeaware.pro @@ -0,0 +1,6 @@ +TEMPLATE = app +TARGET = sizeaware + +CONFIG += qt warn_on release +SOURCES += sizeaware.cpp main.cpp +HEADERS += sizeaware.h diff --git a/tools/designer/examples/vcr/main.cpp b/tools/designer/examples/vcr/main.cpp new file mode 100644 index 0000000..a848328 --- /dev/null +++ b/tools/designer/examples/vcr/main.cpp @@ -0,0 +1,10 @@ +#include +#include "vcr.h" + +int main( int argc, char ** argv ) +{ + QApplication app( argc, argv ); + Vcr *vcr = new Vcr; + vcr->show(); + return app.exec(); +} diff --git a/tools/designer/examples/vcr/play.xpm b/tools/designer/examples/vcr/play.xpm new file mode 100644 index 0000000..8102ed1 --- /dev/null +++ b/tools/designer/examples/vcr/play.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * play_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +"................", +".++.............", +".++++...........", +".++++++.........", +".++++++++.......", +".++++++++++.....", +".++++++++++++...", +".+++++++++++++..", +".+++++++++++++..", +".++++++++++++...", +".++++++++++.....", +".++++++++.......", +".++++++.........", +".++++...........", +".+++............", +"................"}; + diff --git a/tools/designer/examples/vcr/vcr.cpp b/tools/designer/examples/vcr/vcr.cpp new file mode 100644 index 0000000..1b2bccf --- /dev/null +++ b/tools/designer/examples/vcr/vcr.cpp @@ -0,0 +1,117 @@ +#include "vcr.h" +#include +#include + +static const char * rewind_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +"................", +".++..........++.", +".++........++++.", +".++......++++++.", +".++....++++++++.", +".++..++++++++++.", +".++++++++++++++.", +".++++++++++++++.", +".++++++++++++++.", +".++++++++++++++.", +".++..++++++++++.", +".++....++++++++.", +".++......++++++.", +".++........++++.", +".++.........+++.", +"................"}; + +static const char * play_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +"................", +".++.............", +".++++...........", +".++++++.........", +".++++++++.......", +".++++++++++.....", +".++++++++++++...", +".+++++++++++++..", +".+++++++++++++..", +".++++++++++++...", +".++++++++++.....", +".++++++++.......", +".++++++.........", +".++++...........", +".+++............", +"................"}; + +static const char * next_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +"................", +".++.....+.......", +".+++....++......", +".++++...+++.....", +".+++++..++++....", +".++++++.+++++...", +".+++++++++++++..", +".++++++++++++++.", +".++++++++++++++.", +".+++++++++++++..", +".++++++.+++++...", +".+++++..++++....", +".++++...+++.....", +".+++....++......", +".++.....+.......", +"................"}; + +static const char * stop_xpm[] = { +"16 16 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +"................", +".++++++++++++++.", +".++++++++++++++.", +".++++++++++++++.", +".+++........+++.", +".+++........+++.", +".+++........+++.", +".+++........+++.", +".+++........+++.", +".+++........+++.", +".+++........+++.", +".+++........+++.", +".++++++++++++++.", +".++++++++++++++.", +".++++++++++++++.", +"................"}; + + +Vcr::Vcr( QWidget *parent, const char *name ) + : QWidget( parent, name ) +{ + QHBoxLayout *layout = new QHBoxLayout( this ); + layout->setMargin( 0 ); + + QPushButton *rewind = new QPushButton( QPixmap( rewind_xpm ), 0, this, "vcr_rewind" ); + layout->addWidget( rewind ); + connect( rewind, SIGNAL(clicked()), SIGNAL(rewind()) ); + + QPushButton *play = new QPushButton( QPixmap( play_xpm ), 0, this, "vcr_play" ); + layout->addWidget( play ); + connect( play, SIGNAL(clicked()), SIGNAL(play()) ); + + QPushButton *next = new QPushButton( QPixmap( next_xpm ), 0, this, "vcr_next" ); + layout->addWidget( next ); + connect( next, SIGNAL(clicked()), SIGNAL(next()) ); + + QPushButton *stop = new QPushButton( QPixmap( stop_xpm ), 0, this, "vcr_stop" ); + layout->addWidget( stop ); + connect( stop, SIGNAL(clicked()), SIGNAL(stop()) ); +} + + diff --git a/tools/designer/examples/vcr/vcr.h b/tools/designer/examples/vcr/vcr.h new file mode 100644 index 0000000..c24086e --- /dev/null +++ b/tools/designer/examples/vcr/vcr.h @@ -0,0 +1,17 @@ +#ifndef VCR_H +#define VCR_H +#include + +class Vcr : public QWidget +{ + Q_OBJECT +public: + Vcr( QWidget *parent = 0, const char *name = 0 ); + ~Vcr() {} +signals: + void rewind(); + void play(); + void next(); + void stop(); +}; +#endif diff --git a/tools/designer/examples/vcr/vcr.pro b/tools/designer/examples/vcr/vcr.pro new file mode 100644 index 0000000..8bda690 --- /dev/null +++ b/tools/designer/examples/vcr/vcr.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +LANGUAGE = C++ +TARGET = vcr + +CONFIG += qt warn_on release +SOURCES += vcr.cpp main.cpp +HEADERS += vcr.h +DBFILE = vcr.db diff --git a/tools/designer/integration/designer.el b/tools/designer/integration/designer.el new file mode 100644 index 0000000..4b3c38d --- /dev/null +++ b/tools/designer/integration/designer.el @@ -0,0 +1,19 @@ +(defvar designer-exec "/usr/bin/designer") + +(defun designer-open-ui-file () + (interactive) + (defvar procname "designer") + (start-process procname nil designer-exec "-client" buffer-file-name) +) + +(defun designer-create-ui-file (&optional arg) + (interactive "FNew UI-File: ") + (find-file arg) + (insert "") + (save-buffer) + (designer-open-ui-file) +) + +;(global-set-key [f7] 'designer-open-ui-file) +;(global-set-key [f8] 'designer-create-ui-file) + diff --git a/tools/designer/interfaces/actioninterface.h b/tools/designer/interfaces/actioninterface.h new file mode 100644 index 0000000..fc203b1 --- /dev/null +++ b/tools/designer/interfaces/actioninterface.h @@ -0,0 +1,85 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef ACTIONINTERFACE_H +#define ACTIONINTERFACE_H + +#include + +class QAction; +class QObject; + +// {bb206e09-84e5-4777-9fce-706babfab931} +#ifndef IID_Action +#define IID_Action QUuid( 0xbb206e09, 0x84e5, 0x4777, 0x9f, 0xce, 0x70, 0x6b, 0xab, 0xfa, 0xb9, 0x31 ) +#endif + +/*! To add actions to the Qt Designer menubars and toolbars, implement + this interface. You have to implement the create(), group() and + connectTo() functions. + + You also have to implement the function featureList() (\sa + QFeatureListInterface) to return the names of all actions + which this interface provides. +*/ + +class ActionInterface : public QFeatureListInterface +{ +public: + enum Location { + Toolbar, + Menu + }; + + /*! This functions is called to create the action with the name \a + name. \a parent should be used as parent of the action. + + In the implementation return the QAction object for the action + \a name. + */ + virtual QAction* create( const QString &name, QObject* parent = 0 ) = 0; + + /*! In the implementation of the interface return the name of the + group of the action \a name. + */ + virtual QString group( const QString &name ) const = 0; + + /*! In the implementation of the interface return whether the + action \a name should appear in the location \a l */ + virtual bool location( const QString &name, Location l ) const = 0; + + /*! \internal */ + virtual void connectTo( QUnknownInterface *appInterface ) = 0; +}; + +#endif diff --git a/tools/designer/interfaces/classbrowserinterface.h b/tools/designer/interfaces/classbrowserinterface.h new file mode 100644 index 0000000..b97f2b9 --- /dev/null +++ b/tools/designer/interfaces/classbrowserinterface.h @@ -0,0 +1,70 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CLASSBROWSERINTERFACE_H +#define CLASSBROWSERINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include +#include +class QListView; + +// {4ede3c32-ae96-4b7a-9e38-9f1d93592391} +#ifndef IID_ClassBrowser +#define IID_ClassBrowser QUuid( 0x4ede3c32, 0xae96, 0x4b7a, 0x9e, 0x38, 0x9f, 0x1d, 0x93, 0x59, 0x23, 0x91 ) +#endif + +struct ClassBrowserInterface : public QUnknownInterface +{ + enum Type { Class, Function }; + + virtual QListView *createClassBrowser( QWidget *parent ) const = 0; + virtual void update( const QString &code ) const = 0; + virtual void clear() const = 0; + + virtual void onClick( QObject *receiver, const char *slot ) = 0; +}; + +#endif diff --git a/tools/designer/interfaces/designerinterface.h b/tools/designer/interfaces/designerinterface.h new file mode 100644 index 0000000..8988da0 --- /dev/null +++ b/tools/designer/interfaces/designerinterface.h @@ -0,0 +1,268 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DESIGNERINTERFACE_H +#define DESIGNERINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include +#include +#include +#include +#include +#include +#include + +struct DesignerProject; +struct DesignerDatabase; +struct DesignerFormWindow; +struct DesignerDock; +struct DesignerOutputDock; +struct DesignerOutput; +struct DesignerOutputError; +struct DesignerPixmapCollection; +struct DesignerSourceFile; + +class QDockWindow; +class QWidget; +class QObject; +class QAction; +class QIconSet; +class QSqlDatabase; + +// {0e661da-f45c-4830-af47-03ec53eb1633} +#ifndef IID_Designer +#define IID_Designer QUuid( 0xa0e661da, 0xf45c, 0x4830, 0xaf, 0x47, 0x3, 0xec, 0x53, 0xeb, 0x16, 0x33 ) +#endif + +/*! These are the interfaces implemented by the Qt Designer which should + be used by plugins to access and use functionality of the Qt Designer. +*/ + +struct DesignerInterface : public QUnknownInterface +{ + virtual DesignerProject *currentProject() const = 0; + virtual DesignerFormWindow *currentForm() const = 0; + virtual DesignerSourceFile *currentSourceFile() const = 0; + virtual QPtrList projectList() const = 0; + virtual void showStatusMessage( const QString &, int ms = 0 ) const = 0; + virtual DesignerDock *createDock() const = 0; + virtual DesignerOutputDock *outputDock() const = 0; + virtual void setModified( bool b, QWidget *window ) = 0; + virtual void updateFunctionList() = 0; + + virtual void onProjectChange( QObject *receiver, const char *slot ) = 0; + virtual void onFormChange( QObject *receiver, const char *slot ) = 0; + + virtual bool singleProjectMode() const = 0; + virtual void showError( QWidget *widget, int line, const QString &message ) = 0; + virtual void runFinished() = 0; + virtual void showStackFrame( QWidget *w, int line ) = 0; + virtual void showDebugStep( QWidget *w, int line ) = 0; + virtual void runProjectPrecondition() = 0; + virtual void runProjectPostcondition( QObjectList *l ) = 0; + + }; + +struct DesignerProject +{ + virtual QPtrList formList() const = 0; + virtual QStringList formNames() const = 0; + virtual QString formFileName( const QString &form ) const = 0; + virtual void addForm( DesignerFormWindow * ) = 0; + virtual void removeForm( DesignerFormWindow * ) = 0; + virtual QString fileName() const = 0; + virtual void setFileName( const QString & ) = 0; + virtual QString projectName() const = 0; + virtual void setProjectName( const QString & ) = 0; + virtual QString databaseFile() const = 0; + virtual void setDatabaseFile( const QString & ) = 0; + virtual void setupDatabases() const = 0; + virtual QPtrList databaseConnections() const = 0; + virtual void addDatabase( DesignerDatabase * ) = 0; + virtual void removeDatabase( DesignerDatabase * ) = 0; + virtual void save() const = 0; + virtual void setLanguage( const QString & ) = 0; + virtual QString language() const = 0; + virtual void setCustomSetting( const QString &key, const QString &value ) = 0; + virtual QString customSetting( const QString &key ) const = 0; + virtual DesignerPixmapCollection *pixmapCollection() const = 0; + virtual void breakPoints( QMap > &bps ) const = 0; + virtual QString breakPointCondition( QObject *o, int line ) const = 0; + virtual void setBreakPointCondition( QObject *o, int line, const QString &condition ) = 0; + virtual void clearAllBreakpoints() const = 0; + virtual void setIncludePath( const QString &platform, const QString &path ) = 0; + virtual void setLibs( const QString &platform, const QString &path ) = 0; + virtual void setDefines( const QString &platform, const QString &path ) = 0; + virtual void setConfig( const QString &platform, const QString &config ) = 0; + virtual void setTemplate( const QString &t ) = 0; + virtual QString config( const QString &platform ) const = 0; + virtual QString libs( const QString &platform ) const = 0; + virtual QString defines( const QString &platform ) const = 0; + virtual QString includePath( const QString &platform ) const = 0; + virtual QString templte() const = 0; + virtual bool isGenericObject( QObject *o ) const = 0; + +}; + +struct DesignerDatabase +{ + virtual QString name() const = 0; + virtual void setName( const QString & ) = 0; + virtual QString driver() const = 0; + virtual void setDriver( const QString & ) = 0; + virtual QString database() const = 0; + virtual void setDatabase( const QString & ) = 0; + virtual QString userName() const = 0; + virtual void setUserName( const QString & ) = 0; + virtual QString password() const = 0; + virtual void setPassword( const QString & ) = 0; + virtual QString hostName() const = 0; + virtual void setHostName( const QString & ) = 0; + virtual QStringList tables() const = 0; + virtual void setTables( const QStringList & ) = 0; + virtual QMap fields() const = 0; + virtual void setFields( const QMap & ) = 0; + virtual void open( bool suppressDialog = FALSE ) const = 0; + virtual void close() const = 0; + virtual QSqlDatabase* connection() = 0; + +}; + +struct DesignerPixmapCollection +{ + virtual void addPixmap( const QPixmap &p, const QString &name, bool force ) = 0; + virtual QPixmap pixmap( const QString &name ) const = 0; +}; + +struct DesignerFormWindow +{ + virtual QString name() const = 0; + virtual void setName( const QString &n ) = 0; + virtual QString fileName() const = 0; + virtual void setFileName( const QString & ) = 0; + virtual void save() const = 0; + virtual bool isModified() const = 0; + virtual void insertWidget( QWidget * ) = 0; + virtual void removeWidget( QWidget * ) = 0; + virtual QWidget *create( const char *className, QWidget *parent, const char *name ) = 0; + virtual QWidgetList widgets() const = 0; + virtual void undo() = 0; + virtual void redo() = 0; + virtual void cut() = 0; + virtual void copy() = 0; + virtual void paste() = 0; + virtual void adjustSize() = 0; + virtual void editConnections() = 0; + virtual void checkAccels() = 0; + virtual void layoutH() = 0; + virtual void layoutV() = 0; + virtual void layoutHSplit() = 0; + virtual void layoutVSplit() = 0; + virtual void layoutG() = 0; + virtual void layoutHContainer( QWidget* w ) = 0; + virtual void layoutVContainer( QWidget* w ) = 0; + virtual void layoutGContainer( QWidget* w ) = 0; + virtual void breakLayout() = 0; + virtual void selectWidget( QWidget * w ) = 0; + virtual void selectAll() = 0; + virtual void clearSelection() = 0; + virtual bool isWidgetSelected( QWidget * ) const = 0; + virtual QWidgetList selectedWidgets() const = 0; + virtual QWidget *currentWidget() const = 0; + virtual QWidget *form() const = 0; + virtual void setCurrentWidget( QWidget * ) = 0; + virtual QPtrList actionList() const = 0; + virtual QAction *createAction( const QString& text, const QIconSet& icon, const QString& menuText, int accel, + QObject* parent, const char* name = 0, bool toggle = FALSE ) = 0; + virtual void addAction( QAction * ) = 0; + virtual void removeAction( QAction * ) = 0; + virtual void preview() const = 0; + virtual void addFunction( const QCString &slot, const QString &specifier, const QString &access, + const QString &type, const QString &language, const QString &returnType ) = 0; + virtual void addConnection( QObject *sender, const char *signal, QObject *receiver, const char *slot ) = 0; + virtual void setProperty( QObject *o, const char *property, const QVariant &value ) = 0; + virtual QVariant property( QObject *o, const char *property ) const = 0; + virtual void setPropertyChanged( QObject *o, const char *property, bool changed ) = 0; + virtual bool isPropertyChanged( QObject *o, const char *property ) const = 0; + virtual void setColumnFields( QObject *o, const QMap & ) = 0; + virtual QStringList implementationIncludes() const = 0; + virtual QStringList declarationIncludes() const = 0; + virtual void setImplementationIncludes( const QStringList &lst ) = 0; + virtual void setDeclarationIncludes( const QStringList &lst ) = 0; + virtual QStringList forwardDeclarations() const = 0; + virtual void setForwardDeclarations( const QStringList &lst ) = 0; + virtual QStringList signalList() const = 0; + virtual void setSignalList( const QStringList &lst ) = 0; + virtual void addMenu( const QString &text, const QString &name ) = 0; + virtual void addMenuAction( const QString &menu, QAction *a ) = 0; + virtual void addMenuSeparator( const QString &menu ) = 0; + virtual void addToolBar( const QString &text, const QString &name ) = 0; + virtual void addToolBarAction( const QString &tb, QAction *a ) = 0; + virtual void addToolBarSeparator( const QString &tb ) = 0; + + virtual void onModificationChange( QObject *receiver, const char *slot ) = 0; +}; + +struct DesignerSourceFile +{ + virtual QString fileName() const = 0; +}; + +struct DesignerDock +{ + virtual QDockWindow *dockWindow() const = 0; +}; + +struct DesignerOutputDock +{ + virtual QWidget *addView( const QString &pageName ) = 0; + virtual void appendDebug( const QString & ) = 0; + virtual void clearDebug() = 0; + virtual void appendError( const QString &, int ) = 0; + virtual void clearError() = 0; +}; + +#endif diff --git a/tools/designer/interfaces/editorinterface.h b/tools/designer/interfaces/editorinterface.h new file mode 100644 index 0000000..4c3cb7d --- /dev/null +++ b/tools/designer/interfaces/editorinterface.h @@ -0,0 +1,109 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef EDITORINTERFACE_H +#define EDITORINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include +#include +#include + +class QWidget; +class QObjectList; +class QObject; + +// {8668161a-6037-4220-86b6-ccaa20127df8} +#ifndef IID_Editor +#define IID_Editor QUuid( 0x8668161a, 0x6037, 0x4220, 0x86, 0xb6, 0xcc, 0xaa, 0x20, 0x12, 0x7d, 0xf8 ) +#endif + +struct EditorInterface : public QUnknownInterface +{ + enum Mode + { + Editing, + Debugging + }; + + virtual QWidget *editor( bool readOnly, + QWidget *parent, + QUnknownInterface *designerIface ) = 0; + + virtual void setText( const QString &txt ) = 0; + virtual QString text() const = 0; + virtual bool isUndoAvailable() const = 0; + virtual bool isRedoAvailable() const = 0; + virtual void undo() = 0; + virtual void redo() = 0; + virtual void cut() = 0; + virtual void copy() = 0; + virtual void paste() = 0; + virtual void selectAll() = 0; + virtual bool find( const QString &expr, bool cs, bool wo, bool forward, bool startAtCursor ) = 0; + virtual bool replace( const QString &find, const QString &replace, bool cs, bool wo, bool forward, bool startAtCursor, bool replaceAll ) = 0; + virtual void gotoLine( int line ) = 0; + virtual void indent() = 0; + virtual void scrollTo( const QString &txt, const QString &first ) = 0; + virtual void splitView() = 0; + virtual void setContext( QObject *this_ ) = 0; + virtual void setError( int line ) = 0; + virtual void setStep( int line ) = 0; + virtual void setStackFrame( int line ) = 0; + virtual void clearStep() = 0; + virtual void clearStackFrame() = 0; + virtual void readSettings() = 0; + virtual void setModified( bool m ) = 0; + virtual bool isModified() const = 0; + virtual int numLines() const = 0; + virtual void breakPoints( QValueList &l ) const = 0; + virtual void setBreakPoints( const QValueList &l ) = 0; + virtual void setMode( Mode m ) = 0; + + virtual void onBreakPointChange( QObject *receiver, const char *slot ) = 0; + +}; + +#endif diff --git a/tools/designer/interfaces/filterinterface.h b/tools/designer/interfaces/filterinterface.h new file mode 100644 index 0000000..8c7ab2e --- /dev/null +++ b/tools/designer/interfaces/filterinterface.h @@ -0,0 +1,75 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef FILTERINTERFACE_H +#define FILTERINTERFACE_H + +#include + +// {ea8cb381-59b5-44a8-bae5-9bea8295762a} +#ifndef IID_ImportFilter +#define IID_ImportFilter QUuid( 0xea8cb381, 0x59b5, 0x44a8, 0xba, 0xe5, 0x9b, 0xea, 0x82, 0x95, 0x76, 0x2a ) +#endif + +/*! If you write a filter plugin to import dialogs or other user + interfaces from a different format than .ui into the Qt Designer, + implement this interface in that plugin. + + You also have to implement the function featureList() (\sa + QFeatureListInterface) and return there all filters (names of it) + which this interface provides. +*/ + +struct ImportFilterInterface : public QFeatureListInterface +{ + /*! This function is called by Qt Designer to open the file \a + filename using the filter \a filter. Qt Designer expects to get + back one or more .ui files, which it can open then. In the + implementation of the interface you have to return these + filenames, which the filter created, in this function.*/ + virtual QStringList import( const QString &filter, const QString &filename ) = 0; +}; + +// *************** INTERNAL ************************* + +// {c32a07e0-b006-471e-afca-d227457a1280} +#ifndef IID_ExportFilterInterface +#define IID_ExportFilterInterface QUuid( 0xc32a07e0, 0xb006, 0x471e, 0xaf, 0xca, 0xd2, 0x27, 0x45, 0x7a, 0x12, 0x80 ) +#endif + +struct ExportFilterInterface : public QFeatureListInterface +{ +// virtual QStringList export( const QString& filter, const QString& filename ) = 0; +}; + +#endif diff --git a/tools/designer/interfaces/interpreterinterface.h b/tools/designer/interfaces/interpreterinterface.h new file mode 100644 index 0000000..dbda2f0 --- /dev/null +++ b/tools/designer/interfaces/interpreterinterface.h @@ -0,0 +1,66 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef INTERPRETERINTERFACE_H +#define INTERPRETERINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include + +class QObject; + +// {11cad9ec-4e3c-418b-8e90-e1b8c0c1f48f} +#ifndef IID_Interpreter +#define IID_Interpreter QUuid( 0x11cad9ec, 0x4e3c, 0x418b, 0x8e, 0x90, 0xe1, 0xb8, 0xc0, 0xc1, 0xf4, 0x8f ) +#endif + +struct InterpreterInterface : public QUnknownInterface +{ + virtual void setBreakPoints( QObject *obj, const QValueList &lst ) = 0; +}; + + + +#endif diff --git a/tools/designer/interfaces/languageinterface.h b/tools/designer/interfaces/languageinterface.h new file mode 100644 index 0000000..acb5e89 --- /dev/null +++ b/tools/designer/interfaces/languageinterface.h @@ -0,0 +1,138 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LANGUAGEINTERFACE_H +#define LANGUAGEINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include +#include +#include +#include +#include + +// {f208499a-6f69-4883-9219-6e936e55a330} +#ifndef IID_Language +#define IID_Language QUuid( 0xf208499a, 0x6f69, 0x4883, 0x92, 0x19, 0x6e, 0x93, 0x6e, 0x55, 0xa3, 0x30 ) +#endif + +struct LanguageInterface : public QUnknownInterface +{ + struct Function + { + QString name; + QString body; + QString returnType; + QString comments; + int start; + int end; + QString access; + bool operator==( const Function &f ) const { + return ( name == f.name && + body == f.body && + returnType == f.returnType && + comments == f.comments ); + } + }; + + struct Connection + { + QString sender; + QString signal; + QString slot; + bool operator==( const Connection &c ) const { + return ( sender == c.sender && + signal == c.signal && + slot == c.slot ); + } + }; + + enum Support + { + ReturnType, + ConnectionsToCustomSlots, + CompressProject + }; + + virtual void functions( const QString &code, QValueList *funcs ) const = 0; + virtual void connections( const QString &code, QValueList *connections ) const = 0; + virtual QString createFunctionStart( const QString &className, const QString &func, + const QString &returnType, const QString &access ) = 0; + virtual QString createArguments( const QString &cpp_signature ) = 0; + virtual QString createEmptyFunction() = 0; + virtual QStringList definitions() const = 0; + virtual QStringList definitionEntries( const QString &definition, QUnknownInterface *designerIface ) const = 0; + virtual void setDefinitionEntries( const QString &definition, const QStringList &entries, QUnknownInterface *designerIface ) = 0; + virtual bool supports( Support s ) const = 0; + virtual QStringList fileFilterList() const = 0; + virtual QStringList fileExtensionList() const = 0; + virtual void preferedExtensions( QMap &extensionMap ) const = 0; + virtual QString projectKeyForExtension( const QString &extension ) const = 0; + virtual void sourceProjectKeys( QStringList &keys ) const = 0; + virtual QString cleanSignature( const QString &sig ) = 0; + virtual void loadFormCode( const QString &form, const QString &filename, + QValueList &functions, + QStringList &vars, + QValueList &connections ) = 0; + virtual QString formCodeExtension() const = 0; + + virtual bool canConnect( const QString &signal, const QString &slot ) = 0; + + virtual void compressProject( const QString &projectFile, const QString &compressedFile, + bool withWarning ) = 0; + virtual QString uncompressProject( const QString &projectFile, const QString &destDir ) = 0; + virtual QString aboutText() const = 0; + + virtual void addConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot, + QString *code ) = 0; + virtual void removeConnection( const QString &sender, const QString &signal, + const QString &receiver, const QString &slot, + QString *code ) = 0; + virtual QStrList signalNames( QObject *obj ) const = 0; + +}; + +#endif diff --git a/tools/designer/interfaces/preferenceinterface.h b/tools/designer/interfaces/preferenceinterface.h new file mode 100644 index 0000000..aa8b84e --- /dev/null +++ b/tools/designer/interfaces/preferenceinterface.h @@ -0,0 +1,75 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PREFERENCEINTERFACE_H +#define PREFERENCEINTERFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include +#include +#include + +// {5c168ee7-4bee-469f-9995-6afdb04ce5a2} +#ifndef IID_Preference +#define IID_Preference QUuid( 0x5c168ee7, 0x4bee, 0x469f, 0x99, 0x95, 0x6a, 0xfd, 0xb0, 0x4c, 0xe5, 0xa2 ) +#endif + +struct PreferenceInterface : public QUnknownInterface +{ + struct Preference + { + QWidget *tab; + QString title; + QObject *receiver; + const char *init_slot; + const char *accept_slot; + }; + + virtual Preference *preference() = 0; + virtual void connectTo( QUnknownInterface *appInterface ) = 0; + virtual void deletePreferenceObject( Preference * ) = 0; +}; + +#endif diff --git a/tools/designer/interfaces/projectsettingsiface.h b/tools/designer/interfaces/projectsettingsiface.h new file mode 100644 index 0000000..5e814c6 --- /dev/null +++ b/tools/designer/interfaces/projectsettingsiface.h @@ -0,0 +1,76 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PROJECTSETTINGSIFACE_H +#define PROJECTSETTINGSIFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include +#include +#include + +// {d332785d-17fb-4894-84fe-50dbd0ad9512} +#ifndef IID_ProjectSettings +#define IID_ProjectSettings QUuid( 0xd332785d, 0x17fb, 0x4894, 0x84, 0xfe, 0x50, 0xdb, 0xd0, 0xad, 0x95, 0x12 ) +#endif + +struct ProjectSettingsInterface : public QUnknownInterface +{ + struct ProjectSettings + { + QWidget *tab; + QString title; + QObject *receiver; + const char *init_slot; + const char *accept_slot; + }; + + virtual ProjectSettings *projectSetting() = 0; + virtual QStringList projectSettings() const = 0; + virtual void connectTo( QUnknownInterface *appInterface ) = 0; + virtual void deleteProjectSettingsObject( ProjectSettings * ) = 0; +}; + +#endif diff --git a/tools/designer/interfaces/sourcetemplateiface.h b/tools/designer/interfaces/sourcetemplateiface.h new file mode 100644 index 0000000..01a5e75 --- /dev/null +++ b/tools/designer/interfaces/sourcetemplateiface.h @@ -0,0 +1,72 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SOURCETEMPLATEIFACE_H +#define SOURCETEMPLATEIFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include +#include + +// {1b3446a4-1c71-424b-8789-1f34eb5697d8} +#ifndef IID_SourceTemplate +#define IID_SourceTemplate QUuid( 0x1b3446a4, 0x1c71, 0x424b, 0x87, 0x89, 0x1f, 0x34, 0xeb, 0x56, 0x97, 0xd8 ) +#endif + +struct SourceTemplateInterface : public QFeatureListInterface +{ + struct Source + { + QString code; + enum Type { FileName, Unnamed, Invalid } type; + QString filename; + QString extension; + }; + virtual Source create( const QString &templ, QUnknownInterface *appIface ) = 0; + virtual QString language( const QString &templ ) const = 0; + +}; + +#endif diff --git a/tools/designer/interfaces/templatewizardiface.h b/tools/designer/interfaces/templatewizardiface.h new file mode 100644 index 0000000..5a89293 --- /dev/null +++ b/tools/designer/interfaces/templatewizardiface.h @@ -0,0 +1,67 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TEMPLATEWIZARDIFACE_H +#define TEMPLATEWIZARDIFACE_H + +// +// W A R N I N G -- PRIVATE INTERFACES +// -------------------------------------- +// +// This file and the interfaces declared in the file are not +// public. It exists for internal purpose. This header file and +// interfaces may change from version to version (even binary +// incompatible) without notice, or even be removed. +// +// We mean it. +// +// + +#include + +class QWidget; +struct DesignerFormWindow; + +// {983d3eab-fea3-49cc-97ad-d8cc89b7c17b} +#ifndef IID_TemplateWizard +#define IID_TemplateWizard QUuid( 0x983d3eab, 0xfea3, 0x49cc, 0x97, 0xad, 0xd8, 0xcc, 0x89, 0xb7, 0xc1, 0x7b ) +#endif + +class TemplateWizardInterface : public QFeatureListInterface +{ +public: + virtual void setup( const QString &templ, QWidget *widget, DesignerFormWindow *fw, QUnknownInterface *appIface ) = 0; + +}; + +#endif diff --git a/tools/designer/interfaces/widgetinterface.h b/tools/designer/interfaces/widgetinterface.h new file mode 100644 index 0000000..9a0682a --- /dev/null +++ b/tools/designer/interfaces/widgetinterface.h @@ -0,0 +1,42 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef WIDGETINTERFACE_H +#define WIDGETINTERFACE_H + +#include + +#define WidgetInterface QWidgetFactoryInterface +#define IID_Widget IID_QWidgetFactory + +#endif diff --git a/tools/designer/plugins/cppeditor/common.cpp b/tools/designer/plugins/cppeditor/common.cpp new file mode 100644 index 0000000..07b52df --- /dev/null +++ b/tools/designer/plugins/cppeditor/common.cpp @@ -0,0 +1,111 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "editorinterfaceimpl.h" +#include "languageinterfaceimpl.h" +#include "preferenceinterfaceimpl.h" +#include "projectsettingsinterfaceimpl.h" +#include "sourcetemplateinterfaceimpl.h" + +class CommonInterface : public QComponentInformationInterface +{ +public: + CommonInterface(); + virtual ~CommonInterface(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT; + + QString name() const { return "C++"; } + QString description() const { return "C++ Integration"; } + QString version() const { return "0.1"; } + QString author() const { return "Trolltech AS"; } + +private: + LanguageInterfaceImpl *langIface; + PreferenceInterfaceImpl *prefIface; + ProjectSettingsInterfaceImpl *proIface; + SourceTemplateInterfaceImpl *srcIface; + +}; + +CommonInterface::CommonInterface() +{ + langIface = new LanguageInterfaceImpl( this ); + langIface->addRef(); + prefIface = new PreferenceInterfaceImpl( this ); + prefIface->addRef(); + proIface = new ProjectSettingsInterfaceImpl( this ); + proIface->addRef(); + srcIface = new SourceTemplateInterfaceImpl; + srcIface->addRef(); +} + +CommonInterface::~CommonInterface() +{ + langIface->release(); + prefIface->release(); + proIface->release(); + srcIface->release(); +} + +QRESULT CommonInterface::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_QComponentInformation ) + *iface = (QComponentInformationInterface*)this; + else if ( uuid == IID_Editor ) + *iface = new EditorInterfaceImpl; + else if ( uuid == IID_Language ) + *iface = langIface; + else if ( uuid == IID_Preference ) + *iface = prefIface; + else if ( uuid == IID_ProjectSettings ) + *iface = proIface; + else if ( uuid == IID_SourceTemplate ) + *iface = srcIface; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + + +Q_EXPORT_COMPONENT() +{ + Q_CREATE_INSTANCE( CommonInterface ) +} diff --git a/tools/designer/plugins/cppeditor/cppbrowser.cpp b/tools/designer/plugins/cppeditor/cppbrowser.cpp new file mode 100644 index 0000000..3d004b5 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppbrowser.cpp @@ -0,0 +1,78 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "cppbrowser.h" +#include +#include +#include +#include +#include + +CppEditorBrowser::CppEditorBrowser( Editor *e ) + : EditorBrowser( e ) +{ +} + +void CppEditorBrowser::showHelp( const QString &w ) +{ + QString word( w ); + if ( word[ 0 ] == 'Q' ) { + if ( word[ (int)word.length() - 1 ] == '&' || + word[ (int)word.length() - 1 ] == '*' ) + word.remove( word.length() - 1, 1 ); + word = word.lower() + ".html"; + QStringList lst; + lst << "assistant" << "-file" << word; + QProcess proc( lst ); + proc.start(); + return; + } + + if ( word.find( '(' ) != -1 ) { + QString txt = "::" + word.left( word.find( '(' ) ); + QTextDocument *doc = curEditor->document(); + QTextParagraph *p = doc->firstParagraph(); + while ( p ) { + if ( p->string()->toString().find( txt ) != -1 ) { + curEditor->setCursorPosition( p->paragId(), 0 ); + return; + } + p = p->next(); + } + } + + QMainWindow *mw = ::qt_cast(curEditor->topLevelWidget()); + if ( mw ) + mw->statusBar()->message( tr( "Nothing available for '%1'" ).arg( w ), 1500 ); +} diff --git a/tools/designer/plugins/cppeditor/cppbrowser.h b/tools/designer/plugins/cppeditor/cppbrowser.h new file mode 100644 index 0000000..92f07b9 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppbrowser.h @@ -0,0 +1,50 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CPPBROWSER_H +#define CPPBROWSER_H + +#include + +class CppEditorBrowser : public EditorBrowser +{ + Q_OBJECT + +public: + CppEditorBrowser( Editor *e ); + void showHelp( const QString &word ); + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/cppcompletion.cpp b/tools/designer/plugins/cppeditor/cppcompletion.cpp new file mode 100644 index 0000000..464aedb --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppcompletion.cpp @@ -0,0 +1,220 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "cppcompletion.h" +#include +#include +#include +#include + +CppEditorCompletion::CppEditorCompletion( Editor *e ) + : EditorCompletion( e ) +{ +} + +bool CppEditorCompletion::doObjectCompletion( const QString &objName ) +{ + if ( !ths ) + return FALSE; + QString object( objName ); + int i = -1; + if ( ( i = object.findRev( "->" ) ) != -1 ) + object = object.mid( i + 2 ); + if ( ( i = object.findRev( "." ) ) != -1 ) + object = object.mid( i + 1 ); + object = object.simplifyWhiteSpace(); + QObject *obj = 0; + if ( ths->name() == object || object == "this" ) { + obj = ths; + } else { + obj = ths->child( object ); + } + + if ( !obj ) + return FALSE; + + QValueList lst; + + if ( obj->children() ) { + for ( QObjectListIt cit( *obj->children() ); cit.current(); ++cit ) { + QString s( cit.current()->name() ); + if ( s.find( " " ) == -1 && s.find( "qt_" ) == -1 && s.find( "unnamed" ) == -1 ) { + CompletionEntry c; + c.type = "variable"; + c.text = s; + c.prefix = ""; + lst << c; + } + } + } + + QStrList props = obj->metaObject()->propertyNames( TRUE ); + for ( QPtrListIterator pit( props ); pit.current(); ++pit ) { + QString f( pit.current() ); + QChar c = f[ 0 ]; + f.remove( (uint)0, 1 ); + f.prepend( c.upper() ); + f.prepend( "set" ); + + CompletionEntry ce; + ce.type = "property"; + ce.text = f; + ce.postfix = "()"; + + if ( lst.find( ce ) == lst.end() ) + lst << ce; + } + + QStrList slts = obj->metaObject()->slotNames( TRUE ); + for ( QPtrListIterator sit( slts ); sit.current(); ++sit ) { + QString f( sit.current() ); + f = f.left( f.find( "(" ) ); + CompletionEntry c; + c.type = "slot"; + c.text = f; + c.postfix = "()"; + if ( lst.find( c ) == lst.end() ) + lst << c; + } + + if ( lst.isEmpty() ) + return FALSE; + + showCompletion( lst ); + return TRUE; +} + +QValueList CppEditorCompletion::functionParameters( const QString &expr, QChar &separator, + QString &prefix, QString &postfix ) +{ + Q_UNUSED( prefix ); + Q_UNUSED( postfix ); + separator = ','; + if ( !ths ) + return QValueList(); + QString func; + QString objName; + int i = -1; + + i = expr.findRev( "->" ); + if ( i == -1 ) + i = expr.findRev( "." ); + else + ++i; + if ( i == -1 ) { + i = expr.findRev( " " ); + + if ( i == -1 ) + i = expr.findRev( "\t" ); + else + objName = ths->name(); + + if ( i == -1 && expr[ 0 ] != ' ' && expr[ 0 ] != '\t' ) + objName = ths->name(); + } + + if ( !objName.isEmpty() ) { + func = expr.mid( i + 1 ); + func = func.simplifyWhiteSpace(); + } else { + func = expr.mid( i + 1 ); + func = func.simplifyWhiteSpace(); + QString ex( expr ); + ex.remove( i, 0xFFFFFF ); + if ( ex[ (int)ex.length() - 1 ] == '-' ) + ex.remove( ex.length() - 1, 1 ); + int j = -1; + j = ex.findRev( "->" ); + if ( j == -1 ) + j = ex.findRev( "." ); + else + ++j; + if ( j == -1 ) { + j = ex.findRev( " " ); + + if ( j == -1 ) + j = ex.findRev( "\t" ); + else + objName = ths->name(); + + if ( j == -1 ) + objName = ths->name(); + } + objName = ex.mid( j + 1 ); + objName = objName.simplifyWhiteSpace(); + } + + QObject *obj = 0; + if ( ths->name() == objName || objName == "this" ) { + obj = ths; + } else { + obj = ths->child( objName ); + } + + if ( !obj ) + return QValueList(); + + QStrList slts = obj->metaObject()->slotNames( TRUE ); + for ( QPtrListIterator sit( slts ); sit.current(); ++sit ) { + QString f( sit.current() ); + f = f.left( f.find( "(" ) ); + if ( f == func ) { + f = QString( sit.current() ); + f.remove( (uint)0, f.find( "(" ) + 1 ); + f = f.left( f.find( ")" ) ); + QStringList lst = QStringList::split( ',', f ); + if ( !lst.isEmpty() ) { + QValueList l; + l << lst; + return l; + } + } + } + + const QMetaProperty *prop = + obj->metaObject()-> + property( obj->metaObject()->findProperty( func[ 3 ].lower() + func.mid( 4 ), TRUE ), TRUE ); + if ( prop ) { + QValueList l; + l << QStringList( prop->type() ); + return l; + } + + return QValueList(); +} + +void CppEditorCompletion::setContext( QObject *this_ ) +{ + ths = this_; +} diff --git a/tools/designer/plugins/cppeditor/cppcompletion.h b/tools/designer/plugins/cppeditor/cppcompletion.h new file mode 100644 index 0000000..170c850 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppcompletion.h @@ -0,0 +1,60 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CPPCOMPLETION_H +#define CPPCOMPLETION_H + +#include +#include + +class CppEditorCompletion : public EditorCompletion +{ + Q_OBJECT + +public: + CppEditorCompletion( Editor *e ); + +#if defined(Q_USING) + using EditorCompletion::doObjectCompletion; +#endif + bool doObjectCompletion( const QString &object ); + QValueList functionParameters( const QString &func, QChar &, QString &prefix, QString &postfix ); + void setContext( QObject *this_ ); + +private: + QGuardedPtr ths; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/cppeditor.cpp b/tools/designer/plugins/cppeditor/cppeditor.cpp new file mode 100644 index 0000000..37aa9cc --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppeditor.cpp @@ -0,0 +1,168 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "cppeditor.h" +#include "syntaxhighliter_cpp.h" +#include +#include "cppcompletion.h" +#include "cppbrowser.h" +#include +#include +#include +#include +#include + +CppEditor::CppEditor( const QString &fn, QWidget *parent, const char *name, DesignerInterface *i ) + : Editor( fn, parent, name ), dIface( i ) +{ + if ( dIface ) + dIface->addRef(); + document()->setPreProcessor( new SyntaxHighlighter_CPP ); + document()->setIndent( (indent = new CIndent) ); + completion = new CppEditorCompletion( this ); + browser = new CppEditorBrowser( this ); + int j = 0; + while ( SyntaxHighlighter_CPP::keywords[ j ] != QString::null ) + completion->addCompletionEntry( SyntaxHighlighter_CPP::keywords[ j++ ], 0, FALSE ); + configChanged(); +} + +CppEditor::~CppEditor() +{ + delete completion; + if ( dIface ) + dIface->release(); +} + +void CppEditor::configChanged() +{ + QString path = "/Trolltech/CppEditor/"; + QMap styles = Config::readStyles( path ); + config()->styles = styles; + ( (SyntaxHighlighter_CPP*)document()->preProcessor() )->updateStyles( config()->styles ); + + completion->setEnabled( Config::completion( path ) ); + parenMatcher->setEnabled( Config::parenMatching( path ) ); + if ( Config::wordWrap( path ) ) { + if ( hScrollBarMode() != AlwaysOff ) { + document()->setFormatter( new QTextFormatterBreakInWords ); + setHScrollBarMode( AlwaysOff ); + } + } else { + if ( hScrollBarMode() != AlwaysOn ) { + QTextFormatterBreakWords *f = new QTextFormatterBreakWords; + f->setWrapEnabled( FALSE ); + document()->setFormatter( f ); + setHScrollBarMode( AlwaysOn ); + } + } + + setFont( ( (SyntaxHighlighter_CPP*)document()->preProcessor() )->format( 0 )->font() ); + + indent->setTabSize( Config::indentTabSize( path ) ); + indent->setIndentSize( Config::indentIndentSize( path ) ); + indent->setKeepTabs( Config::indentKeepTabs( path ) ); + indent->setAutoIndent( Config::indentAutoIndent( path ) ); + if ( !Config::indentAutoIndent( path ) ) + document()->setIndent( 0 ); + else + document()->setIndent( indent ); + + document()->setTabStops( ( (SyntaxHighlighter_CPP*)document()->preProcessor() )->format( QTextPreProcessor::Standard )->width( 'x' ) * Config::indentTabSize( path ) ); + + Editor::configChanged(); +} + +QPopupMenu *CppEditor::createPopupMenu( const QPoint &p ) +{ + QPopupMenu *m = Editor::createPopupMenu( p ); + m->insertSeparator(); + int adddeclid = m->insertItem( tr( "Add Include File (in Declaration)..." ), this, SLOT( addInclDecl() ) ); + int addimplid = m->insertItem( tr( "Add Include File (in Implementation)..." ), this, SLOT( addInclImpl() ) ); + int addforid = m->insertItem( tr( "Add Forward Declaration..." ), this, SLOT( addForward() ) ); + if ( !dIface->currentForm() ) { + m->setItemEnabled( adddeclid, FALSE ); + m->setItemEnabled( addimplid, FALSE ); + m->setItemEnabled( addforid, FALSE ); + } + return m; +} + +void CppEditor::addInclDecl() +{ + if ( !dIface ) + return; + QString s = QInputDialog::getText( tr( "Add Include File (In Declaration)" ), + tr( "Input this using the format <include.h> or \"include.h\"" ) ); + if ( s.isEmpty() ) + return; + DesignerFormWindow *form = dIface->currentForm(); + QStringList lst = form->declarationIncludes(); + lst << s; + form->setDeclarationIncludes( lst ); +} + +void CppEditor::addInclImpl() +{ + if ( !dIface ) + return; + QString s = QInputDialog::getText( tr( "Add Include File (In Implementation)" ), + tr( "Input this using the format <include.h> or \"include.h\"" ) ); + if ( s.isEmpty() ) + return; + DesignerFormWindow *form = dIface->currentForm(); + QStringList lst = form->implementationIncludes(); + lst << s; + form->setImplementationIncludes( lst ); +} + +void CppEditor::addForward() +{ + if ( !dIface ) + return; + QString s = QInputDialog::getText( tr( "Add Forward Declaration" ), + tr( "Input this using the format ClassName;" ) ); + if ( s.isEmpty() ) + return; + DesignerFormWindow *form = dIface->currentForm(); + QStringList lst = form->forwardDeclarations(); + lst << s; + form->setForwardDeclarations( lst ); +} + +void CppEditor::paste() +{ + Editor::paste(); + emit intervalChanged(); +} diff --git a/tools/designer/plugins/cppeditor/cppeditor.h b/tools/designer/plugins/cppeditor/cppeditor.h new file mode 100644 index 0000000..05d7930 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppeditor.h @@ -0,0 +1,78 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CPPEDITOR_H +#define CPPEDITOR_H + +#include + +class EditorCompletion; +class EditorBrowser; +struct DesignerInterface; +class CIndent; + +class CppEditor : public Editor +{ + Q_OBJECT + +public: + CppEditor( const QString &fn, QWidget *parent, const char *name, DesignerInterface *i ); + ~CppEditor(); + + virtual EditorCompletion *completionManager() { return completion; } + virtual EditorBrowser *browserManager() { return browser; } + void configChanged(); + + bool supportsBreakPoints() const { return FALSE; } +#if defined(Q_USING) + using QTextEdit::createPopupMenu; +#endif + QPopupMenu *createPopupMenu( const QPoint &p ); + + void paste(); + +private slots: + void addInclDecl(); + void addInclImpl(); + void addForward(); + +protected: + EditorCompletion *completion; + EditorBrowser *browser; + DesignerInterface *dIface; + CIndent *indent; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/cppeditor.pro b/tools/designer/plugins/cppeditor/cppeditor.pro new file mode 100644 index 0000000..391c1d7 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppeditor.pro @@ -0,0 +1,21 @@ +TEMPLATE = lib +CONFIG += qt warn_on plugin + +SOURCES += cppeditor.cpp syntaxhighliter_cpp.cpp cppcompletion.cpp editorinterfaceimpl.cpp languageinterfaceimpl.cpp common.cpp preferenceinterfaceimpl.cpp yyreg.cpp cppbrowser.cpp projectsettingsinterfaceimpl.cpp sourcetemplateinterfaceimpl.cpp +HEADERS += cppeditor.h syntaxhighliter_cpp.h cppcompletion.h editorinterfaceimpl.h languageinterfaceimpl.h preferenceinterfaceimpl.h yyreg.h cppbrowser.h projectsettingsinterfaceimpl.h sourcetemplateinterfaceimpl.h +FORMS = projectsettings.ui mainfilesettings.ui + +TARGET = cppeditor +DESTDIR = ../../../../plugins/designer +VERSION = 1.0.0 + +INCLUDEPATH += ../../interfaces ../../editor $$QT_BUILD_TREE/tools/designer/editor + +hpux-* { + LIBS += $$QT_BUILD_TREE/lib/libeditor.a +} else { + LIBS += -L$$QT_BUILD_TREE/lib -leditor +} + +target.path += $$plugins.path/designer +INSTALLS += target diff --git a/tools/designer/plugins/cppeditor/editorinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/editorinterfaceimpl.cpp new file mode 100644 index 0000000..d396720 --- /dev/null +++ b/tools/designer/plugins/cppeditor/editorinterfaceimpl.cpp @@ -0,0 +1,338 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "editorinterfaceimpl.h" +#include +#include "cppeditor.h" +#include +#include +#include "completion.h" +#include +#include + +EditorInterfaceImpl::EditorInterfaceImpl() + : EditorInterface(), viewManager( 0 ), dIface( 0 ) +{ + updateTimer = new QTimer( this ); + connect( updateTimer, SIGNAL( timeout() ), + this, SLOT( update() ) ); +} + +EditorInterfaceImpl::~EditorInterfaceImpl() +{ + updateTimer->stop(); + delete (ViewManager*)viewManager; + if ( dIface ) + dIface->release(); +} + +QRESULT EditorInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_Editor ) + *iface = (EditorInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QWidget *EditorInterfaceImpl::editor( bool readonly, + QWidget *parent, QUnknownInterface *iface ) +{ + if ( !viewManager ) { + ( (EditorInterfaceImpl*)this )->viewManager = new ViewManager( parent, 0 ); + ( (EditorInterfaceImpl*)this )->viewManager->showMarkerWidget( FALSE ); + if ( iface ) + iface->queryInterface( IID_Designer, (QUnknownInterface**) &dIface ); + CppEditor *e = new CppEditor( QString::null, viewManager, "editor", dIface ); + e->setEditable( !readonly ); + e->installEventFilter( this ); + connect( e, SIGNAL( intervalChanged() ), this, SLOT( intervalChanged() ) ); + QApplication::sendPostedEvents( viewManager, QEvent::ChildInserted ); + } + return viewManager->currentView(); +} + +void EditorInterfaceImpl::setText( const QString &txt ) +{ + if ( !viewManager || !viewManager->currentView() ) + return; + CppEditor *e = (CppEditor*)viewManager->currentView(); + disconnect( e, SIGNAL( modificationChanged( bool ) ), this, SLOT( modificationChanged( bool ) ) ); + e->setText( txt ); + e->setModified( FALSE ); + connect( e, SIGNAL( modificationChanged( bool ) ), this, SLOT( modificationChanged( bool ) ) ); +} + +QString EditorInterfaceImpl::text() const +{ + if ( !viewManager || !viewManager->currentView() ) + return QString::null; + QString txt = ( (CppEditor*)viewManager->currentView() )->text(); + if ( !txt.isEmpty() && !txt.endsWith("\n") ) + txt += "\n"; + return txt; +} + +bool EditorInterfaceImpl::isUndoAvailable() const +{ + if ( !viewManager || !viewManager->currentView() ) + return FALSE; + return ( (CppEditor*)viewManager->currentView() )->isUndoAvailable(); +} + +bool EditorInterfaceImpl::isRedoAvailable() const +{ + if ( !viewManager || !viewManager->currentView() ) + return FALSE; + return ( (CppEditor*)viewManager->currentView() )->isRedoAvailable(); +} + +void EditorInterfaceImpl::undo() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->undo(); +} + +void EditorInterfaceImpl::redo() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->redo(); +} + +void EditorInterfaceImpl::cut() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->cut(); +} + +void EditorInterfaceImpl::copy() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->copy(); +} + +void EditorInterfaceImpl::paste() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->paste(); +} + +void EditorInterfaceImpl::selectAll() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->selectAll(); +} + +bool EditorInterfaceImpl::find( const QString &expr, bool cs, bool wo, bool forward, bool startAtCursor ) +{ + if ( !viewManager || !viewManager->currentView() ) + return FALSE; + CppEditor *e = (CppEditor*)viewManager->currentView(); + if ( startAtCursor ) + return e->find( expr, cs, wo, forward ); + int dummy = 0; + return e->find( expr, cs, wo, forward, &dummy, &dummy ); +} + +bool EditorInterfaceImpl::replace( const QString &find, const QString &replace, bool cs, bool wo, + bool forward, bool startAtCursor, bool replaceAll ) +{ + if ( !viewManager || !viewManager->currentView() ) + return FALSE; + CppEditor *e = (CppEditor*)viewManager->currentView(); + bool ok = FALSE; + if ( startAtCursor ) { + ok = e->find( find, cs, wo, forward ); + } else { + int dummy = 0; + ok = e->find( find, cs, wo, forward, &dummy, &dummy ); + } + + if ( ok ) { + e->removeSelectedText(); + e->insert( replace, FALSE, FALSE ); + } + + if ( !replaceAll || !ok ) { + if ( ok ) + e->setSelection( e->textCursor()->paragraph()->paragId(), + e->textCursor()->index() - replace.length(), + e->textCursor()->paragraph()->paragId(), + e->textCursor()->index() ); + return ok; + } + + bool ok2 = TRUE; + while ( ok2 ) { + ok2 = e->find( find, cs, wo, forward ); + if ( ok2 ) { + e->removeSelectedText(); + e->insert( replace, FALSE, FALSE ); + } + } + + return TRUE; +} + +void EditorInterfaceImpl::gotoLine( int line ) +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->setCursorPosition( line, 0 ); +} + +void EditorInterfaceImpl::indent() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->QTextEdit::indent(); +} + +void EditorInterfaceImpl::splitView() +{ +#if 0 + if ( !viewManager || !viewManager->currentView() ) + return; + QTextDocument *doc = ( (CppEditor*)viewManager->currentView() )->document(); + CppEditor *editor = new CppEditor( QString::null, viewManager, "editor" ); + editor->setDocument( doc ); +#endif +} + +void EditorInterfaceImpl::scrollTo( const QString &txt, const QString & ) +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->sync(); + QTextDocument *doc = ( (CppEditor*)viewManager->currentView() )->document(); + QTextParagraph *p = doc->firstParagraph(); + while ( p ) { + if ( p->string()->toString().find( txt ) != -1 ) { + ( (CppEditor*)viewManager->currentView() )->setCursorPosition( p->paragId() + 2, 0 ); + break; + } + p = p->next(); + } + ( (CppEditor*)viewManager->currentView() )->setFocus(); +} + +void EditorInterfaceImpl::setContext( QObject *this_ ) +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->completionManager()->setContext( this_ ); +} + +void EditorInterfaceImpl::setError( int line ) +{ + if ( !viewManager ) + return; + viewManager->setError( line ); +} + +void EditorInterfaceImpl::readSettings() +{ + if ( !viewManager ) + return; + ( (CppEditor*)viewManager->currentView() )->configChanged(); +} + +void EditorInterfaceImpl::modificationChanged( bool m ) +{ + if ( viewManager && dIface ) + dIface->setModified( m, viewManager->currentView() ); +} + +void EditorInterfaceImpl::setModified( bool m ) +{ + if ( !viewManager ) + return; + ( (CppEditor*)viewManager->currentView() )->setModified( m ); +} + +bool EditorInterfaceImpl::isModified() const +{ + if ( !viewManager ) + return FALSE; + return ( (CppEditor*)viewManager->currentView() )->isModified(); +} + +bool EditorInterfaceImpl::eventFilter( QObject *o, QEvent *e ) +{ + if ( e->type() == QEvent::KeyPress ) + updateTimer->stop(); + else if ( e->type() == QEvent::FocusOut ) + update(); + + return QObject::eventFilter( o, e ); +} + +int EditorInterfaceImpl::numLines() const +{ + if ( !viewManager || !viewManager->currentView() ) + return 0; + return ( (CppEditor*)viewManager->currentView() )->paragraphs(); +} + +void EditorInterfaceImpl::intervalChanged() +{ + if ( !dIface ) + return; + updateTimer->start( 2000, TRUE ); +} + +void EditorInterfaceImpl::update() +{ + if ( !dIface ) + return; + dIface->updateFunctionList(); +} + +void EditorInterfaceImpl::onBreakPointChange( QObject *receiver, const char *slot ) +{ + if ( !viewManager ) + return; + connect( viewManager, SIGNAL( markersChanged() ), receiver, slot ); +} diff --git a/tools/designer/plugins/cppeditor/editorinterfaceimpl.h b/tools/designer/plugins/cppeditor/editorinterfaceimpl.h new file mode 100644 index 0000000..06b3d2a --- /dev/null +++ b/tools/designer/plugins/cppeditor/editorinterfaceimpl.h @@ -0,0 +1,107 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef EDITORINTERFACEIMPL_H +#define EDITORINTERFACEIMPL_H + +#include +#include +#include + +class QTimer; +class ViewManager; +struct DesignerInterface; + +class EditorInterfaceImpl : public QObject, public EditorInterface +{ + Q_OBJECT + +public: + EditorInterfaceImpl(); + virtual ~EditorInterfaceImpl(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT; + + QWidget *editor( bool readonly, QWidget *parent, QUnknownInterface *designerIface ); + + void setText( const QString &txt ); + QString text() const; + bool isUndoAvailable() const; + bool isRedoAvailable() const; + void undo(); + void redo(); + void cut(); + void copy(); + void paste(); + void selectAll(); + bool find( const QString &expr, bool cs, bool wo, bool forward, bool startAtCursor ); + bool replace( const QString &find, const QString &replace, bool cs, bool wo, bool forward, bool startAtCursor, bool replaceAll ); + void gotoLine( int line ); + void indent(); + void scrollTo( const QString &txt, const QString &first ); + void splitView(); + void setContext( QObject *this_ ); + void readSettings(); + + void setError( int line ); + void setStep( int ) {} + void clearStep() {} + void setModified( bool m ); + bool isModified() const; + void setMode( Mode ) {} + + int numLines() const; + void breakPoints( QValueList & ) const {} + void setBreakPoints( const QValueList & ) {} + void onBreakPointChange( QObject *receiver, const char *slot ); + void clearStackFrame() {} + void setStackFrame( int ) {} + +protected: + bool eventFilter( QObject*, QEvent* ); + +private slots: + void modificationChanged( bool m ); + void intervalChanged(); + void update(); + +private: + QGuardedPtr viewManager; + DesignerInterface *dIface; + QTimer *updateTimer; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/languageinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/languageinterfaceimpl.cpp new file mode 100644 index 0000000..124be70 --- /dev/null +++ b/tools/designer/plugins/cppeditor/languageinterfaceimpl.cpp @@ -0,0 +1,249 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "languageinterfaceimpl.h" +#include +#include +#include +#include "yyreg.h" +#include + +LanguageInterfaceImpl::LanguageInterfaceImpl( QUnknownInterface *outer ) + : parent( outer ), ref( 0 ) +{ +} + +ulong LanguageInterfaceImpl::addRef() +{ + return parent ? parent->addRef() : ref++; +} + +ulong LanguageInterfaceImpl::release() +{ + if ( parent ) + return parent->release(); + if ( !--ref ) { + delete this; + return 0; + } + return ref; +} + +QRESULT LanguageInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + if ( parent ) + return parent->queryInterface( uuid, iface ); + + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_Language ) + *iface = (LanguageInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + + +class NormalizeObject : public QObject +{ +public: + NormalizeObject() : QObject() {} + static QCString normalizeSignalSlot( const char *signalSlot ) { return QObject::normalizeSignalSlot( signalSlot ); } +}; + +void LanguageInterfaceImpl::functions( const QString &code, QValueList *functionMap ) const +{ + QValueList l; + extractCppFunctions( code, &l ); + for ( QValueList::Iterator it = l.begin(); it != l.end(); ++it ) { + Function func; + func.name = (*it).prototype(); + func.name.remove( 0, (*it).returnType().length() ); + if ( func.name.find( "::" ) == -1 ) + continue; + func.name.remove( (uint)0, func.name.find( "::" ) + 2 ); + func.body = (*it).body(); + func.returnType = (*it).returnType(); + func.start = (*it).functionStartLineNum(); + func.end = (*it).closingBraceLineNum(); + functionMap->append( func ); + } +} + +QString LanguageInterfaceImpl::createFunctionStart( const QString &className, const QString &func, + const QString &returnType, + const QString & ) +{ + return returnType + " " + className + "::" + func; +} + +QStringList LanguageInterfaceImpl::definitions() const +{ + QStringList lst; + lst << "Includes (in Implementation)" << "Includes (in Declaration)" << "Forward Declarations" << "Signals"; + return lst; +} + +QStringList LanguageInterfaceImpl::definitionEntries( const QString &definition, QUnknownInterface *designerIface ) const +{ + DesignerInterface *iface = 0; + designerIface->queryInterface( IID_Designer, (QUnknownInterface**) &iface ); + if ( !iface ) + return QStringList(); + DesignerFormWindow *fw = iface->currentForm(); + if ( !fw ) + return QStringList(); + QStringList lst; + if ( definition == "Includes (in Implementation)" ) { + lst = fw->implementationIncludes(); + } else if ( definition == "Includes (in Declaration)" ) { + lst = fw->declarationIncludes(); + } else if ( definition == "Forward Declarations" ) { + lst = fw->forwardDeclarations(); + } else if ( definition == "Signals" ) { + lst = fw->signalList(); + } + iface->release(); + return lst; +} + +void LanguageInterfaceImpl::setDefinitionEntries( const QString &definition, const QStringList &entries, QUnknownInterface *designerIface ) +{ + DesignerInterface *iface = 0; + designerIface->queryInterface( IID_Designer, (QUnknownInterface**) &iface ); + if ( !iface ) + return; + DesignerFormWindow *fw = iface->currentForm(); + if ( !fw ) + return; + if ( definition == "Includes (in Implementation)" ) { + fw->setImplementationIncludes( entries ); + } else if ( definition == "Includes (in Declaration)" ) { + fw->setDeclarationIncludes( entries ); + } else if ( definition == "Forward Declarations" ) { + fw->setForwardDeclarations( entries ); + } else if ( definition == "Signals" ) { + fw->setSignalList( entries ); + } + iface->release(); +} + +QString LanguageInterfaceImpl::createEmptyFunction() +{ + return "{\n\n}\n"; +} + +bool LanguageInterfaceImpl::supports( Support s ) const +{ + if ( s == ReturnType ) + return TRUE; + if ( s == ConnectionsToCustomSlots ) + return TRUE; + return FALSE; +} + +QStringList LanguageInterfaceImpl::fileFilterList() const +{ + QStringList f; + f << "C++ Files (*.cpp *.C *.cxx *.c++ *.c *.h *.H *.hpp *.hxx)"; + return f; + +} +QStringList LanguageInterfaceImpl::fileExtensionList() const +{ + QStringList f; + f << "cpp" << "C" << "cxx" << "c++" << "c" <<"h" << "H" << "hpp" << "hxx"; + return f; +} + +QString LanguageInterfaceImpl::projectKeyForExtension( const QString &extension ) const +{ + // also handle something like foo.ut.cpp + QString ext = extension; + int i = ext.findRev('.'); + if ( i > -1 && i < (int)(ext.length()-1) ) + ext = ext.mid( i + 1 ); + if ( ext[ 0 ] == 'c' || ext[ 0 ] == 'C' ) + return "SOURCES"; + return "HEADERS"; +} + +void LanguageInterfaceImpl::sourceProjectKeys( QStringList &keys ) const +{ + keys << "HEADERS" << "SOURCES"; +} + + class CheckObject : public QObject +{ +public: + CheckObject() {} + bool checkConnectArgs( const char *signal, const char *member ) { return QObject::checkConnectArgs( signal, 0, member ); } + +}; + +bool LanguageInterfaceImpl::canConnect( const QString &signal, const QString &slot ) +{ + CheckObject o; + return o.checkConnectArgs( signal.latin1(), slot.latin1() ); +} + +void LanguageInterfaceImpl::loadFormCode( const QString &, const QString &filename, + QValueList &functions, + QStringList &, + QValueList & ) +{ + QFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + QString code( ts.read() ); + this->functions( code, &functions ); +} + +void LanguageInterfaceImpl::preferedExtensions( QMap &extensionMap ) const +{ + extensionMap.insert( "cpp", "C++ Source File" ); + extensionMap.insert( "h", "C++ Header File" ); +} + +QStrList LanguageInterfaceImpl::signalNames( QObject *obj ) const +{ + QStrList sigs; + sigs = obj->metaObject()->signalNames( TRUE ); + sigs.remove( "destroyed()" ); + return sigs; +} diff --git a/tools/designer/plugins/cppeditor/languageinterfaceimpl.h b/tools/designer/plugins/cppeditor/languageinterfaceimpl.h new file mode 100644 index 0000000..55781e7 --- /dev/null +++ b/tools/designer/plugins/cppeditor/languageinterfaceimpl.h @@ -0,0 +1,90 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LANGUAGEINTERFACEIMPL_H +#define LANGUAGEINTERFACEIMPL_H + +#include + +class LanguageInterfaceImpl : public LanguageInterface +{ +public: + LanguageInterfaceImpl( QUnknownInterface *outer = 0 ); + + ulong addRef(); + ulong release(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + + void functions( const QString &code, QValueList *funcs ) const; + void connections( const QString &, QValueList * ) const {}; + QString createFunctionStart( const QString &className, const QString &func, + const QString &returnType, const QString &access ); + QStringList definitions() const; + QStringList definitionEntries( const QString &definition, QUnknownInterface *designerIface ) const; + void setDefinitionEntries( const QString &definition, const QStringList &entries, QUnknownInterface *designerIface ); + QString createArguments( const QString & ) { return QString::null; } + QString createEmptyFunction(); + bool supports( Support s ) const; + QStringList fileFilterList() const; + QStringList fileExtensionList() const; + void preferedExtensions( QMap &extensionMap ) const; + void sourceProjectKeys( QStringList &keys ) const; + QString projectKeyForExtension( const QString &extension ) const; + QString cleanSignature( const QString &sig ) { return sig; } // #### implement me + void loadFormCode( const QString &, const QString &, + QValueList &, + QStringList &, + QValueList & ); + QString formCodeExtension() const { return ".h"; } + bool canConnect( const QString &signal, const QString &slot ); + void compressProject( const QString &, const QString &, bool ) {} + QString uncompressProject( const QString &, const QString & ) { return QString::null; } + QString aboutText() const { return ""; } + + void addConnection( const QString &, const QString &, + const QString &, const QString &, + QString * ) {} + void removeConnection( const QString &, const QString &, + const QString &, const QString &, + QString * ) {} + QStrList signalNames( QObject *obj ) const; + +private: + QUnknownInterface *parent; + ulong ref; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/mainfilesettings.ui b/tools/designer/plugins/cppeditor/mainfilesettings.ui new file mode 100644 index 0000000..2816cda --- /dev/null +++ b/tools/designer/plugins/cppeditor/mainfilesettings.ui @@ -0,0 +1,211 @@ + +CppMainFile +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + CppMainFile + + + + 0 + 0 + 308 + 283 + + + + Configure Main-File + + + + unnamed + + + 11 + + + 6 + + + + TextLabel1 + + + Filename: + + + + + editFileName + + + + + TextLabel2 + + + Main-Form: + + + + + listForms + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + Help + + + 4144 + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + OK + + + 0 + + + true + + + true + + + + + buttonCancel + + + Cancel + + + 0 + + + true + + + + + + + + + buttonOk + clicked() + CppMainFile + accept() + + + buttonCancel + clicked() + CppMainFile + reject() + + + listForms + selectionChanged() + CppMainFile + updateOkButton() + + + listForms + currentChanged(QListBoxItem*) + CppMainFile + updateOkButton() + + + editFileName + textChanged(const QString&) + CppMainFile + updateOkButton() + + + + mainfilesettings.ui.h + + + struct QUnknownInterface; + + + init() + setup( QUnknownInterface * appIface ) + updateOkButton() + + + + diff --git a/tools/designer/plugins/cppeditor/mainfilesettings.ui.h b/tools/designer/plugins/cppeditor/mainfilesettings.ui.h new file mode 100644 index 0000000..ea79101 --- /dev/null +++ b/tools/designer/plugins/cppeditor/mainfilesettings.ui.h @@ -0,0 +1,36 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +#include + +void CppMainFile::init() +{ +} + +void CppMainFile::setup( QUnknownInterface *appIface ) +{ + DesignerInterface *dIface = 0; + appIface->queryInterface( IID_Designer, (QUnknownInterface**)&dIface ); + if ( !dIface ) + return; + QStringList l = dIface->currentProject()->formNames(); + editFileName->setText( "main.cpp" ); + listForms->clear(); + listForms->insertStringList( l ); + listForms->setCurrentItem( 0 ); + updateOkButton(); + editFileName->setFocus(); + editFileName->selectAll(); +} + +void CppMainFile::updateOkButton() +{ + buttonOk->setEnabled( editFileName->text().length() > 0 && listForms->currentItem() != -1 ); +} + + diff --git a/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.cpp new file mode 100644 index 0000000..b6dd10c --- /dev/null +++ b/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.cpp @@ -0,0 +1,102 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "preferenceinterfaceimpl.h" +#include + +PreferenceInterfaceImpl::PreferenceInterfaceImpl( QUnknownInterface *outer ) + : parent( outer ), + ref( 0 ), + cppEditorSyntax( 0 ) +{ +} + +PreferenceInterfaceImpl::~PreferenceInterfaceImpl() +{ +} + +ulong PreferenceInterfaceImpl::addRef() +{ + return parent ? parent->addRef() : ref++; +} + +ulong PreferenceInterfaceImpl::release() +{ + if ( parent ) + return parent->release(); + if ( !--ref ) { + delete this; + return 0; + } + return ref; +} + +QRESULT PreferenceInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + if ( parent ) + return parent->queryInterface( uuid, iface ); + + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_Preference ) + *iface = (PreferenceInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +PreferenceInterface::Preference *PreferenceInterfaceImpl::preference() +{ + if ( !cppEditorSyntax ) { + cppEditorSyntax = new PreferencesBase( 0, "cppeditor_syntax" ); + ( (PreferencesBase*)cppEditorSyntax )->setPath( "/Trolltech/CppEditor/" ); + cppEditorSyntax->hide(); + } + Preference *pf = 0; + pf = new Preference; + pf->tab = cppEditorSyntax; + pf->title = "C++ Editor"; + pf->receiver = pf->tab; + pf->init_slot = SLOT( reInit() ); + pf->accept_slot = SLOT( save() ); + return pf; +} + +void PreferenceInterfaceImpl::deletePreferenceObject( Preference *p ) +{ + delete p; +} diff --git a/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.h b/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.h new file mode 100644 index 0000000..e1225fc --- /dev/null +++ b/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.h @@ -0,0 +1,64 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PREFERENCEINTERFACEIMPL_H +#define PREFERENCEINTERFACEIMPL_H + +#include +class QWidget; + +class PreferenceInterfaceImpl : public PreferenceInterface +{ +public: + PreferenceInterfaceImpl( QUnknownInterface *outer = 0 ); + virtual ~PreferenceInterfaceImpl(); + + ulong addRef(); + ulong release(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + + Preference *preference(); + void connectTo( QUnknownInterface * ) {} + void deletePreferenceObject( Preference * ); + +private: + QUnknownInterface *parent; + int ref; + QWidget *cppEditorSyntax; + +}; + +#endif + diff --git a/tools/designer/plugins/cppeditor/projectsettings.ui b/tools/designer/plugins/cppeditor/projectsettings.ui new file mode 100644 index 0000000..d5d9d87 --- /dev/null +++ b/tools/designer/plugins/cppeditor/projectsettings.ui @@ -0,0 +1,347 @@ + +CppProjectSettings +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* +projectsettings.ui.h +struct QUnknownInterface; +QMap<QString, QString> config, libs, defines, includes; + + + + + CppProjectSettings + + + + 0 + 0 + 373 + 191 + + + + Project Settings + + + + unnamed + + + 11 + + + 6 + + + + TextLabel1 + + + Config: + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + TextLabel2_2 + + + Defines: + + + + + editDefines + + + + + TextLabel2 + + + Libs: + + + + + TextLabel2_3 + + + Includepath: + + + + + + (all) + + + + + unix + + + + + win32 + + + + + mac + + + + comboDefines + + + + + + (all) + + + + + unix + + + + + win32 + + + + + mac + + + + comboInclude + + + + + editInclude + + + + + editLibs + + + + + editConfig + + + + + + (all) + + + + + unix + + + + + win32 + + + + + mac + + + + comboLibs + + + + + + (all) + + + + + unix + + + + + win32 + + + + + mac + + + + comboConfig + + + + + TextLabel3 + + + Template: + + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + app + + + + + lib + + + + comboTemplate + + + + + + + comboConfig + activated(const QString&) + CppProjectSettings + configPlatformChanged(const QString&) + + + comboLibs + activated(const QString&) + CppProjectSettings + libsPlatformChanged(const QString&) + + + comboDefines + activated(const QString&) + CppProjectSettings + definesPlatformChanged(const QString&) + + + editConfig + textChanged(const QString&) + CppProjectSettings + configChanged(const QString&) + + + editLibs + textChanged(const QString&) + CppProjectSettings + libsChanged(const QString&) + + + editDefines + textChanged(const QString&) + CppProjectSettings + definesChanged(const QString&) + + + editInclude + textChanged(const QString&) + CppProjectSettings + includesChanged(const QString&) + + + comboInclude + activated(const QString&) + CppProjectSettings + includesPlatformChanged(const QString&) + + reInit( QUnknownInterface * iface ) + save( QUnknownInterface * iface ) + configChanged( const QString & str ) + libsChanged( const QString & str ) + definesChanged( const QString & str ) + includesChanged( const QString & str ) + configPlatformChanged( const QString & plat ) + libsPlatformChanged( const QString & plat ) + definesPlatformChanged( const QString & plat ) + includesPlatformChanged( const QString & plat ) + + + comboTemplate + comboConfig + editConfig + comboLibs + editLibs + comboDefines + editDefines + comboInclude + editInclude + + diff --git a/tools/designer/plugins/cppeditor/projectsettings.ui.h b/tools/designer/plugins/cppeditor/projectsettings.ui.h new file mode 100644 index 0000000..f5de0b7 --- /dev/null +++ b/tools/designer/plugins/cppeditor/projectsettings.ui.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** Add custom slot implementations here. Use a slot init() for +** initialization code called during construction, and a slot destroy() +** for cleanup code called during destruction. +** +** This file gets modified by Qt Designer whenever you add, rename or +** remove custom slots. Implementation code does not get lost. +*****************************************************************************/ + +#include + +void CppProjectSettings::reInit( QUnknownInterface *iface ) +{ + comboConfig->setCurrentItem( 0 ); + comboLibs->setCurrentItem( 0 ); + comboDefines->setCurrentItem( 0 ); + comboInclude->setCurrentItem( 0 ); + + DesignerInterface *dIface = 0; + iface->queryInterface( IID_Designer, (QUnknownInterface**)&dIface ); + if ( !dIface ) + return; + DesignerProject *project = dIface->currentProject(); + if ( project->templte() == "app" ) + comboTemplate->setCurrentItem( 0 ); + else + comboTemplate->setCurrentItem( 1 ); + + config.clear(); + defines.clear(); + libs.clear(); + defines.clear(); + includes.clear(); + + const QString platforms[] = { "(all)", "win32", "unix", "mac", QString::null }; + for ( int i = 0; platforms[ i ] != QString::null; ++i ) { + config.replace( platforms[ i ], project->config( platforms[ i ] ) ); + libs.replace( platforms[ i ], project->libs( platforms[ i ] ) ); + defines.replace( platforms[ i ], project->defines( platforms[ i ] ) ); + includes.replace( platforms[ i ], project->includePath( platforms[ i ] ) ); + } + editConfig->setText( config[ "(all)" ] ); + editLibs->setText( libs[ "(all)" ] ); + editDefines->setText( defines[ "(all)" ] ); + editInclude->setText( includes[ "(all)" ] ); +} + +void CppProjectSettings::save( QUnknownInterface *iface ) +{ + DesignerInterface *dIface = 0; + iface->queryInterface( IID_Designer, (QUnknownInterface**)&dIface ); + if ( !dIface ) + return; + DesignerProject *project = dIface->currentProject(); + + project->setTemplate( comboTemplate->currentText() ); + const QString platforms[] = { "(all)", "win32", "unix", "mac", QString::null }; + for ( int i = 0; platforms[ i ] != QString::null; ++i ) { + project->setConfig( platforms[ i ], config[ platforms[ i ] ] ); + project->setLibs( platforms[ i ], libs[ platforms[ i ] ] ); + project->setDefines( platforms[ i ], defines[ platforms[ i ] ] ); + project->setIncludePath( platforms[ i ], includes[ platforms[ i ] ] ); + } +} + +void CppProjectSettings::configChanged( const QString &str ) +{ + config.replace( comboConfig->currentText(), str ); +} + +void CppProjectSettings::libsChanged( const QString &str ) +{ + libs.replace( comboLibs->currentText(), str ); +} + +void CppProjectSettings::definesChanged( const QString &str ) +{ + defines.replace( comboDefines->currentText(), str ); +} + +void CppProjectSettings::includesChanged( const QString &str ) +{ + includes.replace( comboInclude->currentText(), str ); +} + +void CppProjectSettings::configPlatformChanged( const QString &plat ) +{ + editConfig->setText( config[ plat ] ); +} + +void CppProjectSettings::libsPlatformChanged( const QString &plat ) +{ + editLibs->setText( libs[ plat ] ); +} + +void CppProjectSettings::definesPlatformChanged( const QString &plat ) +{ + editDefines->setText( defines[ plat ] ); +} + +void CppProjectSettings::includesPlatformChanged( const QString &plat ) +{ + editInclude->setText( includes[ plat ] ); +} diff --git a/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.cpp new file mode 100644 index 0000000..9bb5d51 --- /dev/null +++ b/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.cpp @@ -0,0 +1,106 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "projectsettingsinterfaceimpl.h" +#include "projectsettings.h" + +ProjectSettingsInterfaceImpl::ProjectSettingsInterfaceImpl( QUnknownInterface *outer ) + : parent( outer ), + ref( 0 ), + settingsTab( 0 ) +{ +} + +ulong ProjectSettingsInterfaceImpl::addRef() +{ + return parent ? parent->addRef() : ref++; +} + +ulong ProjectSettingsInterfaceImpl::release() +{ + if ( parent ) + return parent->release(); + if ( !--ref ) { + delete this; + return 0; + } + return ref; +} + +ProjectSettingsInterface::ProjectSettings *ProjectSettingsInterfaceImpl::projectSetting() +{ + if ( !settingsTab ) { + settingsTab = new CppProjectSettings( 0 ); + settingsTab->hide(); + } + ProjectSettings *pf = 0; + pf = new ProjectSettings; + pf->tab = settingsTab; + pf->title = "C++"; + pf->receiver = pf->tab; + pf->init_slot = SLOT( reInit( QUnknownInterface * ) ); + pf->accept_slot = SLOT( save( QUnknownInterface * ) ); + return pf; +} + +QStringList ProjectSettingsInterfaceImpl::projectSettings() const +{ + return QStringList(); +} + +void ProjectSettingsInterfaceImpl::connectTo( QUnknownInterface * ) +{ +} + +void ProjectSettingsInterfaceImpl::deleteProjectSettingsObject( ProjectSettings *pf ) +{ + delete pf; +} + +QRESULT ProjectSettingsInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + if ( parent ) + return parent->queryInterface( uuid, iface ); + + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_ProjectSettings ) + *iface = (ProjectSettingsInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} diff --git a/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.h b/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.h new file mode 100644 index 0000000..0cd0f45 --- /dev/null +++ b/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.h @@ -0,0 +1,62 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PROJECTSETTINGSINTERFACEIMPL_H +#define PROJECTSETTINGSINTERFACEIMPL_H + +#include + +class CppProjectSettings; + +class ProjectSettingsInterfaceImpl : public ProjectSettingsInterface +{ +public: + ProjectSettingsInterfaceImpl( QUnknownInterface *outer = 0 ); + + ulong addRef(); + ulong release(); + + ProjectSettings *projectSetting(); + QStringList projectSettings() const; + void connectTo( QUnknownInterface *appInterface ); + void deleteProjectSettingsObject( ProjectSettings * ); + QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ); + +private: + QUnknownInterface *parent; + int ref; + CppProjectSettings *settingsTab; +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.cpp new file mode 100644 index 0000000..a158e81 --- /dev/null +++ b/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.cpp @@ -0,0 +1,117 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "sourcetemplateinterfaceimpl.h" +#include +#include "mainfilesettings.h" +#include +#include + +SourceTemplateInterfaceImpl::SourceTemplateInterfaceImpl() +{ +} + +QRESULT SourceTemplateInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( uuid == IID_SourceTemplate ) + *iface = (SourceTemplateInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QStringList SourceTemplateInterfaceImpl::featureList() const +{ + QStringList l; + l << "C++ Main-File (main.cpp)"; + return l; +} + +static QString generateMainCppCode( const QString &formname, const QString &include ) +{ + QString code; + code += "#include \n"; + code += "#include \"" + include + "\"\n"; + code += "\n"; + code += "int main( int argc, char ** argv )\n"; + code += "{\n"; + code += " QApplication a( argc, argv );\n"; + code += " " + formname + " w;\n"; + code += " w.show();\n"; + code += " a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );\n"; + code += " return a.exec();\n"; + code += "}\n"; + return code; +} + +SourceTemplateInterface::Source SourceTemplateInterfaceImpl::create( const QString &templ, + QUnknownInterface *appIface ) +{ + SourceTemplateInterface::Source src; + src.type = SourceTemplateInterface::Source::Invalid; + if ( templ == "C++ Main-File (main.cpp)" ) { + CppMainFile dia( 0, 0, TRUE ); + dia.setup( appIface ); + if ( dia.exec() == QDialog::Accepted ) { + DesignerInterface *dIface = 0; + appIface->queryInterface( IID_Designer, (QUnknownInterface**)&dIface ); + if ( dIface ) { + src.type = SourceTemplateInterface::Source::FileName; + src.filename = dia.editFileName->text(); + QString include = dIface->currentProject()-> + formFileName( dia.listForms->text( dia.listForms->currentItem() ) ); + include.remove( include.length() - 2, 2 ); + include += "h"; + int slashFind = include.findRev('/'); + if (slashFind != -1) + include = include.mid(slashFind+1); + src.code = generateMainCppCode( dia.listForms->text( dia.listForms->currentItem() ), + include ); + } + } + } + return src; +} + +QString SourceTemplateInterfaceImpl::language( const QString & ) const +{ + return "C++"; +} diff --git a/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.h b/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.h new file mode 100644 index 0000000..52ae2d6 --- /dev/null +++ b/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.h @@ -0,0 +1,54 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SOURCETEMPLATEINTERFACEIMPL_H +#define SOURCETEMPLATEINTERFACEIMPL_H + +#include + +class SourceTemplateInterfaceImpl : public SourceTemplateInterface +{ +public: + SourceTemplateInterfaceImpl(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + QStringList featureList() const; + Source create( const QString &templ, QUnknownInterface *appIface ); + QString language( const QString &templ ) const; + + Q_REFCOUNT +}; + + +#endif diff --git a/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.cpp b/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.cpp new file mode 100644 index 0000000..1b0a617 --- /dev/null +++ b/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.cpp @@ -0,0 +1,550 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "syntaxhighliter_cpp.h" +#include "paragdata.h" +#include "qstring.h" +#include "qstringlist.h" +#include "qmap.h" +#include "qapplication.h" +#include "qregexp.h" + +const char * const SyntaxHighlighter_CPP::keywords[] = { + // C++ keywords + "and", + "and_eq", + "asm", + "auto", + "bitand", + "bitor", + "bool", + "break", + "case", + "catch", + "char", + "class", + "compl", + "const", + "const_cast", + "continue", + "default", + "delete", + "do", + "double", + "dynamic_cast", + "else", + "enum", + "explicit", + "export", + "extern", + "false", + "FALSE", + "float", + "for", + "friend", + "goto", + "if", + "inline", + "int", + "long", + "mutable", + "namespace", + "new", + "not", + "not_eq", + "operator", + "or", + "or_eq", + "private", + "protected", + "public", + "register", + "reinterpret_cast", + "return", + "short", + "signed", + "sizeof", + "static", + "static_cast", + "struct", + "switch", + "template", + "this", + "throw", + "true", + "TRUE", + "try", + "typedef", + "typeid", + "typename", + "union", + "unsigned", + "using", + "virtual", + "void", + "volatile", + "wchar_t", + "while", + "xor", + "xor_eq", + // additional "keywords" intoduced by Qt + "slots", + "signals", + "uint", + "ushort", + "ulong", + "emit", + // end of array + 0 +}; + +static QMap > *wordMap = 0; + +SyntaxHighlighter_CPP::SyntaxHighlighter_CPP() + : QTextPreProcessor(), lastFormat( 0 ), lastFormatId( -1 ) +{ + QFont f( qApp->font() ); + + addFormat( Standard, new QTextFormat( f, Qt::black ) ); + addFormat( Number, new QTextFormat( f, Qt::darkBlue ) ); + addFormat( String, new QTextFormat( f, Qt::darkGreen ) ); + addFormat( Type, new QTextFormat( f, Qt::darkMagenta ) ); + addFormat( Keyword, new QTextFormat( f, Qt::darkYellow ) ); + addFormat( PreProcessor, new QTextFormat( f, Qt::darkBlue ) ); + addFormat( Label, new QTextFormat( f, Qt::darkRed ) ); + f.setFamily( "times" ); + addFormat( Comment, new QTextFormat( f, Qt::red ) ); + + if ( wordMap ) + return; + + wordMap = new QMap >; + int len; + for ( int i = 0; keywords[ i ]; ++i ) { + len = (int)strlen( keywords[ i ] ); + if ( !wordMap->contains( len ) ) + wordMap->insert( len, QMap() ); + QMap &map = wordMap->operator[]( len ); + map[ keywords[ i ] ] = Keyword; + } +} + +SyntaxHighlighter_CPP::~SyntaxHighlighter_CPP() +{ +} + +static int string2Id( const QString &s ) +{ + if ( s == "Standard" ) + return SyntaxHighlighter_CPP::Standard; + if ( s == "Comment" ) + return SyntaxHighlighter_CPP::Comment; + if ( s == "Number" ) + return SyntaxHighlighter_CPP::Number; + if ( s == "String" ) + return SyntaxHighlighter_CPP::String; + if ( s == "Type" ) + return SyntaxHighlighter_CPP::Type; + if ( s == "Preprocessor" ) + return SyntaxHighlighter_CPP::PreProcessor; + if ( s == "Label" ) + return SyntaxHighlighter_CPP::Label; + if ( s == "Keyword" ) + return SyntaxHighlighter_CPP::Keyword; + return SyntaxHighlighter_CPP::Standard; +} + +void SyntaxHighlighter_CPP::updateStyles( const QMap &styles ) +{ + for ( QMap::ConstIterator it = styles.begin(); it != styles.end(); ++it ) { + int id = string2Id( it.key() ); + QTextFormat *f = format( id ); + if ( !f ) + continue; + f->setFont( (*it).font ); + f->setColor( (*it).color ); + } +} + +void SyntaxHighlighter_CPP::process( QTextDocument *doc, QTextParagraph *string, int, bool invalidate ) +{ + + QTextFormat *formatStandard = format( Standard ); + QTextFormat *formatComment = format( Comment ); + QTextFormat *formatNumber = format( Number ); + QTextFormat *formatString = format( String ); + QTextFormat *formatType = format( Type ); + QTextFormat *formatPreProcessor = format( PreProcessor ); + QTextFormat *formatLabel = format( Label ); + + // states + const int StateStandard = 0; + const int StateCommentStart1 = 1; + const int StateCCommentStart2 = 2; + const int StateCppCommentStart2 = 3; + const int StateCComment = 4; + const int StateCppComment = 5; + const int StateCCommentEnd1 = 6; + const int StateCCommentEnd2 = 7; + const int StateStringStart = 8; + const int StateString = 9; + const int StateStringEnd = 10; + const int StateString2Start = 11; + const int StateString2 = 12; + const int StateString2End = 13; + const int StateNumber = 14; + const int StatePreProcessor = 15; + + // tokens + const int InputAlpha = 0; + const int InputNumber = 1; + const int InputAsterix = 2; + const int InputSlash = 3; + const int InputParen = 4; + const int InputSpace = 5; + const int InputHash = 6; + const int InputQuotation = 7; + const int InputApostrophe = 8; + const int InputSep = 9; + + static uchar table[ 16 ][ 10 ] = { + { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStandard + { StateStandard, StateNumber, StateCCommentStart2, StateCppCommentStart2, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCommentStart1 + { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentStart2 + { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // CppCommentStart2 + { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCComment + { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // StateCppComment + { StateCComment, StateCComment, StateCCommentEnd1, StateCCommentEnd2, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentEnd1 + { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCCommentEnd2 + { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateStringStart + { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateString + { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStringEnd + { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2Start + { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2 + { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateString2End + { StateNumber, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateNumber + { StatePreProcessor, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard } // StatePreProcessor + }; + + QString buffer; + + int state = StateStandard; + if ( string->prev() ) { + if ( string->prev()->endState() == -1 ) + process( doc, string->prev(), 0, FALSE ); + state = string->prev()->endState(); + } + int input = -1; + int i = 0; + bool lastWasBackSlash = FALSE; + bool makeLastStandard = FALSE; + + ParagData *paragData = (ParagData*)string->extraData(); + if ( paragData ) + paragData->parenList.clear(); + else + paragData = new ParagData; + + QString alphabeth = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QString mathChars = "xXeE"; + QString numbers = "0123456789"; + bool questionMark = FALSE; + QChar lastChar; + for (;;) { + QChar c = string->at( i )->c; + + if ( lastWasBackSlash ) { + input = InputSep; + } else { + switch ( c ) { + case '*': + input = InputAsterix; + break; + case '/': + input = InputSlash; + break; + case '(': case '[': case '{': + input = InputParen; + if ( state == StateStandard || + state == StateNumber || + state == StatePreProcessor || + state == StateCCommentEnd2 || + state == StateCCommentEnd1 || + state == StateString2End || + state == StateStringEnd ) + paragData->parenList << Paren( Paren::Open, c, i ); + break; + case ')': case ']': case '}': + input = InputParen; + if ( state == StateStandard || + state == StateNumber || + state == StatePreProcessor || + state == StateCCommentEnd2 || + state == StateCCommentEnd1 || + state == StateString2End || + state == StateStringEnd ) + paragData->parenList << Paren( Paren::Closed, c, i ); + break; + case '#': + input = InputHash; + break; + case '"': + input = InputQuotation; + break; + case '\'': + input = InputApostrophe; + break; + case ' ': + input = InputSpace; + break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '0': + if ( alphabeth.find( lastChar ) != -1 && + ( mathChars.find( lastChar ) == -1 || numbers.find( string->at( i - 1 )->c ) == -1 ) ) { + input = InputAlpha; + } else { + if ( input == InputAlpha && numbers.find( lastChar ) != -1 ) + input = InputAlpha; + else + input = InputNumber; + } + break; + case ':': { + input = InputAlpha; + QChar nextChar = ' '; + if ( i < string->length() - 1 ) + nextChar = string->at( i + 1 )->c; + if ( state == StateStandard && !questionMark && lastChar != ':' && nextChar != ':' ) { + for ( int j = 0; j < i; ++j ) { + if ( string->at( j )->format() == formatStandard ) + string->setFormat( j, 1, formatLabel, FALSE ); + } + } + } break; + default: { + if ( !questionMark && c == '?' ) + questionMark = TRUE; + if ( c.isLetter() || c == '_' ) + input = InputAlpha; + else + input = InputSep; + } break; + } + } + + lastWasBackSlash = !lastWasBackSlash && c == '\\'; + + if ( input == InputAlpha ) + buffer += c; + + state = table[ state ][ input ]; + + switch ( state ) { + case StateStandard: { + int len = buffer.length(); + string->setFormat( i, 1, formatStandard, FALSE ); + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + if ( buffer.length() > 0 && input != InputAlpha ) { + if ( buffer[ 0 ] == 'Q' ) { + string->setFormat( i - buffer.length(), buffer.length(), formatType, FALSE ); + } else { + QMap >::Iterator it = wordMap->find( len ); + if ( it != wordMap->end() ) { + QMap::Iterator it2 = ( *it ).find( buffer ); + if ( it2 != ( *it ).end() ) + string->setFormat( i - buffer.length(), buffer.length(), format( ( *it2 ) ), FALSE ); + } + } + buffer = QString::null; + } + } break; + case StateCommentStart1: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = TRUE; + buffer = QString::null; + break; + case StateCCommentStart2: + string->setFormat( i - 1, 2, formatComment, FALSE ); + makeLastStandard = FALSE; + buffer = QString::null; + break; + case StateCppCommentStart2: + string->setFormat( i - 1, 2, formatComment, FALSE ); + makeLastStandard = FALSE; + buffer = QString::null; + break; + case StateCComment: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatComment, FALSE ); + buffer = QString::null; + break; + case StateCppComment: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatComment, FALSE ); + buffer = QString::null; + break; + case StateCCommentEnd1: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatComment, FALSE ); + buffer = QString::null; + break; + case StateCCommentEnd2: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatComment, FALSE ); + buffer = QString::null; + break; + case StateStringStart: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatStandard, FALSE ); + buffer = QString::null; + break; + case StateString: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatString, FALSE ); + buffer = QString::null; + break; + case StateStringEnd: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatStandard, FALSE ); + buffer = QString::null; + break; + case StateString2Start: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatStandard, FALSE ); + buffer = QString::null; + break; + case StateString2: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatString, FALSE ); + buffer = QString::null; + break; + case StateString2End: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatStandard, FALSE ); + buffer = QString::null; + break; + case StateNumber: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatNumber, FALSE ); + buffer = QString::null; + break; + case StatePreProcessor: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatPreProcessor, FALSE ); + buffer = QString::null; + break; + } + + lastChar = c; + i++; + if ( i >= string->length() ) + break; + } + + string->setExtraData( paragData ); + + int oldEndState = string->endState(); + if ( state == StateCComment || + state == StateCCommentEnd1 ) { + string->setEndState( StateCComment ); + } else if ( state == StateString ) { + string->setEndState( StateString ); + } else if ( state == StateString2 ) { + string->setEndState( StateString2 ); + } else { + string->setEndState( StateStandard ); + } + + string->setFirstPreProcess( FALSE ); + + QTextParagraph *p = string->next(); + if ( (!!oldEndState || !!string->endState()) && oldEndState != string->endState() && + invalidate && p && !p->firstPreProcess() && p->endState() != -1 ) { + while ( p ) { + if ( p->endState() == -1 ) + return; + p->setEndState( -1 ); + p = p->next(); + } + } +} + +QTextFormat *SyntaxHighlighter_CPP::format( int id ) +{ + if ( lastFormatId == id && lastFormat ) + return lastFormat; + + QTextFormat *f = formats[ id ]; + lastFormat = f ? f : formats[ 0 ]; + lastFormatId = id; + return lastFormat; +} + +void SyntaxHighlighter_CPP::addFormat( int id, QTextFormat *f ) +{ + formats.insert( id, f ); +} + +void SyntaxHighlighter_CPP::removeFormat( int id ) +{ + formats.remove( id ); +} + diff --git a/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.h b/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.h new file mode 100644 index 0000000..ea973d9 --- /dev/null +++ b/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.h @@ -0,0 +1,73 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QCPPSYNTAXHIGHLIGHTER_H +#define QCPPSYNTAXHIGHLIGHTER_H + +#include +#include + +class SyntaxHighlighter_CPP : public QTextPreProcessor +{ +public: + enum CppIds { + Comment = 1, + Number, + String, + Type, + Keyword, + PreProcessor, + Label + }; + + SyntaxHighlighter_CPP(); + virtual ~SyntaxHighlighter_CPP(); + void process( QTextDocument *doc, QTextParagraph *string, int start, bool invalidate = TRUE ); + void updateStyles( const QMap &styles ); + + static const char * const keywords[]; + + QTextFormat *format( int id ); + +private: + void addFormat( int id, QTextFormat *f ); + void removeFormat( int id ); + + QTextFormat *lastFormat; + int lastFormatId; + QIntDict formats; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/yyreg.cpp b/tools/designer/plugins/cppeditor/yyreg.cpp new file mode 100644 index 0000000..144c99f --- /dev/null +++ b/tools/designer/plugins/cppeditor/yyreg.cpp @@ -0,0 +1,800 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +#include +#include + +#include "yyreg.h" + +/* + First comes the tokenizer. We don't need something that knows much + about C++. However, we need something that gives tokens from the + end of the file to the start, which is tricky. + + If you are not familiar with hand-written tokenizers and parsers, + you might want to read other simpler parsers written in the same + style: + + $(QTDIR)/src/tools/qregexp.cpp + $(QTDIR)/tools/inspector/cppparser.cpp + + You might also want to read Section 2 in the Dragon Book. +*/ + +/* + Those are the tokens we are interested in. Tok_Something represents + any C++ token that does not interest us, but it's dangerous to + ignore tokens completely. +*/ +enum { Tok_Boi, Tok_Ampersand, Tok_Aster, Tok_LeftParen, Tok_RightParen, + Tok_Equal, Tok_LeftBrace, Tok_RightBrace, Tok_Semicolon, Tok_Colon, + Tok_LeftAngle, Tok_RightAngle, Tok_Comma, Tok_Ellipsis, Tok_Gulbrandsen, + Tok_LeftBracket, Tok_RightBracket, Tok_Tilde, Tok_Something, Tok_Comment, + Tok_Ident, + + Tok_char, Tok_const, Tok_double, Tok_int, Tok_long, Tok_operator, + Tok_short, Tok_signed, Tok_unsigned }; + +/* + The following variables store the lexical analyzer state. The best way + to understand them is to implement a function myGetToken() that calls + getToken(), to add some qDebug() statements in there and then to + #define getToken() myGetToken(). +*/ +static QString *yyIn; // the input stream +static int yyPos; // the position of the current token in yyIn +static int yyCurPos; // the position of the next lookahead character +static char *yyLexBuf; // the lexeme buffer +static const int YYLexBufSize = 65536; // big enough for long comments +static char *yyLex; // the lexeme itself (a pointer into yyLexBuf) +static int yyCh; // the lookbehind character + +/* + Moves back to the previous character in the input stream and + updates the tokenizer state. This function is to be used only by + getToken(), which provides the right abstraction. +*/ +static inline void readChar() +{ + if ( yyCh == EOF ) + return; + + if ( yyLex > yyLexBuf ) + *--yyLex = (char) yyCh; + + if ( yyCurPos < 0 ) + yyCh = EOF; + else + yyCh = (*yyIn)[yyCurPos].unicode(); + yyCurPos--; +} + +/* + Sets up the tokenizer. +*/ +static void startTokenizer( const QString& in ) +{ + yyIn = new QString; + *yyIn = in; + yyPos = yyIn->length() - 1; + yyCurPos = yyPos; + yyLexBuf = new char[YYLexBufSize]; + yyLex = yyLexBuf + YYLexBufSize - 1; + *yyLex = '\0'; + yyCh = '\0'; + readChar(); +} + +/* + Frees resources allocated by the tokenizer. +*/ +static void stopTokenizer() +{ + delete yyIn; + delete[] yyLexBuf; + yyLexBuf = 0; +} + +/* + These two macros implement quick-and-dirty hashing for telling + apart keywords fast. +*/ +#define HASH( ch, len ) ( (ch) | ((len) << 8) ) +#define CHECK( target ) \ + if ( strcmp((target), yyLex) != 0 ) \ + break; + +/* + Returns the previous token in the abstract token stream. The parser + deals only with tokens, not with characters. +*/ +static int getToken() +{ + // why "+ 2"? try putting some qDebug()'s and see + yyPos = yyCurPos + 2; + + for ( ;; ) { + /* + See if the previous token is interesting. If it isn't, we + will loop anyway an go to the token before the previous + token, and so on. + */ + + yyLex = yyLexBuf + YYLexBufSize - 1; + *yyLex = '\0'; + + if ( yyCh == EOF ) { + break; + } else if ( isspace(yyCh) ) { + bool metNL = FALSE; + do { + metNL = ( metNL || yyCh == '\n' ); + readChar(); + } while ( isspace(yyCh) ); + + if ( metNL ) { + /* + C++ style comments are tricky. In left-to-right + thinking, C++ comments start with "//" and end with + '\n'. In right-to-left thinking, they start with a + '\n'; but of course not every '\n' starts a comment. + + When we meet the '\n', we look behind, on the same + line, for a "//", and if there is one we mess + around with the tokenizer state to effectively + ignore the comment. Beware of off-by-one and + off-by-two bugs when you modify this code by adding + qDebug()'s here and there. + */ + if ( yyCurPos >= 0 ) { + int lineStart = yyIn->findRev( QChar('\n'), yyCurPos ) + 1; + QString line = yyIn->mid( lineStart, + yyCurPos - lineStart + 2 ); + int commentStart = line.find( QString("//") ); + if ( commentStart != -1 ) { + yyCurPos = lineStart + commentStart - 1; + yyPos = yyCurPos + 2; + readChar(); + } + } + } + } else if ( isalnum(yyCh) || yyCh == '_' ) { + do { + readChar(); + } while ( isalnum(yyCh) || yyCh == '_' ); + + switch ( HASH(yyLex[0], strlen(yyLex)) ) { + case HASH( 'c', 4 ): + CHECK( "char" ); + return Tok_char; + case HASH( 'c', 5 ): + CHECK( "const" ); + return Tok_const; + case HASH( 'd', 6 ): + CHECK( "double" ); + return Tok_double; + case HASH( 'i', 3 ): + CHECK( "int" ); + return Tok_int; + case HASH( 'l', 4 ): + CHECK( "long" ); + return Tok_long; + case HASH( 'o', 8 ): + CHECK( "operator" ); + return Tok_operator; + case HASH( 's', 5 ): + CHECK( "short" ); + return Tok_short; + case HASH( 's', 6 ): + CHECK( "signed" ); + return Tok_signed; + case HASH( 'u', 8 ): + CHECK( "unsigned" ); + return Tok_unsigned; + } + if ( isdigit(*yyLex) ) + return Tok_Something; + else + return Tok_Ident; + } else { + int quote; + + switch ( yyCh ) { + case '!': + case '%': + case '^': + case '+': + case '-': + case '?': + case '|': + readChar(); + return Tok_Something; + case '"': + case '\'': + quote = yyCh; + readChar(); + + while ( yyCh != EOF && yyCh != '\n' ) { + if ( yyCh == quote ) { + readChar(); + if ( yyCh != '\\' ) + break; + } else { + readChar(); + } + } + return Tok_Something; + case '&': + readChar(); + if ( yyCh == '&' ) { + readChar(); + return Tok_Something; + } else { + return Tok_Ampersand; + } + case '(': + readChar(); + return Tok_LeftParen; + case ')': + readChar(); + return Tok_RightParen; + case '*': + readChar(); + return Tok_Aster; + case ',': + readChar(); + return Tok_Comma; + case '.': + readChar(); + if ( yyCh == '.' ) { + do { + readChar(); + } while ( yyCh == '.' ); + return Tok_Ellipsis; + } else { + return Tok_Something; + } + case '/': + /* + C-style comments are symmetric. C++-style comments + are handled elsewhere. + */ + readChar(); + if ( yyCh == '*' ) { + bool metAster = FALSE; + bool metAsterSlash = FALSE; + + readChar(); + + while ( !metAsterSlash ) { + if ( yyCh == EOF ) + break; + + if ( yyCh == '*' ) + metAster = TRUE; + else if ( metAster && yyCh == '/' ) + metAsterSlash = TRUE; + else + metAster = FALSE; + readChar(); + } + break; + // return Tok_Comment; + } else { + return Tok_Something; + } + case ':': + readChar(); + if ( yyCh == ':' ) { + readChar(); + return Tok_Gulbrandsen; + } else { + return Tok_Colon; + } + case ';': + readChar(); + return Tok_Semicolon; + case '<': + readChar(); + return Tok_LeftAngle; + case '=': + readChar(); + return Tok_Equal; + case '>': + readChar(); + return Tok_RightAngle; + case '[': + readChar(); + return Tok_LeftBracket; + case ']': + readChar(); + return Tok_RightBracket; + case '{': + readChar(); + return Tok_LeftBrace; + case '}': + readChar(); + return Tok_RightBrace; + case '~': + readChar(); + return Tok_Tilde; + default: + readChar(); + } + } + } + return Tok_Boi; +} + +/* + Follow the member function(s) of CppFunction. +*/ + +/* + Returns the prototype for the C++ function, without the semicolon. +*/ +QString CppFunction::prototype() const +{ + QString proto; + + if ( !returnType().isEmpty() ) + proto = returnType() + QChar( ' ' ); + proto += scopedName(); + proto += QChar( '(' ); + if ( !parameterList().isEmpty() ) { + QStringList::ConstIterator p = parameterList().begin(); + proto += *p; + ++p; + while ( p != parameterList().end() ) { + proto += QString( ", " ); + proto += *p; + ++p; + } + } + proto += QChar( ')' ); + if ( isConst() ) + proto += QString( " const" ); + return proto; +} + +/* + The parser follows. We are not really parsing C++, just trying to + find the start and end of function definitions. + + One important pitfall is that the parsed code needs not be valid. + Parsing from right to left helps cope with that, as explained in + comments below. + + In the examples, we will use the symbol @ to stand for the position + in the token stream. In "int @ x ;", the lookahead token (yyTok) is + 'int'. +*/ + +static int yyTok; // the current token + +/* + Returns TRUE if thingy is a constructor or a destructor; otherwise + returns FALSE. +*/ +static bool isCtorOrDtor( const QString& thingy ) +{ + // e.g., Alpha::Beta >::~Beta + QRegExp xtor( QString( + "(?:([A-Z_a-z][0-9A-Z_a-z]*)" // class name + "(?:<(?:[^>]|<[^>]*>)*>)*" // template arguments + "::)+" // many in a row + "~?" // ctor or dtor? + "\\1") ); // function has same name as class + return xtor.exactMatch( thingy ); +} + +/* + Skips over any template arguments with balanced angle brackets, and + returns the skipped material as a string. + + Before: QMap < QString , QValueList < QString > > @ m ; + After: QMap @ < QString , QValueList < QString > > m ; +*/ +static QString matchTemplateAngles() +{ + QString t; + + if ( yyTok == Tok_RightAngle ) { + int depth = 0; + do { + if ( yyTok == Tok_RightAngle ) + depth++; + else if ( yyTok == Tok_LeftAngle ) + depth--; + t.prepend( yyLex ); + yyTok = getToken(); + } while ( depth > 0 && yyTok != Tok_Boi && yyTok != Tok_LeftBrace ); + } + return t; +} + +/* + Similar to matchTemplateAngles(), but for array brackets in parameter + data types (as in "int *argv[]"). +*/ +static QString matchArrayBrackets() +{ + QString t; + + while ( yyTok == Tok_RightBracket ) { + t.prepend( yyLex ); + yyTok = getToken(); + if ( yyTok == Tok_Something ) { + t.prepend( yyLex ); + yyTok = getToken(); + } + if ( yyTok != Tok_LeftBracket ) + return QString::null; + t.prepend( yyLex ); + yyTok = getToken(); + } + return t; +} + +/* + Prepends prefix to *type. This operation is in theory trivial, but + for the spacing to look good, we have to do something. The original + spacing is lost as the input is tokenized. +*/ +static void prependToType( QString *type, const QString& prefix ) +{ + if ( !type->isEmpty() && !prefix.isEmpty() ) { + QChar left = prefix[(int) prefix.length() - 1]; + QChar right = (*type)[0]; + + if ( left.isLetter() && + (right.isLetter() || right == QChar('*') || right == QChar('&')) ) + type->prepend( QChar(' ') ); + } + type->prepend( prefix ); +} + +static bool isModifier( int tok ) +{ + return ( tok == Tok_signed || tok == Tok_unsigned || + tok == Tok_short || tok == Tok_long ); +} + +/* + Parses a data type (backwards as usual) and returns a textual + representation of it. +*/ +static QString matchDataType() +{ + QString type; + + while ( yyTok == Tok_Ampersand || yyTok == Tok_Aster || + yyTok == Tok_const ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } + + /* + This code is really hard to follow... sorry. The loop matches + Alpha::Beta::Gamma::...::Omega. + */ + for ( ;; ) { + bool modifierMet = FALSE; + + prependToType( &type, matchTemplateAngles() ); + + if ( yyTok != Tok_Ident ) { + /* + People may write 'const unsigned short' or + 'short unsigned const' or any other permutation. + */ + while ( yyTok == Tok_const || isModifier(yyTok) ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + if ( yyTok != Tok_const ) + modifierMet = TRUE; + } + + if ( yyTok == Tok_Tilde ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } + } + + if ( !modifierMet ) { + if ( yyTok == Tok_Ellipsis || yyTok == Tok_Ident || + yyTok == Tok_char || yyTok == Tok_int || + yyTok == Tok_double ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } else { + return QString::null; + } + } else if ( yyTok == Tok_int || yyTok == Tok_char || + yyTok == Tok_double ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } + + while ( yyTok == Tok_const || isModifier(yyTok) ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } + + if ( yyTok == Tok_Gulbrandsen ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } else { + break; + } + } + return type; +} + +/* + Parses a function prototype (without the semicolon) and returns an + object that stores information about this function. +*/ +static CppFunction matchFunctionPrototype( bool stripParamNames ) +{ + CppFunction func; +#if 0 + QString documentation; +#endif + QString returnType; + QString scopedName; + QStringList params; + QString qualifier; + bool cnst = FALSE; + + if ( yyTok == Tok_const ) { + cnst = TRUE; + yyTok = getToken(); + } + + if ( yyTok != Tok_RightParen ) + return func; + yyTok = getToken(); + + if ( yyTok != Tok_LeftParen ) { + for ( ;; ) { + QString brackets = matchArrayBrackets(); + QString name; + if ( yyTok == Tok_Ident ) { + name = yyLex; + yyTok = getToken(); + } + QString type = matchDataType(); + + if ( type.isEmpty() ) { + if ( name.isEmpty() ) + return func; + type = name; + name = QString::null; + } + if ( stripParamNames ) + name = QString::null; + + QString param = type + QChar( ' ' ) + name + brackets; + params.prepend( param.stripWhiteSpace() ); + + if ( yyTok != Tok_Comma ) + break; + yyTok = getToken(); + } + if ( yyTok != Tok_LeftParen ) + return func; + } + yyTok = getToken(); + + for ( ;; ) { + scopedName.prepend( matchTemplateAngles() ); + + if ( yyTok != Tok_Ident ) { + // the operator keyword should be close + int i = 0; + while ( i < 4 && yyTok != Tok_operator ) { + scopedName.prepend( yyLex ); + i++; + } + if ( yyTok != Tok_operator ) + return func; + } + scopedName.prepend( yyLex ); + yyTok = getToken(); + + if ( yyTok != Tok_Gulbrandsen ) + break; + scopedName.prepend( yyLex ); + yyTok = getToken(); + } + + if ( !isCtorOrDtor(scopedName) ) { + returnType = matchDataType(); + if ( returnType.isEmpty() ) + return func; + } + + /* + The documentation feature is unused so far, since we cannot + really distinguist between a normal comment between two + functions and one that relates to the following function. One + good heuristic is to assume that a comment immediately followed + by a function with no blank line in between relates to the + function, but there's no easy way to find that out with a + tokenizer. + */ +#if 0 + if ( yyTok == Tok_Comment ) { + documentation = yyLex; + yyTok = getToken(); + } + + func.setDocumentation( documentation ); +#endif + func.setReturnType( returnType ); + func.setScopedName( scopedName ); + func.setParameterList( params ); + func.setConst( cnst ); + return func; +} + +/* + Try to set the body. It's not sufficient to call + func->setBody(somewhatBody), as the somewhatBody might be too large. + Case in point: + + void foo() + { + printf( "Hello" ); + } + + int n; + + void bar() + { + printf( " world!\n" ); + } + + The parser first finds bar(). Then it finds "void foo() {" and + naively expects the body to extend up to "void bar()". This + function's job is to count braces and make sure "int n;" is not + counted as part of the body. + + Cases where the closing brace of the body is missing require no + special processing. +*/ +static void setBody( CppFunction *func, const QString& somewhatBody ) +{ + QString body = somewhatBody; + + int braceDepth = 0; + int i = 0; + while ( i < (int) body.length() ) { + if ( body[i] == QChar('{') ) { + braceDepth++; + } else if ( body[i] == QChar('}') ) { + braceDepth--; + if ( braceDepth == 0 ) { + body.truncate( i + 1 ); + break; + } + } + i++; + } + + func->setBody( body ); +} + +/* + Parses a whole C++ file, looking for function definitions. Case in + point: + + void foo() + { + printf( "Hello" ); + + void bar() + { + printf( " world!\n" ); + } + + The parser looks for left braces and tries to parse a function + prototype backwards. First it finds "void bar() {". Then it works + up and finds "void foo() {". +*/ +static void matchTranslationUnit( QValueList *flist ) +{ + int endBody = -1; + int startBody; + + for ( ;; ) { + if ( endBody == -1 ) + endBody = yyPos; + + while ( yyTok != Tok_Boi && yyTok != Tok_LeftBrace ) + yyTok = getToken(); + if ( yyTok == Tok_Boi ) + break; + + // found a left brace + yyTok = getToken(); + startBody = yyPos; + CppFunction func = matchFunctionPrototype( FALSE ); + if ( !func.scopedName().isEmpty() ) { + QString body = yyIn->mid( startBody, endBody - startBody ); + setBody( &func, body ); + body = func.body(); // setBody() can change the body + + /* + Compute important line numbers. + */ + int functionStartLineNo = 1 + QConstString( yyIn->unicode(), yyPos ) + .string().contains( QChar('\n') ); + int startLineNo = functionStartLineNo + + QConstString( yyIn->unicode() + yyPos, startBody - yyPos ) + .string().contains( QChar('\n') ); + int endLineNo = startLineNo + body.contains( QChar('\n') ); + + func.setLineNums( functionStartLineNo, startLineNo, endLineNo ); + flist->prepend( func ); + endBody = -1; + } + } +} + +/* + Extracts C++ function from source code and put them in a list. +*/ +void extractCppFunctions( const QString& code, QValueList *flist ) +{ + startTokenizer( code ); + yyTok = getToken(); + matchTranslationUnit( flist ); + stopTokenizer(); +} + +/* + Returns the prototype with the parameter names removed. +*/ +QString canonicalCppProto( const QString& proto ) +{ + startTokenizer( proto ); + yyTok = getToken(); + CppFunction func = matchFunctionPrototype( TRUE ); + stopTokenizer(); + return func.prototype(); +} diff --git a/tools/designer/plugins/cppeditor/yyreg.h b/tools/designer/plugins/cppeditor/yyreg.h new file mode 100644 index 0000000..f75c948 --- /dev/null +++ b/tools/designer/plugins/cppeditor/yyreg.h @@ -0,0 +1,88 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef YYREG_H +#define YYREG_H + +#include +#include + +class CppFunction +{ +public: + CppFunction() : cnst( FALSE ), lineno1( 0 ), lineno2( 0 ) { } + + void setReturnType( const QString& r ) { ret = r; } + void setScopedName( const QString& n ) { nam = n; } + void setParameterList( const QStringList& p ) { params = p; } + void setConst( bool c ) { cnst = c; } + void setBody( const QString& b ) { bod = b; } + void setDocumentation( const QString& d ) { doc = d; } + void setLineNums( int functionStart, int openingBrace, int closingBrace ) { + lineno0 = functionStart; + lineno1 = openingBrace; + lineno2 = closingBrace; + } + + const QString& returnType() const { return ret; } + const QString& scopedName() const { return nam; } + const QStringList& parameterList() const { return params; } + bool isConst() const { return cnst; } + QString prototype() const; + const QString& body() const { return bod; } + const QString& documentation() const { return doc; } + int functionStartLineNum() const { return lineno0; } + int openingBraceLineNum() const { return lineno1; } + int closingBraceLineNum() const { return lineno2; } + +#if defined(Q_FULL_TEMPLATE_INSTANTIATION) + bool operator==( const CppFunction& ) const { return FALSE; } +#endif + +private: + QString ret; + QString nam; + QStringList params; + bool cnst; + QString bod; + QString doc; + int lineno0; + int lineno1; + int lineno2; +}; + +void extractCppFunctions( const QString& code, QValueList *flist ); +QString canonicalCppProto( const QString& proto ); + +#endif diff --git a/tools/designer/plugins/dlg/dlg.pro b/tools/designer/plugins/dlg/dlg.pro new file mode 100644 index 0000000..ee93cb9 --- /dev/null +++ b/tools/designer/plugins/dlg/dlg.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += qt warn_on release plugin +HEADERS = dlg2ui.h +SOURCES = main.cpp dlg2ui.cpp +DESTDIR = ../../../../plugins/designer +DEFINES += QT_INTERNAL_XML +include( ../../../../src/qt_professional.pri ) +TARGET = dlgplugin +INCLUDEPATH += ../../interfaces + + +target.path += $$plugins.path/designer +INSTALLS += target diff --git a/tools/designer/plugins/dlg/dlg2ui.cpp b/tools/designer/plugins/dlg/dlg2ui.cpp new file mode 100644 index 0000000..c309eb2 --- /dev/null +++ b/tools/designer/plugins/dlg/dlg2ui.cpp @@ -0,0 +1,1632 @@ +/********************************************************************** +** +** Converts a Qt Architect 2.1+ .dlg file into a .ui file. +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "dlg2ui.h" +#include +#include +#include +#include +#include + +/* + Possible improvements: + + 1. Convert layout stretch factors to size policy stretches, now + that Qt Designer supports the latter. +*/ + +/* + These big tables could be more or less eliminated by using Qt's + QMetaObject and QMetaProperty classes. However, the interface of + these classes is unwieldy for an otherwise non-GUI program like this + one, as we would have to create one dummy object for most QObject + subclasses in Qt. Let's take the safe road. +*/ + +static const char *widgetTypes[] = { + "Button", "ButtonGroup", "CheckBox", "ComboBox", "Dial", "DlgWidget", + "Frame", "Grid", "GroupBox", "HBox", "HButtonGroup", "HGroupBox", + "IconView", "LCDNumber", "Label", "LineEdit", "ListBox", "ListView", + "MenuBar", "MultiLineEdit", "ProgressBar", "PushButton", "RadioButton", + "ScrollBar", "ScrollView", "Slider", "SpinBox", "Splitter", "TabBar", + "TextBrowser", "TextView", "User", "VBox", "VButtonGroup", "VGroupBox", 0 +}; + +/* + This table maps Qt Architect properties to Qt Designer properties. + If there is no corresponding Qt Designer property, qtName is 0 and + the property can be handled explicitly. +*/ +static const struct { + const char *widgetName; + const char *architectName; + const char *qtName; + const char *type; +} propertyDefs[] = { + { "Button", "AutoRepeat", "autoRepeat", "boolean" }, + { "Button", "AutoResize", 0, 0 }, + { "Button", "Text", "text", "qstring" }, + { "ButtonGroup", "Exclusive", "exclusive", "boolean" }, + { "ButtonGroup", "RadioButtonExclusive", "radioButtonExclusive", + "boolean" }, + { "CheckBox", "Checked", "checked", "boolean" }, + { "ComboBox", "AutoCompletion", "autoCompletion", "boolean" }, + { "ComboBox", "AutoResize", 0, 0 }, + { "ComboBox", "DuplicatesEnabled", "duplicatesEnabled", "boolean" }, + { "ComboBox", "MaxCount", "maxCount", "integer" }, + { "ComboBox", "Policy", "insertionPolicy", "enum" }, + { "ComboBox", "SizeLimit", "sizeLimit", "integer" }, + { "ComboBox", "Style", 0, 0 }, + { "Dial", "Initial", "value", "integer" }, + { "Dial", "LineStep", "lineStep", "integer" }, + { "Dial", "MaxValue", "maxValue", "integer" }, + { "Dial", "MinValue", "minValue", "integer" }, + { "Dial", "NotchTarget", "notchTarget", "double" }, + { "Dial", "PageStep", "pageStep", "integer" }, + { "Dial", "ShowNotches", "notchesVisible", "boolean" }, + { "Dial", "Tracking", "tracking", "boolean" }, + { "Dial", "Wrapping", "wrapping", "boolean" }, + { "DlgWidget", "AdjustSize", 0, 0 }, + { "DlgWidget", "BackgroundMode", "backgroundMode", "enum" }, + { "DlgWidget", "BackgroundOrigin", "backgroundOrigin", "enum" }, + { "DlgWidget", "BackgroundPixmap", "backgroundPixmap", "qpixmap" }, + { "DlgWidget", "DataLenName", 0, 0 }, + { "DlgWidget", "DataVarName", 0, 0 }, + { "DlgWidget", "Enabled", "enabled", "boolean" }, + { "DlgWidget", "FocusPolicy", "focusPolicy", "enum" }, + { "DlgWidget", "Font", "font", "qfont" }, + { "DlgWidget", "FontPropagation", 0, 0 }, + { "DlgWidget", "MaximumSize", "maximumSize", "qsize" }, + { "DlgWidget", "MinimumSize", "minimumSize", "qsize" }, + { "DlgWidget", "Name", 0, 0 }, + { "DlgWidget", "Palette", "palette", "qpalette" }, + { "DlgWidget", "PalettePropagation", 0, 0 }, + { "DlgWidget", "ReadPixmapFromData", 0, 0 }, + { "DlgWidget", "Rect", 0, 0 }, + { "DlgWidget", "SignalConnection", 0, 0 }, + { "DlgWidget", "UseBackgroudPixmap", 0, 0 }, + { "DlgWidget", "Variable", 0, 0 }, + { "Frame", "FrameMargin", "margin", "integer" }, + { "Frame", "LineWidth", "lineWidth", "integer" }, + { "Frame", "MidLineWidth", "midLineWidth", "integer" }, + { "Frame", "Style", 0, 0 }, + { "GroupBox", "Title", "title", "qstring" }, + { "IconView", "AlignMode", 0, 0 }, + { "IconView", "Aligning", 0, 0 }, + { "IconView", "Arrangement", "arrangement", "enum" }, + { "IconView", "AutoArrange", "autoArrange", "boolean" }, + { "IconView", "EnableMoveItems", "itemsMovable", "boolean" }, + { "IconView", "GridX", "gridX", "integer" }, + { "IconView", "GridY", "gridY", "integer" }, + { "IconView", "ItemTextPos", "itemTextPos", "enum" }, + { "IconView", "ItemsMovable", "itemsMovable", "boolean" }, + { "IconView", "MaxItemTextLength", "maxItemTextLength", "integer" }, + { "IconView", "MaxItemWidth", "maxItemWidth", "integer" }, + { "IconView", "ResizeMode", "resizeMode", "enum" }, + { "IconView", "SelectionMode", "selectionMode", "enum" }, + { "IconView", "ShowToolTips", "showToolTips", "boolean" }, + { "IconView", "SortAscending", "sortDirection", "bool" }, + { "IconView", "Spacing", "spacing", "integer" }, + { "IconView", "WordWrapIconText", "wordWrapIconText", "boolean" }, + { "LCDNumber", "Digits", "numDigits", "integer" }, + { "LCDNumber", "Mode", "mode", "enum" }, + { "LCDNumber", "SegmentStyle", "segmentStyle", "enum" }, + { "LCDNumber", "SmallDecimalPoint", "smallDecimalPoint", "boolean" }, + { "LCDNumber", "Value", 0, 0 }, + { "Label", "AutoResize", 0, 0 }, + { "Label", "Indent", "indent", "integer" }, + { "Label", "Text", "text", "qstring" }, + { "Label", "TextFormat", "textFormat", "enum" }, + { "LineEdit", "EchoMode", "echoMode", "enum" }, + { "LineEdit", "FrameShown", "frame", "boolean" }, + { "LineEdit", "MaxLength", "maxLength", "integer" }, + { "LineEdit", "Text", "text", "qstring" }, + { "ListBox", "AutoScroll", 0, 0 }, + { "ListBox", "AutoUpdate", 0, 0 }, + { "ListBox", "ColumnMode", "columnMode", "enum" }, + { "ListBox", "DragSelect", 0, 0 }, + { "ListBox", "RowMode", "rowMode", "enum" }, + { "ListBox", "SelectionMode", "selectionMode", "enum" }, + { "ListBox", "SmoothScrolling", 0, 0 }, + { "ListView", "AllColumnsShowFocus", "allColumnsShowFocus", "boolean" }, + { "ListView", "HeaderInformation", 0, 0 }, + { "ListView", "ItemMargin", "itemMargin", "integer" }, + { "ListView", "MultiSelection", "multiSelection", "boolean" }, + { "ListView", "RootIsDecorated", "rootIsDecorated", "boolean" }, + { "ListView", "TreeStepSize", "treeStepSize", "boolean" }, + { "MultiLineEdit", "AutoUpdate", 0, 0 }, + { "MultiLineEdit", "EchoMode", 0, 0 }, + { "MultiLineEdit", "HorizontalMargin", 0, 0 }, + { "MultiLineEdit", "MaxLength", 0, 0 }, + { "MultiLineEdit", "MaxLineLength", 0, 0 }, + { "MultiLineEdit", "MaxLines", 0, 0 }, + { "MultiLineEdit", "OverwriteMode", 0, 0 }, + { "MultiLineEdit", "ReadOnly", 0, 0 }, + { "MultiLineEdit", "Text", 0, 0 }, + { "MultiLineEdit", "UndoDepth", "undoDepth", "integer" }, + { "MultiLineEdit", "UndoEnabled", 0, 0 }, + { "MultiLineEdit", "WordWrap", 0, 0 }, + { "MultiLineEdit", "WrapColumnOrWidth", 0, 0 }, + { "MultiLineEdit", "WrapPolicy", 0, 0 }, + { "ProgressBar", "CenterIndicator", "centerIndicator", "boolean" }, + { "ProgressBar", "IndicatorFollowsStyle", "indicatorFollowsStyle", + "boolean" }, + { "ProgressBar", "Progress", "progress", "integer" }, + { "ProgressBar", "TotalSteps", "totalSteps", "integer" }, + { "PushButton", "AutoDefault", "autoDefault", "boolean" }, + { "PushButton", "Default", "default", "boolean" }, + { "PushButton", "IsMenuButton", 0, 0 }, + { "PushButton", "ToggleButton", "toggleButton", "boolean" }, + { "RadioButton", "Checked", "checked", "boolean" }, + { "ScrollBar", "Initial", "value", "integer" }, + { "ScrollBar", "LineStep", "lineStep", "integer" }, + { "ScrollBar", "MaxValue", "maxValue", "integer" }, + { "ScrollBar", "MinValue", "minValue", "integer" }, + { "ScrollBar", "Orientation", "orientation", "enum" }, + { "ScrollBar", "PageStep", "pageStep", "integer" }, + { "ScrollBar", "Tracking", "tracking", "boolean" }, + { "ScrollView", "DragAutoScroll", "dragAutoScroll", "boolean" }, + { "ScrollView", "HScrollBarMode", "hScrollBarMode", "enum" }, + { "ScrollView", "ResizePolicy", "resizePolicy", "enum" }, + { "ScrollView", "VScrollBarMode", "vScrollBarMode", "enum" }, + { "Slider", "Initial", "value", "integer" }, + { "Slider", "LineStep", "lineStep", "integer" }, + { "Slider", "MaxValue", "maxValue", "integer" }, + { "Slider", "MinValue", "minValue", "integer" }, + { "Slider", "Orientation", "orientation", "enum" }, + { "Slider", "PageStep", "pageStep", "integer" }, + { "Slider", "TickInterval", "tickInterval", "integer" }, + { "Slider", "Tickmarks", "tickmarks", "enum" }, + { "Slider", "Tracking", "tracking", "boolean" }, + { "SpinBox", "ButtonSymbols", "buttonSymbols", "enum" }, + { "SpinBox", "MaxValue", "maxValue", "integer" }, + { "SpinBox", "MinValue", "minValue", "integer" }, + { "SpinBox", "Prefix", "prefix", "qstring" }, + { "SpinBox", "SpecialValue", "specialValueText", "qstring" }, + { "SpinBox", "Step", "lineStep", "integer" }, + { "SpinBox", "Suffix", "suffix", "qstring" }, + { "SpinBox", "Wrapping", "wrapping", "boolean" }, + { "Splitter", "OpaqueResize", 0, 0 }, + { "Splitter", "Orientation", "orientation", "enum" }, + { "TabBar", "Shape", "shape", "enum" }, + { "TabBar", "TabNames", 0, 0 }, + { "TextView", "Context", 0, 0 }, + { "TextView", "LinkUnderline", "linkUnderline", "boolean" }, + { "TextView", "Text", "text", "qstring" }, + { "TextView", "TextFormat", "textFormat", "enum" }, + { "User", "UserClassHeader", 0, 0 }, + { "User", "UserClassName", 0, 0 }, + { 0, 0, 0, 0 } +}; + +/* + This is the number of supported color groups in a palette, and + supported color roles in a color group. Changing these constants is + dangerous. +*/ +static const int NumColorRoles = 14; + +static bool isTrue( const QString& val ) +{ + return val.lower() == QString( "true" ); +} + +static AttributeMap attribute( const QString& name, const QString& val ) +{ + AttributeMap attr; + attr.insert( name, val ); + return attr; +} + +static QString entitize( const QString& str ) +{ + QString t = str; + t.replace( '&', QString("&") ); + t.replace( '>', QString(">") ); + t.replace( '<', QString("<") ); + t.replace( '"', QString(""") ); + t.replace( '\'', QString("'") ); + return t; +} + +QString Dlg2Ui::alias( const QString& name ) const +{ + if ( yyAliasMap.contains(name) ) + return yyAliasMap[name]; + else + return name; +} + +QString Dlg2Ui::opening( const QString& tag, const AttributeMap& attr ) +{ + QString t = QChar( '<' ) + tag; + AttributeMap::ConstIterator a = attr.begin(); + while ( a != attr.end() ) { + t += QChar( ' ' ) + a.key() + QString( "=\"" ) + entitize( *a ) + + QChar( '"' ); + ++a; + } + t += QChar( '>' ); + return t; +} + +QString Dlg2Ui::closing( const QString& tag ) +{ + return opening( QChar('/') + tag ); +} + +void Dlg2Ui::error( const QString& message ) +{ + if ( numErrors++ == 0 ) + QMessageBox::warning( 0, yyFileName, message ); +} + +void Dlg2Ui::syntaxError() +{ + error( QString("Sorry, I met a random syntax error. I did what I could, but" + " that was not enough." + "

    You might want to write to" + " qt-bugs@trolltech.com about this incident.") ); +} + +QString Dlg2Ui::getTextValue( const QDomNode& node ) +{ + if ( node.childNodes().count() > 1 ) { + syntaxError(); + return QString::null; + } + + if ( node.childNodes().count() == 0 ) + return QString::null; + + QDomText child = node.firstChild().toText(); + if ( child.isNull() ) { + syntaxError(); + return QString::null; + } + QString t = child.data().stripWhiteSpace(); + t.replace( "\\\\", "\\" ); + t.replace( "\\n", "\n" ); + return t; +} + +QVariant Dlg2Ui::getValue( const QDomNodeList& children, const QString& tagName, + const QString& type ) +{ + for ( int i = 0; i < (int) children.count(); i++ ) { + QDomNode n = children.item( i ); + if ( n.toElement().tagName() == tagName ) + return getValue( n.toElement(), tagName, type ); + } + return QVariant(); +} + +void Dlg2Ui::emitHeader() +{ + yyOut += QString( "\n" ); +} + +void Dlg2Ui::emitFooter() +{ + yyOut += QString( "\n" ); +} + +void Dlg2Ui::emitSimpleValue( const QString& tag, const QString& value, + const AttributeMap& attr ) +{ + yyOut += yyIndentStr + opening( tag, attr ) + entitize( value ) + + closing( tag ) + QChar( '\n' ); +} + +void Dlg2Ui::emitOpening( const QString& tag, const AttributeMap& attr ) +{ + yyOut += yyIndentStr + opening( tag, attr ) + QChar( '\n' ); + yyIndentStr += QString( " " ); +} + +void Dlg2Ui::emitClosing( const QString& tag ) +{ + yyIndentStr.truncate( yyIndentStr.length() - 4 ); + yyOut += yyIndentStr + closing( tag ) + QChar( '\n' ); +} + +void Dlg2Ui::emitOpeningWidget( const QString& className ) +{ + AttributeMap attr = attribute( QString("class"), className ); + if ( yyGridColumn >= 0 ) { + attr.insert( QString("row"), QString::number(yyGridRow) ); + attr.insert( QString("column"), QString::number(yyGridColumn) ); + yyGridColumn = -1; + } + emitOpening( QString("widget"), attr ); +} + +QString Dlg2Ui::widgetClassName( const QDomElement& e ) +{ + if ( e.tagName() == QString("User") ) { + return getValue( e.childNodes(), QString("UserClassName") ) + .toString(); + } else if ( e.tagName() == QString("DlgWidget") ) { + return QString( "QWidget" ); + } else { + return QChar( 'Q' ) + e.tagName(); + } +} + +void Dlg2Ui::emitColor( const QColor& color ) +{ + emitOpening( QString("color") ); + emitSimpleValue( QString("red"), QString::number(color.red()) ); + emitSimpleValue( QString("green"), QString::number(color.green()) ); + emitSimpleValue( QString("blue"), QString::number(color.blue()) ); + emitClosing( QString("color") ); +} + +void Dlg2Ui::emitColorGroup( const QString& name, const QColorGroup& group ) +{ + emitOpening( name ); + for ( int i = 0; i < NumColorRoles; i++ ) + emitColor( group.color((QColorGroup::ColorRole) i) ); + emitClosing( name ); +} + +void Dlg2Ui::emitVariant( const QVariant& val, const QString& stringType ) +{ + if ( val.isValid() ) { + switch ( val.type() ) { + case QVariant::String: + emitSimpleValue( stringType, val.toString() ); + break; + case QVariant::CString: + emitSimpleValue( QString("cstring"), val.toString() ); + break; + case QVariant::Bool: + emitSimpleValue( QString("bool"), + QString(val.toBool() ? "true" : "false") ); + break; + case QVariant::Int: + case QVariant::UInt: + emitSimpleValue( QString("number"), val.toString() ); + break; + case QVariant::Rect: + emitOpening( QString("rect") ); + emitSimpleValue( QString("x"), QString::number(val.toRect().x()) ); + emitSimpleValue( QString("y"), QString::number(val.toRect().y()) ); + emitSimpleValue( QString("width"), + QString::number(val.toRect().width()) ); + emitSimpleValue( QString("height"), + QString::number(val.toRect().height()) ); + emitClosing( QString("rect") ); + break; + case QVariant::Point: + emitOpening( QString("point") ); + emitSimpleValue( QString("x"), QString::number(val.toPoint().x()) ); + emitSimpleValue( QString("y"), QString::number(val.toPoint().y()) ); + emitClosing( QString("point") ); + break; + case QVariant::Size: + emitOpening( QString("size") ); + emitSimpleValue( QString("width"), + QString::number(val.toSize().width()) ); + emitSimpleValue( QString("height"), + QString::number(val.toSize().height()) ); + emitClosing( QString("size") ); + break; + case QVariant::Color: + emitColor( val.toColor() ); + break; + case QVariant::Font: + emitOpening( QString("font") ); + emitSimpleValue( QString("family"), val.toFont().family() ); + emitSimpleValue( QString("pointsize"), + QString::number(val.toFont().pointSize()) ); + if ( val.toFont().bold() ) + emitSimpleValue( QString("bold"), QChar('1') ); + if ( val.toFont().italic() ) + emitSimpleValue( QString("italic"), QChar('1') ); + if ( val.toFont().underline() ) + emitSimpleValue( QString("underline"), QChar('1') ); + if ( val.toFont().strikeOut() ) + emitSimpleValue( QString("strikeout"), QChar('1') ); + emitClosing( QString("font") ); + break; + case QVariant::Palette: + emitOpening( QString("palette") ); + emitColorGroup( QString("active"), val.toPalette().active() ); + emitColorGroup( QString("disabled"), val.toPalette().disabled() ); + emitColorGroup( QString("inactive"), val.toPalette().inactive() ); + emitClosing( QString("palette") ); + break; + default: + emitSimpleValue( QString("fnord"), QString::null ); + } + } +} + +void Dlg2Ui::emitProperty( const QString& prop, const QVariant& val, + const QString& stringType ) +{ + emitOpening( QString("property"), attribute(QString("name"), prop) ); + emitVariant( val, stringType ); + emitClosing( QString("property") ); +} + +void Dlg2Ui::emitAttribute( const QString& attr, const QVariant& val, + const QString& stringType ) +{ + emitOpening( QString("attribute"), attribute(QString("name"), attr) ); + emitVariant( val, stringType ); + emitClosing( QString("attribute") ); +} + +void Dlg2Ui::emitOpeningLayout( bool needsWidget, const QString& layoutKind, + const QString& name, int border, + int autoBorder ) +{ + QString namex = name; + + if ( namex.isEmpty() ) + namex = QString( "Layout%1" ).arg( uniqueLayout++ ); + + if ( needsWidget ) { + emitOpeningWidget( QString("QLayoutWidget") ); + emitProperty( QString("name"), namex.latin1() ); + } + emitOpening( layoutKind ); + if ( !needsWidget ) + emitProperty( QString("name"), namex.latin1() ); + if ( border != 5 ) + emitProperty( QString("margin"), border ); + if ( autoBorder != 5 ) + emitProperty( QString("spacing"), autoBorder ); + yyLayoutDepth++; +} + +void Dlg2Ui::flushWidgets() +{ + QRegExp widgetForLayout( QString("Q(?:[HV]Box|Grid)") ); + + while ( !yyWidgetMap.isEmpty() ) { + QString className = widgetClassName( *yyWidgetMap.begin() ); + if ( !widgetForLayout.exactMatch(className) ) { + emitOpeningWidget( className ); + emitWidgetBody( *yyWidgetMap.begin(), FALSE ); + emitClosing( QString("widget") ); + } + yyWidgetMap.remove( yyWidgetMap.begin() ); + } +} + +void Dlg2Ui::emitClosingLayout( bool needsWidget, const QString& layoutKind ) +{ + yyLayoutDepth--; + /* + Qt Designer can deal with layouted widgets and with + fixed-position widgets, but not both at the same time. If such a + thing happens, we arbitrarily put the fixed-position widgets in + the layout so that they at least show up in Qt Designer. + */ + if ( yyLayoutDepth == 0 ) + flushWidgets(); + + emitClosing( layoutKind ); + if ( needsWidget ) + emitClosing( QString("widget") ); +} + +bool Dlg2Ui::isWidgetType( const QDomElement& e ) +{ + return yyWidgetTypeSet.contains( e.tagName() ); +} + +void Dlg2Ui::emitSpacer( int spacing, int stretch ) +{ + QString orientationStr; + QSize sizeHint; + QString sizeType = QString( "Fixed" ); + + if ( yyBoxKind == QString("hbox") ) { + orientationStr = QString( "Horizontal" ); + sizeHint = QSize( spacing, 20 ); + } else { + orientationStr = QString( "Vertical" ); + sizeHint = QSize( 20, spacing ); + } + if ( stretch > 0 ) + sizeType = QString( "Expanding" ); + + emitOpening( QString("spacer") ); + emitProperty( QString("name"), + QString("Spacer%1").arg(uniqueSpacer++).latin1() ); + emitProperty( QString("orientation"), orientationStr, QString("enum") ); + if ( spacing > 0 ) + emitProperty( QString("sizeHint"), sizeHint, QString("qsize") ); + emitProperty( QString("sizeType"), sizeType, QString("enum") ); + emitClosing( QString("spacer") ); +} + +QString Dlg2Ui::filteredFlags( const QString& flags, const QRegExp& filter ) +{ + QRegExp evil( QString("[^0-9A-Z_a-z|]") ); + + QString f = flags; + f.replace( evil, QString::null ); + QStringList splitted = QStringList::split( QChar('|'), f ); + return splitted.grep( filter ).join( QChar('|') ); +} + +void Dlg2Ui::emitFrameStyleProperty( int style ) +{ + QString shape; + QString shadow; + + switch ( style & QFrame::MShape ) { + case QFrame::Box: + shape = QString( "Box" ); + break; + case QFrame::Panel: + shape = QString( "Panel" ); + break; + case QFrame::WinPanel: + shape = QString( "WinPanel" ); + break; + case QFrame::HLine: + shape = QString( "HLine" ); + break; + case QFrame::VLine: + shape = QString( "VLine" ); + break; + case QFrame::StyledPanel: + shape = QString( "StyledPanel" ); + break; + case QFrame::PopupPanel: + shape = QString( "PopupPanel" ); + break; + case QFrame::MenuBarPanel: + shape = QString( "MenuBarPanel" ); + break; + case QFrame::ToolBarPanel: + shape = QString( "ToolBarPanel" ); + break; + case QFrame::LineEditPanel: + shape = QString( "LineEditPanel" ); + break; + case QFrame::TabWidgetPanel: + shape = QString( "TabWidgetPanel" ); + break; + case QFrame::GroupBoxPanel: + shape = QString( "GroupBoxPanel" ); + break; + default: + shape = QString( "NoFrame" ); + } + + switch ( style & QFrame::MShadow ) { + case QFrame::Raised: + shadow = QString( "Raised" ); + break; + case QFrame::Sunken: + shadow = QString( "Sunken" ); + break; + default: + shadow = QString( "Plain" ); + } + + emitProperty( QString("frameShape"), shape, QString("enum") ); + emitProperty( QString("frameShadow"), shadow, QString("enum") ); +} + +void Dlg2Ui::emitWidgetBody( const QDomElement& e, bool layouted ) +{ + QRegExp align( QString("^(?:Align|WordBreak$)") ); + QRegExp frameShape( QString( + "^(?:NoFrame|Box|(?:Win|Styled|Popup|(?:Menu|Tool)Bar)?Panel|" + "[HV]Line)$") ); + QRegExp frameShadow( QString( "^(?:Plain|Raised|Sunken)$") ); + QRegExp numeric( QString("[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+") ); + QRegExp connex( QString( + "\\s*\\[(BaseClass|P(?:ublic|rotected))\\]\\s*([0-9A-Z_a-z]+)\\s*" + "-->\\s*([0-9A-Z_a-z]+)\\s*(\\([^()]*\\))\\s*") ); + QRegExp qdialogSlots( QString( + "done\\(\\s*int\\s*\\)|(?:accept|reject)\\(\\s*\\)") ); + + QString userClassHeader; + QString userClassName; + QString parentTagName; + QString name; + QString variableName; + QMap pp; + + QDomNode n = e; + while ( !n.isNull() ) { + if ( isWidgetType(n.toElement()) ) { + parentTagName = n.toElement().tagName(); + pp = yyPropertyMap[parentTagName]; + n = n.firstChild(); + } else { + QString tagName = n.toElement().tagName(); + + QMap::ConstIterator p = pp.find( tagName ); + if ( p == pp.end() ) { + /* + These properties are not in the propertyDefs table, + since they are found in many classes anyway and need + to be treated the same in each case. + */ + if ( tagName == QString("Alignement") || + tagName == QString("Alignment") ) { + QString flags = getValue( n.toElement(), tagName ) + .toString(); + flags = filteredFlags( flags, align ); + if ( !flags.isEmpty() ) + emitProperty( QString("alignment"), flags, + QString("set") ); + } else if ( tagName == QString("ItemList") ) { + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == QString("Item") ) { + QString text = getTextValue( child ); + emitOpening( QString("item") ); + emitProperty( QString("text"), text ); + emitClosing( QString("item") ); + } + child = child.nextSibling(); + } + } + } else { + QString propertyName( propertyDefs[*p].qtName ); + + if ( propertyName.isEmpty() ) { + /* + These properties are in the propertyDefs table, + but they have no direct Qt equivalent. + */ + if ( parentTagName == QString("ComboBox") ) { + if ( tagName == QString("Style") ) { + if ( getTextValue(n) == QString("ReadWrite") ) + emitProperty( QString("editable"), + QVariant(TRUE, 0) ); + } + } else if ( parentTagName == QString("DlgWidget") ) { + if ( tagName == QString("Name") ) { + name = getTextValue( n ); + } else if ( tagName == QString("Rect") ) { + QRect rect = getValue( n.toElement(), tagName, + QString("qrect") ) + .toRect(); + if ( !layouted ) + emitProperty( QString("geometry"), rect, + QString("qrect") ); + } else if ( tagName == QString("SignalConnection") ) { + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == + QString("Signal") ) { + QString text = getTextValue( child ); + if ( connex.exactMatch(text) ) { + DlgConnection c; + c.sender = getValue( + n.parentNode().childNodes(), + QString("Name") ).toString(); + c.signal = connex.cap( 2 ) + + connex.cap( 4 ); + c.slot = connex.cap( 3 ) + + connex.cap( 4 ); + yyConnections.append( c ); + + if ( connex.cap(1) != + QString("BaseClass") && + !qdialogSlots.exactMatch(c.slot) ) + yySlots.insert( c.slot, + connex.cap(1) ); + } + } + child = child.nextSibling(); + } + } else if ( tagName == QString("Variable") ) { + variableName = getTextValue( n ); + } + } else if ( parentTagName == QString("Frame") ) { + if ( tagName == QString("Style") ) { + int style = getValue( n.toElement(), tagName, + QString("integer") ).toInt(); + emitFrameStyleProperty( style ); + } + } else if ( parentTagName == QString("LCDNumber") ) { + if ( tagName == QString("Value") ) { + QString text = getValue( n.toElement(), tagName ) + .toString(); + if ( numeric.exactMatch(text) ) + emitProperty( QString("value"), + text.toDouble() ); + } + } else if ( parentTagName == QString("ListView") ) { + if ( tagName == QString("HeaderInformation") ) { + int columnNo = 1; + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == + QString("Header") ) { + QString text = getValue( child.childNodes(), + QString("Text") ) + .toString(); + if ( text.isEmpty() ) + text = QString( "Column %1" ) + .arg( columnNo ); + emitOpening( QString("column") ); + emitProperty( QString("text"), text ); + emitClosing( QString("column") ); + } + child = child.nextSibling(); + columnNo++; + } + } + } else if ( parentTagName == QString("TabBar") ) { + if ( tagName == QString("TabNames") ) { + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == + QString("Tab") ) { + QString text = getTextValue( child ); + emitOpeningWidget( QString("QWidget") ); + emitProperty( QString("name"), "tab" ); + emitAttribute( QString("title"), text ); + emitClosing( QString("widget") ); + } + child = child.nextSibling(); + } + } + } else if ( parentTagName == QString("User") ) { + if ( tagName == QString("UserClassHeader") ) { + userClassHeader = getTextValue( n ); + } else if ( tagName == QString("UserClassName") ) { + userClassName = getTextValue( n ); + } + } + } else { + /* + These properties are in the propertyDefs table; + they have a direct Qt equivalent. + */ + QString type( propertyDefs[*p].type ); + QVariant val = getValue( n.toElement(), tagName, type ); + + if ( type == QString("qstring") ) + type = QString( "string" ); + + bool omit = FALSE; + if ( propertyName == QString("backgroundOrigin") && + val.toString() == QString("WidgetOrigin") ) + omit = TRUE; + if ( propertyName == QString("enabled") && val.toBool() ) + omit = TRUE; + if ( propertyName == QString("minimumSize") && + val.toSize() == QSize(-1, -1) ) + omit = TRUE; + if ( propertyName == QString("maximumSize") && + val.toSize() == QSize(32767, 32767) ) + omit = TRUE; + + if ( !omit ) + emitProperty( propertyName, val, type ); + } + } + n = n.nextSibling(); + } + } + + if ( !variableName.isEmpty() ) { + yyAliasMap.insert( name, variableName ); + name = variableName; + } + if ( !name.isEmpty() ) + emitProperty( QString("name"), name.latin1() ); + + if ( !userClassName.isEmpty() ) + yyCustomWidgets.insert( userClassName, userClassHeader ); +} + +bool Dlg2Ui::checkTagName( const QDomElement& e, const QString& tagName ) +{ + bool ok = ( e.tagName() == tagName ); + if ( !ok ) + syntaxError(); + return ok; +} + +QString Dlg2Ui::normalizeType( const QString& type ) +{ + QString t = type; + if ( t.isEmpty() || t == QString("enum") || t == QString( "qcstring" ) || + t == QString("set") ) + t = QString( "qstring" ); + return t; +} + +QVariant Dlg2Ui::getValue( const QDomElement& e, const QString& tagName, + const QString& type ) +{ + QVariant val; + + if ( e.tagName() != tagName ) + return val; + + QString t = e.attributes().namedItem( "type" ).toAttr().value(); + if ( normalizeType(t) != normalizeType(type) ) + return val; + + if ( type == QString("integer") ) { + return getTextValue( e ).toInt(); + } else if ( type == QString("boolean") ) { + return QVariant( isTrue(getTextValue(e)), 0 ); + } else if ( type == QString("double") ) { + return getTextValue( e ).toDouble(); + } else if ( type == QString("qcstring") ) { + return getTextValue( e ).latin1(); + } else if ( type == QString("enum") || type == QString("qstring") || + type == QString("set") ) { + return getTextValue( e ); + } else { + QDomNodeList children = e.childNodes(); + + if ( type == QString("qsize") ) { + int width = getValue( children, QString("Width"), + QString("integer") ).toInt(); + int height = getValue( children, QString("Height"), + QString("integer") ).toInt(); + return QSize( width, height ); + } else if ( type == QString("qrect") ) { + int x = getValue( children, QString("X"), QString("integer") ) + .toInt(); + int y = getValue( children, QString("Y"), QString("integer") ) + .toInt(); + int width = getValue( children, QString("Width"), + QString("integer") ).toInt(); + int height = getValue( children, QString("Height"), + QString("integer") ).toInt(); + return QRect( x, y, width, height ); + } else if ( type == QString("qpoint") ) { + int x = getValue( children, QString("X"), QString("integer") ) + .toInt(); + int y = getValue( children, QString("Y"), QString("integer") ) + .toInt(); + return QPoint( x, y ); + } else if ( type == QString("qpalette") ) { + QColorGroup active = getValue( children, QString("Active"), + QString("qcolorgroup") ) + .toColorGroup(); + QColorGroup disabled = getValue( children, QString("Disabled"), + QString("qcolorgroup") ) + .toColorGroup(); + QColorGroup inactive = getValue( children, QString("Inactive"), + QString("qcolorgroup") ) + .toColorGroup(); + return QPalette( active, disabled, inactive ); + } else if ( type == QString("qfont") ) { + QString family = getValue( children, QString("Family"), + QString("qstring") ).toString(); + int pointSize = getValue( children, QString("PointSize"), + QString("integer") ).toInt(); + int weight = getValue( children, QString("weight"), + QString("integer") ).toInt(); + bool italic = getValue( children, QString("Italic"), + QString("boolean") ).toBool(); + bool underline = getValue( children, QString("Underline"), + QString("boolean") ).toBool(); + bool strikeOut = getValue( children, QString("StrikeOut"), + QString("boolean") ).toBool(); + int styleHint = getValue( children, QString("StyleHint"), + QString("integer") ).toInt(); + + QFont f; + if ( !family.isEmpty() ) + f.setFamily( family ); + if ( pointSize != 0 ) + f.setPointSize( pointSize ); + if ( weight != 0 ) + f.setWeight( weight ); + f.setItalic( italic ); + f.setUnderline( underline ); + f.setStrikeOut( strikeOut ); + if ( styleHint != 0 ) + f.setStyleHint( (QFont::StyleHint) styleHint ); + return f; + } else if ( type == QString("qcolor") ) { + // if any component missing, zero is to be assumed + int red = getValue( children, QString("Red"), QString("integer") ) + .toInt(); + int green = getValue( children, QString("Green"), + QString("integer") ).toInt(); + int blue = getValue( children, QString("Blue"), QString("integer") ) + .toInt(); + return QColor( red, green, blue ); + } else if ( type == QString("qcolorgroup") ) { + static const QColorGroup::ColorRole roles[NumColorRoles] = { + QColorGroup::Foreground, QColorGroup::Button, + QColorGroup::Light, QColorGroup::Midlight, QColorGroup::Dark, + QColorGroup::Mid, QColorGroup::Text, QColorGroup::BrightText, + QColorGroup::ButtonText, QColorGroup::Base, + QColorGroup::Background, QColorGroup::Shadow, + QColorGroup::Highlight, QColorGroup::HighlightedText + }; + static const char * const roleNames[NumColorRoles] = { + "Foreground", "Button", "Light", "MidLight", "Dark", "Mid", + "Text", "BrightText", "ButtonText", "Base", "Background", + "Shadow", "HighLighted", "HighLightedText" + }; + QColorGroup group; + + for ( int i = 0; i < NumColorRoles; i++ ) + group.setColor( roles[i], + getValue(children, QString(roleNames[i]), + QString("qcolor")).toColor() ); + return group; + } else { + syntaxError(); + } + } + return val; +} + +void Dlg2Ui::matchDialogCommon( const QDomElement& dialogCommon ) +{ + if ( !checkTagName(dialogCommon, QString("DialogCommon")) ) + return; + + QString sourceDir; + QString classHeader; + QString classSource; + QString dataHeader; + QString dataSource; + QString dataName; + QString windowBaseClass( "QDialog" ); + bool isCustom = FALSE; + QString customBaseHeader; + QString windowCaption; + + yyClassName = "Form1"; + + QDomNode n = dialogCommon.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + QString val = getTextValue( n ); + + if ( tagName == QString("SourceDir") ) { + sourceDir = val; + } else if ( tagName == QString("ClassHeader") ) { + classHeader = val; + } else if ( tagName == QString("ClassSource") ) { + classSource = val; + } else if ( tagName == QString("ClassName") ) { + yyClassName = val; + } else if ( tagName == QString("DataHeader") ) { + dataHeader = val; + } else if ( tagName == QString("DataSource") ) { + dataSource = val; + } else if ( tagName == QString("DataName") ) { + dataName = val; + } else if ( tagName == QString("WindowBaseClass") ) { + if ( val == QString("Custom") ) + isCustom = TRUE; + else + windowBaseClass = val; + } else if ( tagName == QString("IsModal") ) { + } else if ( tagName == QString("CustomBase") ) { + windowBaseClass = val; + } else if ( tagName == QString("CustomBaseHeader") ) { + customBaseHeader = val; + } else if ( tagName == QString("WindowCaption") ) { + windowCaption = val; + } + n = n.nextSibling(); + } + + emitSimpleValue( QString("class"), yyClassName ); + emitOpeningWidget( windowBaseClass ); + + if ( windowCaption.isEmpty() ) + windowCaption = yyClassName; + emitProperty( QString("name"), yyClassName.latin1() ); + emitProperty( QString("caption"), windowCaption ); + + if ( isCustom ) + yyCustomWidgets.insert( windowBaseClass, customBaseHeader ); +} + +bool Dlg2Ui::needsQLayoutWidget( const QDomElement& e ) +{ + QRegExp widgetExists( QString("WidgetLayout|Layout_Widget") ); + + // we should also check that the widget is not a QHBox, QVBox, or QGrid + QString grandpa = e.parentNode().parentNode().toElement().tagName(); + return !widgetExists.exactMatch( grandpa ); +} + +void Dlg2Ui::matchBoxLayout( const QDomElement& boxLayout ) +{ + QString directionStr; + QString prevBoxKind = yyBoxKind; + int border = 5; + int autoBorder = 5; + QString name; + bool needsWidget = needsQLayoutWidget( boxLayout ); + bool opened = FALSE; + + QDomNode n = boxLayout.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + + if ( tagName == QString("Children") ) { + if ( !opened ) { + emitOpeningLayout( needsWidget, yyBoxKind, name, border, + autoBorder ); + if ( !directionStr.isEmpty() ) + emitProperty( QString("direction"), directionStr, + QString("enum") ); + opened = TRUE; + } + matchLayout( n.toElement() ); + } else { + QString val = getTextValue( n ); + + if ( tagName == QString("Direction") ) { + if ( val == QString("LeftToRight") ) { + yyBoxKind = QString( "hbox" ); + } else if ( val == QString("RightToLeft") ) { + directionStr = val; + yyBoxKind = QString( "hbox" ); + } else if ( val == QString("TopToBottom") ) { + yyBoxKind = QString( "vbox" ); + } else if ( val == QString("BottomToTop") ) { + directionStr = val; + yyBoxKind = QString( "vbox" ); + } else { + syntaxError(); + } + } else if ( tagName == QString("Border") ) { + border = val.toInt(); + } else if ( tagName == QString("AutoBorder") ) { + autoBorder = val.toInt(); + } else if ( tagName == QString("Name") ) { + name = val; + } + } + + n = n.nextSibling(); + } + if ( opened ) { + emitClosingLayout( needsWidget, yyBoxKind ); + yyBoxKind = prevBoxKind; + } +} + +void Dlg2Ui::matchBoxSpacing( const QDomElement& boxSpacing ) +{ + int spacing = 7; + + QDomNode n = boxSpacing.firstChild(); + while ( !n.isNull() ) { + QString val = getTextValue( n ); + + if ( n.toElement().tagName() == QString("Spacing") ) + spacing = val.toInt(); + n = n.nextSibling(); + } + emitSpacer( spacing, 0 ); +} + +void Dlg2Ui::matchBoxStretch( const QDomElement& boxStretch ) +{ + int stretch = 1; + + QDomNode n = boxStretch.firstChild(); + while ( !n.isNull() ) { + QString val = getTextValue( n ); + + if ( n.toElement().tagName() == QString("Stretch") ) + stretch = val.toInt(); + n = n.nextSibling(); + } + emitSpacer( 0, stretch ); +} + +void Dlg2Ui::matchGridLayout( const QDomElement& gridLayout ) +{ + int oldGridRow = yyGridRow; + int oldGridColumn = yyGridColumn; + int border = 5; + int autoBorder = 5; + QString name; + QString menu; + bool needsWidget = needsQLayoutWidget( gridLayout ); + bool opened = FALSE; + + QDomNode n = gridLayout.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + + if ( tagName == QString("Children") ) { + if ( !opened ) { + emitOpeningLayout( needsWidget, QString("grid"), name, border, + autoBorder ); + yyGridRow = -1; + yyGridColumn = -1; + opened = TRUE; + } + matchLayout( n.toElement() ); + } else { + if ( tagName == QString("Border") ) { + border = getTextValue( n ).toInt(); + } else if ( tagName == QString("AutoBorder") ) { + autoBorder = getTextValue( n ).toInt(); + } else if ( tagName == QString("Name") ) { + name = getTextValue( n ); + } else if ( tagName == QString("Menu") ) { + menu = getTextValue( n ); + } + } + n = n.nextSibling(); + } + if ( opened ) + emitClosingLayout( needsWidget, QString("grid") ); + yyGridRow = oldGridRow; + yyGridColumn = oldGridColumn; +} + +void Dlg2Ui::matchGridRow( const QDomElement& gridRow ) +{ + yyGridRow++; + + QDomNode n = gridRow.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + + if ( tagName == QString("Children") ) { + yyGridColumn = 0; + matchLayout( n.toElement() ); + } + n = n.nextSibling(); + } +} + +void Dlg2Ui::matchGridSpacer( const QDomElement& gridSpacer ) +{ + if ( !gridSpacer.firstChild().isNull() ) + syntaxError(); +} + +void Dlg2Ui::matchLayoutWidget( const QDomElement& layoutWidget ) +{ + QDomElement children; + QString widget; + + QDomNode n = layoutWidget.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + + if ( tagName == QString("Children") ) + children = n.toElement(); + else if ( tagName == QString("Widget") ) + widget = getTextValue( n ); + n = n.nextSibling(); + } + + if ( !widget.isEmpty() ) { + QMap::Iterator w = yyWidgetMap.find( widget ); + if ( w == yyWidgetMap.end() ) { + syntaxError(); + } else { + QString className = widgetClassName( *w ); + if ( className == QString("QHBox") || + className == QString("QVBox") ) { + bool needsWidget = needsQLayoutWidget( layoutWidget ); + + QString prevBoxKind = yyBoxKind; + yyBoxKind = className.mid( 1 ).lower(); + + int spacing = getValue( (*w).childNodes(), QString("Spacing"), + QString("integer") ).toInt(); + if ( spacing < 1 ) + spacing = 5; + + emitOpeningLayout( needsWidget, yyBoxKind, widget, 0, spacing ); + if ( !children.isNull() ) + matchLayout( children ); + emitClosingLayout( needsWidget, yyBoxKind ); + yyBoxKind = prevBoxKind; + } else if ( className == QString("QGrid") ) { + bool needsWidget = needsQLayoutWidget( layoutWidget ); + int n = 0; + + QString direction = getValue( (*w).childNodes(), + QString("Direction") ).toString(); + int rowsCols = getValue( (*w).childNodes(), QString("RowCols"), + QString("integer") ).toInt(); + if ( rowsCols == 0 ) + rowsCols = getValue( (*w).childNodes(), + QString("RowsCols"), + QString("integer") ).toInt(); + if ( rowsCols < 1 ) + rowsCols = 5; + int spacing = getValue( (*w).childNodes(), QString("Spacing"), + QString("integer") ).toInt(); + if ( spacing < 1 ) + spacing = 5; + + emitOpeningLayout( needsWidget, QString("grid"), widget, 0, + spacing ); + + QDomNode child = children.firstChild(); + while ( !child.isNull() ) { + if ( direction == QString("Vertical") ) { + yyGridColumn = n / rowsCols; + yyGridRow = n % rowsCols; + } else { + yyGridColumn = n % rowsCols; + yyGridRow = n / rowsCols; + } + matchBox( child.toElement() ); + n++; + child = child.nextSibling(); + } + yyGridColumn = -1; + yyGridRow = -1; + emitClosingLayout( needsWidget, QString("grid") ); + } else { + emitOpeningWidget( widgetClassName(*w) ); + emitWidgetBody( *w, TRUE ); + if ( !children.isNull() ) + matchLayout( children ); + emitClosing( QString("widget") ); + } + yyWidgetMap.remove( w ); + } + } +} + +void Dlg2Ui::matchBox( const QDomElement& box ) +{ + /* + What is this jump table doing in here? + */ + static const struct { + const char *tagName; + void (Dlg2Ui::*matchFunc)( const QDomElement& ); + } jumpTable[] = { + { "Box_Layout", &Dlg2Ui::matchBoxLayout }, + { "Box_Spacing", &Dlg2Ui::matchBoxSpacing }, + { "Box_Stretch", &Dlg2Ui::matchBoxStretch }, + { "Grid_Layout", &Dlg2Ui::matchGridLayout }, + { "Grid_Row", &Dlg2Ui::matchGridRow }, + { "Grid_Spacer", &Dlg2Ui::matchGridSpacer }, + { "Layout_Widget", &Dlg2Ui::matchLayoutWidget }, + { 0, 0 } + }; + + int i = 0; + while ( jumpTable[i].tagName != 0 ) { + if ( QString(jumpTable[i].tagName) == box.tagName() ) { + (this->*jumpTable[i].matchFunc)( box ); + break; + } + i++; + } + if ( jumpTable[i].tagName == 0 ) + syntaxError(); +} + +void Dlg2Ui::matchLayout( const QDomElement& layout ) +{ + int column = yyGridColumn; + + QDomNode n = layout.firstChild(); + while ( !n.isNull() ) { + if ( column != -1 ) + yyGridColumn = column++; + matchBox( n.toElement() ); + n = n.nextSibling(); + } +} + +void Dlg2Ui::matchWidgetLayoutCommon( const QDomElement& widgetLayoutCommon ) +{ + QDomNodeList children = widgetLayoutCommon.childNodes(); + + /* + Since we do not respect the spacing and margins specified in + the .dlg file, the specified geometry is slightly wrong (too + small). It still seems to be better to take it in. + */ +#if 1 + QPoint initialPos = getValue( children, QString("InitialPos"), + QString("qpoint") ).toPoint(); + QSize size = getValue( children, QString("Size"), QString("qsize") ) + .toSize(); +#endif + QSize minSize = getValue( children, QString("MinSize"), QString("qsize") ) + .toSize(); + QSize maxSize = getValue( children, QString("MaxSize"), QString("qsize") ) + .toSize(); + +#if 1 + if ( initialPos == QPoint(-1, -1) ) + initialPos = QPoint( 0, 0 ); + + emitProperty( QString("geometry"), QRect(initialPos, size) ); +#endif + if ( minSize != QSize(-1, -1) ) + emitProperty( QString("minimumSize"), minSize ); + if ( maxSize != QSize(32767, 32767) ) + emitProperty( QString("maximumSize"), maxSize ); +} + +void Dlg2Ui::matchWidget( const QDomElement& widget ) +{ + QString name; + + QDomNode n = widget; + while ( !n.isNull() ) { + if ( isWidgetType(n.toElement()) ) { + n = n.firstChild(); + } else { + if ( n.toElement().tagName() == QString("Name") ) { + name = getTextValue( n ); + break; + } + n = n.nextSibling(); + } + } + if ( name.isEmpty() ) + name = QString( "Widget%1" ).arg( uniqueWidget++ ); + + if ( yyWidgetMap.contains(name) ) + syntaxError(); + yyWidgetMap.insert( name, widget ); +} + +void Dlg2Ui::matchWidgets( const QDomElement& widgets ) +{ + QDomNode n = widgets.firstChild(); + while ( !n.isNull() ) { + matchWidget( n.toElement() ); + n = n.nextSibling(); + } +} + +void Dlg2Ui::matchTabOrder( const QDomElement& tabOrder ) +{ + QDomNode n = tabOrder.firstChild(); + while ( !n.isNull() ) { + if ( n.toElement().tagName() == QString("Widget") ) + yyTabStops.append( getTextValue(n.toElement()) ); + n = n.nextSibling(); + } +} + +void Dlg2Ui::matchWidgetLayout( const QDomElement& widgetLayout ) +{ + if ( !checkTagName(widgetLayout, QString("WidgetLayout")) ) + return; + + QDomNode n = widgetLayout.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + + if ( tagName == QString("WidgetLayoutCommon") ) { + matchWidgetLayoutCommon( n.toElement() ); + } else if ( tagName == QString("Widgets") ) { + matchWidgets( n.toElement() ); + } else if ( tagName == QString("TabOrder") ) { + matchTabOrder( n.toElement() ); + } else if ( tagName == QString("Layout") ) { + matchLayout( n.toElement() ); + } + n = n.nextSibling(); + } +} + +void Dlg2Ui::matchDialog( const QDomElement& dialog ) +{ + if ( !checkTagName(dialog, QString("Dialog")) ) + return; + + QDomNodeList nodes = dialog.childNodes(); + if ( nodes.count() == 2 ) { + matchDialogCommon( nodes.item(0).toElement() ); + matchWidgetLayout( nodes.item(1).toElement() ); + flushWidgets(); + emitClosing( QString("widget") ); + + if ( !yyCustomWidgets.isEmpty() ) { + emitOpening( QString("customwidgets") ); + + QMap::Iterator w = yyCustomWidgets.begin(); + while ( w != yyCustomWidgets.end() ) { + emitOpening( QString("customwidget") ); + emitSimpleValue( QString("class"), w.key() ); + if ( !(*w).isEmpty() ) + emitSimpleValue( QString("header"), *w, + attribute(QString("location"), + QString("local")) ); + emitClosing( QString("customwidget") ); + ++w; + } + emitClosing( QString("customwidgets") ); + } + + if ( yyConnections.count() + yySlots.count() > 0 ) { + emitOpening( QString("connections") ); + + QValueList::Iterator c = yyConnections.begin(); + while ( c != yyConnections.end() ) { + emitOpening( QString("connection") ); + emitSimpleValue( QString("sender"), alias((*c).sender) ); + emitSimpleValue( QString("signal"), (*c).signal ); + emitSimpleValue( QString("receiver"), yyClassName ); + emitSimpleValue( QString("slot"), (*c).slot ); + emitClosing( QString("connection") ); + ++c; + } + + QMap::Iterator s = yySlots.begin(); + while ( s != yySlots.end() ) { + AttributeMap attr; + attr.insert( QString("access"), *s ); + attr.insert( QString("language"), QString("C++") ); + attr.insert( QString("returntype"), QString("void") ); + emitSimpleValue( QString("slot"), s.key(), attr ); + ++s; + } + emitClosing( QString("connections") ); + } + + if ( !yyTabStops.isEmpty() ) { + emitOpening( QString("tabstops") ); + QStringList::ConstIterator t = yyTabStops.begin(); + while ( t != yyTabStops.end() ) { + emitSimpleValue( QString("tabstop"), alias(*t) ); + ++t; + } + emitClosing( QString("tabstops") ); + } + } +} + +QStringList Dlg2Ui::convertQtArchitectDlgFile( const QString& fileName ) +{ + int i; + + yyFileName = fileName; + yyLayoutDepth = 0; + yyGridRow = -1; + yyGridColumn = -1; + + numErrors = 0; + uniqueLayout = 1; + uniqueSpacer = 1; + uniqueWidget = 1; + + i = 0; + while ( widgetTypes[i] != 0 ) { + yyWidgetTypeSet.insert( QString(widgetTypes[i]), 0 ); + i++; + } + + i = 0; + while ( propertyDefs[i].widgetName != 0 ) { + yyPropertyMap[QString(propertyDefs[i].widgetName)] + .insert( QString(propertyDefs[i].architectName), i ); + i++; + } + + QDomDocument doc( QString("QtArch") ); + QFile f( fileName ); + if ( !f.open(IO_ReadOnly) ) { + return QStringList(); + } + if ( !doc.setContent(&f) ) { + QString firstLine; + f.at( 0 ); + f.readLine( firstLine, 128 ); + firstLine = firstLine.stripWhiteSpace(); + if ( firstLine.startsWith(QString("DlgEdit:v1")) ) { + error( QString("This file is a Qt Architect 1.x file. Qt Designer" + " can only read XML dialog files, as generated by Qt" + " Architect 2.1 or above." + "

    To convert this file to the right format," + " first install Qt Architect 2.1 (available at" + " http://qtarch.sourceforge.net/). Use the" + " update20.pl Perl script to update the file" + " to the 2.0 format. Load that file in Qt" + " Architect and save it. The file should now be in" + " XML format and loadable in Qt Designer.") ); + } else if ( firstLine.startsWith(QString("DlgEdit::v2")) ) { + error( QString("This file is a Qt Architect 2.0 file. Qt Designer" + " can only read XML dialog files, as generated by Qt" + " Architect 2.1 or above." + "

    To convert this file to the right format," + " first install Qt Architect 2.1 (available at" + " http://qtarch.sourceforge.net/). Load the" + " 2.0 file in Qt Architect and save it. The file" + " should now be in XML format and loadable in Qt" + " Designer.") ); + } else { + error( QString("The file you gave me is not an XML file, as far as" + " I can tell.") ); + } + + f.close(); + return QStringList(); + } + f.close(); + + QDomElement root = doc.documentElement(); + if ( root.tagName() != QString("QtArch") || + root.attributeNode("type").value() != QString("Dialog") ) { + error( QString("The file you gave me is not a Qt Architect dialog" + " file.") ); + return QStringList(); + } + + emitHeader(); + + QDomNode n = root.firstChild(); + while ( !n.isNull() ) { + // there should be only one + matchDialog( n.toElement() ); + n = n.nextSibling(); + } + + emitFooter(); + + QFile outf; + QString outFileName = yyClassName + QString( ".ui" ); + + outf.setName( outFileName ); + if ( !outf.open(IO_WriteOnly) ) { + qWarning( "dlg2ui: Could not open output file '%s'", + outFileName.latin1() ); + return QStringList(); + } + + QTextStream out; + out.setEncoding( QTextStream::Latin1 ); + out.setDevice( &outf ); + out << yyOut; + outf.close(); + + return QStringList( outFileName ); +} diff --git a/tools/designer/plugins/dlg/dlg2ui.h b/tools/designer/plugins/dlg/dlg2ui.h new file mode 100644 index 0000000..9fb206a --- /dev/null +++ b/tools/designer/plugins/dlg/dlg2ui.h @@ -0,0 +1,144 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DLG2UI_H +#define DLG2UI_H + +#include +#include +#include +#include + +typedef QMap AttributeMap; + +struct DlgConnection +{ + QString sender; + QString signal; + QString slot; + +#if defined(Q_FULL_TEMPLATE_INSTANTIATION) + bool operator==( const DlgConnection& ) const { + return sender == sender && signal == signal && slot == slot; + } +#endif +}; + +class Dlg2Ui +{ +public: + QStringList convertQtArchitectDlgFile( const QString& fileName ); + +private: + QString alias( const QString& name ) const; + QString opening( const QString& tag, + const AttributeMap& attr = AttributeMap() ); + QString closing( const QString& tag ); + void error( const QString& message ); + void syntaxError(); + QString getTextValue( const QDomNode& node ); + QVariant getValue( const QDomNodeList& children, const QString& tagName, + const QString& type = "qstring" ); + void emitHeader(); + void emitFooter(); + void emitSimpleValue( const QString& tag, const QString& value, + const AttributeMap& attr = AttributeMap() ); + void emitOpening( const QString& tag, + const AttributeMap& attr = AttributeMap() ); + void emitClosing( const QString& tag ); + void emitOpeningWidget( const QString& className ); + QString widgetClassName( const QDomElement& e ); + void emitColor( const QColor& color ); + void emitColorGroup( const QString& name, const QColorGroup& group ); + void emitVariant( const QVariant& val, + const QString& stringType = "string" ); + void emitProperty( const QString& prop, const QVariant& val, + const QString& stringType = "string" ); + void emitAttribute( const QString& attr, const QVariant& val, + const QString& stringType = "string" ); + void emitOpeningLayout( bool needsWidget, const QString& layoutKind, + const QString& name, int border, int autoBorder ); + void flushWidgets(); + void emitClosingLayout( bool needsWidget, const QString& layoutKind ); + bool isWidgetType( const QDomElement& e ); + void emitSpacer( int spacing, int stretch ); + QString filteredFlags( const QString& flags, const QRegExp& filter ); + void emitFrameStyleProperty( int style ); + void emitWidgetBody( const QDomElement& e, bool layouted ); + bool checkTagName( const QDomElement& e, const QString& tagName ); + QString normalizeType( const QString& type ); + QVariant getValue( const QDomElement& e, const QString& tagName, + const QString& type = "qstring" ); + void matchDialogCommon( const QDomElement& dialogCommon ); + bool needsQLayoutWidget( const QDomElement& e ); + void matchBoxLayout( const QDomElement& boxLayout ); + void matchBoxSpacing( const QDomElement& boxSpacing ); + void matchBoxStretch( const QDomElement& boxStretch ); + void matchGridLayout( const QDomElement& gridLayout ); + void matchGridRow( const QDomElement& gridRow ); + void matchGridSpacer( const QDomElement& gridSpacer ); + void matchLayoutWidget( const QDomElement& layoutWidget ); + void matchBox( const QDomElement& box ); + void matchLayout( const QDomElement& layout ); + void matchWidgetLayoutCommon( const QDomElement& widgetLayoutCommon ); + void matchWidget( const QDomElement& widget ); + void matchWidgets( const QDomElement& widgets ); + void matchTabOrder( const QDomElement& tabOrder ); + void matchWidgetLayout( const QDomElement& widgetLayout ); + void matchDialog( const QDomElement& dialog ); + + QString yyOut; + QString yyIndentStr; + QString yyFileName; + QString yyClassName; + QMap yyWidgetTypeSet; + QMap > yyPropertyMap; + QMap yyWidgetMap; + QMap yyCustomWidgets; + QValueList yyConnections; + QMap yySlots; + QMap yyAliasMap; + QStringList yyTabStops; + QString yyBoxKind; + int yyLayoutDepth; + int yyGridRow; + int yyGridColumn; + + int numErrors; + int uniqueLayout; + int uniqueSpacer; + int uniqueWidget; +}; + +#endif diff --git a/tools/designer/plugins/dlg/main.cpp b/tools/designer/plugins/dlg/main.cpp new file mode 100644 index 0000000..b698bad --- /dev/null +++ b/tools/designer/plugins/dlg/main.cpp @@ -0,0 +1,108 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include + +#include "dlg2ui.h" + +class DlgFilter : public ImportFilterInterface, public QLibraryInterface +{ +public: + DlgFilter(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface **iface ); + Q_REFCOUNT; + + QStringList featureList() const; + QStringList import( const QString& filter, const QString& filename ); + + bool init(); + void cleanup(); + bool canUnload() const; +}; + +DlgFilter::DlgFilter() +{ +} + +QRESULT DlgFilter::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)(ImportFilterInterface*)this; + else if ( uuid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( uuid == IID_ImportFilter ) + *iface = (ImportFilterInterface*)this; + else if ( uuid == IID_QLibrary ) + *iface = (QLibraryInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QStringList DlgFilter::featureList() const +{ + QStringList list; + list << "Qt Architect Dialog Files (*.dlg)" ; + return list; +} + +QStringList DlgFilter::import( const QString &, const QString& filename ) +{ + Dlg2Ui d; + return d.convertQtArchitectDlgFile( filename ); +} + +bool DlgFilter::init() +{ + return TRUE; +} + +void DlgFilter::cleanup() +{ +} + +bool DlgFilter::canUnload() const +{ + return TRUE; +} + +Q_EXPORT_COMPONENT() +{ + Q_CREATE_INSTANCE( DlgFilter ) +} diff --git a/tools/designer/plugins/glade/glade.pro b/tools/designer/plugins/glade/glade.pro new file mode 100644 index 0000000..c1be0c5 --- /dev/null +++ b/tools/designer/plugins/glade/glade.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += qt warn_on release plugin +HEADERS = glade2ui.h +SOURCES = main.cpp glade2ui.cpp +DESTDIR = ../../../../plugins/designer +DEFINES += QT_INTERNAL_XML +include( ../../../../src/qt_professional.pri ) +TARGET = gladeplugin +INCLUDEPATH += ../../interfaces + + +target.path += $$plugins.path/designer +INSTALLS += target diff --git a/tools/designer/plugins/glade/glade2ui.cpp b/tools/designer/plugins/glade/glade2ui.cpp new file mode 100644 index 0000000..39ff5e8 --- /dev/null +++ b/tools/designer/plugins/glade/glade2ui.cpp @@ -0,0 +1,2203 @@ +/********************************************************************** +** +** Converts a Glade .glade file into a .ui file. +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "glade2ui.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static const struct { + const char *gtkName; + const char *qtName; +} classNames[] = { + { "Custom", "Custom" }, + { "GnomeAbout", "QDialog" }, + { "GnomeApp", "QMainWindow" }, + { "GnomeCanvas", "QLabel" }, + { "GnomeColorPicker", "QComboBox" }, + { "GnomeDateEdit", "QDateTimeEdit" }, + { "GnomeDialog", "QDialog" }, + { "GnomeFontPicker", "QComboBox" }, + { "GnomeIconSelection", "QIconView" }, + { "GnomePixmap", "QLabel" }, + { "GnomePropertyBox", "QDialog" }, + { "GtkAccelLabel", "QLabel" }, + { "GtkAspectFrame", "QFrame" }, + { "GtkButton", "QPushButton" }, + { "GtkCList", "QListView" }, + { "GtkCTree", "QListView" }, + { "GtkCheckButton", "QCheckBox" }, + { "GtkCombo", "QComboBox" }, + { "GtkDial", "QDial" }, + { "GtkDialog", "QDialog" }, + { "GtkEntry", "QLineEdit" }, + { "GtkFixed", "QLayoutWidget" }, + { "GtkFrame", "QFrame" }, + { "GtkHPaned", "QSplitter" }, + { "GtkHScale", "QSlider" }, + { "GtkHScrollbar", "QScrollBar" }, + { "GtkHSeparator", "Line" }, + { "GtkHandleBox", "QFrame" }, + { "GtkImage", "QLabel" }, + { "GtkLabel", "QLabel" }, + { "GtkList", "QListBox" }, + { "GtkNotebook", "QTabWidget" }, + { "GtkOptionMenu", "QComboBox" }, + { "GtkPixmap", "QLabel" }, + { "GtkPreview", "QLabel" }, + { "GtkProgressBar", "QProgressBar" }, + { "GtkRadioButton", "QRadioButton" }, + { "GtkSpinButton", "QSpinBox" }, + { "GtkStatusbar", "QStatusBar" }, + { "GtkText", "QTextEdit" }, + { "GtkToggleButton", "QPushButton" }, + { "GtkTree", "QListView" }, + { "GtkVPaned", "QSplitter" }, + { "GtkVScale", "QSlider" }, + { "GtkVScrollbar", "QScrollBar" }, + { "GtkVSeparator", "Line" }, + { "Placeholder", "QLabel" }, + { 0, 0 } +}; + +static const struct { + const char *name; + const char *menuText; +} stockMenuItems[] = { + { "ABOUT", "&About" }, + { "CLEAR", "C&lear" }, + { "CLOSE", "&Close" }, + { "CLOSE_WINDOW", "&Close This Window" }, + { "COPY", "&Copy" }, + { "CUT", "C&ut" }, + { "END_GAME", "&End Game" }, + { "EXIT", "E&xit" }, + { "FIND", "&Find..." }, + { "FIND_AGAIN", "Find &Again" }, + { "HINT", "&Hint" }, + { "NEW", "&New" }, + { "NEW_GAME", "&New Game" }, + { "NEW_WINDOW", "Create New &Window" }, + { "OPEN", "&Open..." }, + { "PASTE", "&Paste" }, + { "PAUSE_GAME", "&Pause Game" }, + { "PREFERENCES", "&Preferences..." }, + { "PRINT", "&Print" }, + { "PRINT_SETUP", "Print S&etup..." }, + { "PROPERTIES", "&Properties..." }, + { "REDO", "&Redo" }, + { "REDO_MOVE", "&Redo Move" }, + { "REPLACE", "&Replace..." }, + { "RESTART_GAME", "&Restart Game" }, + { "REVERT", "&Revert" }, + { "SAVE", "&Save" }, + { "SAVE_AS", "Save &As..." }, + { "SCORES", "&Scores..." }, + { "SELECT_ALL", "&Select All" }, + { "UNDO", "&Undo" }, + { "UNDO_MOVE", "&Undo Move" }, + { 0, 0 } +}; + +static const struct { + const char *gtkName; + int qtValue; +} keys[] = { + { "BackSpace", Qt::Key_BackSpace }, + { "Delete", Qt::Key_Delete }, + { "Down", Qt::Key_Down }, + { "End", Qt::Key_End }, + { "Escape", Qt::Key_Escape }, + { "F1", Qt::Key_F1 }, + { "F10", Qt::Key_F10 }, + { "F11", Qt::Key_F11 }, + { "F12", Qt::Key_F12 }, + { "F2", Qt::Key_F2 }, + { "F3", Qt::Key_F3 }, + { "F4", Qt::Key_F4 }, + { "F5", Qt::Key_F5 }, + { "F6", Qt::Key_F6 }, + { "F7", Qt::Key_F7 }, + { "F8", Qt::Key_F8 }, + { "F9", Qt::Key_F9 }, + { "Home", Qt::Key_Home }, + { "Insert", Qt::Key_Insert }, + { "KP_Enter", Qt::Key_Enter }, + { "Left", Qt::Key_Left }, + { "Page_Down", Qt::Key_PageDown }, + { "Page_Up", Qt::Key_PageUp }, + { "Return", Qt::Key_Return }, + { "Right", Qt::Key_Right }, + { "Tab", Qt::Key_Tab }, + { "Up", Qt::Key_Up }, + { "space", Qt::Key_Space }, + { 0, 0 } +}; + +static QString nonMenuText( const QString& menuText ) +{ + QString t; + int len = (int) menuText.length(); + if ( menuText.endsWith(QString("...")) ) + len -= 3; + for ( int i = 0; i < len; i++ ) { + if ( menuText[i] != QChar('&') ) + t += menuText[i]; + } + return t; +} + +/* + Some GTK dialog use hyphens in variable names. Let's take no chance. +*/ +static QString fixedName( const QString& name ) +{ + const char *latin1 = name.latin1(); + QString fixed; + + int i = 0; + while ( latin1 != 0 && latin1[i] != '\0' ) { + if ( isalnum(latin1[i]) ) + fixed += name[i]; + else + fixed += QChar( '_' ); + i++; + } + return fixed; +} + +/* + Returns an hexadecimal rendering of a block of memory. +*/ +static QString hexed( const char *data, int length ) +{ + QString t; + for ( int i = 0; i < length; i++ ) { + QString x; + x.sprintf( "%.2x", (uchar) data[i] ); + t += x; + } + return t; +} + +static bool isTrue( const QString& val ) +{ + return val.lower() == QString( "true" ); +} + +static AttributeMap attribute( const QString& name, const QString& val ) +{ + AttributeMap attr; + attr.insert( name, val ); + return attr; +} + +static QString entitize( const QString& str ) +{ + QString t = str; + t.replace( '&', QString("&") ); + t.replace( '>', QString(">") ); + t.replace( '<', QString("<") ); + t.replace( '"', QString(""") ); + t.replace( '\'', QString("'") ); + return t; +} + +Glade2Ui::Glade2Ui() +{ + int i = 0; + while ( classNames[i].gtkName != 0 ) { + yyClassNameMap.insert( QString(classNames[i].gtkName), + QString(classNames[i].qtName) ); + i++; + } + + i = 0; + while ( stockMenuItems[i].name != 0 ) { + yyStockMap.insert( QString(stockMenuItems[i].name), + QString(stockMenuItems[i].menuText) ); + i++; + } + + i = 0; + while ( keys[i].gtkName != 0 ) { + yyKeyMap.insert( QString(keys[i].gtkName), keys[i].qtValue ); + i++; + } +} + +QString Glade2Ui::imageName( const QString& fileName ) +{ + return *yyImages.insert( fileName, QString("image%1").arg(yyImages.count()), + FALSE ); +} + +QString Glade2Ui::opening( const QString& tag, const AttributeMap& attr ) +{ + QString t = QChar( '<' ) + tag; + AttributeMap::ConstIterator a = attr.begin(); + while ( a != attr.end() ) { + t += QChar( ' ' ) + a.key() + QString( "=\"" ) + entitize( *a ) + + QChar( '"' ); + ++a; + } + t += QChar( '>' ); + return t; +} + +QString Glade2Ui::closing( const QString& tag ) +{ + return opening( QChar('/') + tag ); +} + +QString Glade2Ui::atom( const QString& tag, const AttributeMap& attr ) +{ + QString t = opening( tag, attr ); + t.insert( t.length() - 1, QChar('/') ); + return t; +} + +void Glade2Ui::error( const QString& message ) +{ + if ( numErrors++ == 0 ) + QMessageBox::warning( 0, yyFileName, message ); +} + +void Glade2Ui::syntaxError() +{ + error( QString("Sorry, I met a random syntax error. I did what I could, but" + " that was not enough." + "

    You might want to write to" + " qt-bugs@trolltech.com about this incident.") ); +} + +QString Glade2Ui::getTextValue( const QDomNode& node ) +{ + if ( node.childNodes().count() > 1 ) { + syntaxError(); + return QString::null; + } + + if ( node.childNodes().count() == 0 ) + return QString::null; + + QDomText t = node.firstChild().toText(); + if ( t.isNull() ) { + syntaxError(); + return QString::null; + } + return t.data().stripWhiteSpace(); +} + +void Glade2Ui::emitHeader() +{ + yyOut += QString( "\n" ); +} + +void Glade2Ui::emitFooter() +{ + yyOut += QString( "\n" ); +} + +void Glade2Ui::emitSimpleValue( const QString& tag, const QString& value, + const AttributeMap& attr ) +{ + yyOut += yyIndentStr + opening( tag, attr ) + entitize( value ) + + closing( tag ) + QChar( '\n' ); +} + +void Glade2Ui::emitOpening( const QString& tag, const AttributeMap& attr ) +{ + yyOut += yyIndentStr + opening( tag, attr ) + QChar( '\n' ); + yyIndentStr += QString( " " ); +} + +void Glade2Ui::emitClosing( const QString& tag ) +{ + yyIndentStr.truncate( yyIndentStr.length() - 4 ); + yyOut += yyIndentStr + closing( tag ) + QChar( '\n' ); +} + +void Glade2Ui::emitAtom( const QString& tag, const AttributeMap& attr ) +{ + yyOut += yyIndentStr + atom( tag, attr ) + QChar( '\n' ); +} + +void Glade2Ui::emitVariant( const QVariant& val, const QString& stringType ) +{ + if ( val.isValid() ) { + switch ( val.type() ) { + case QVariant::String: + emitSimpleValue( stringType, val.toString() ); + break; + case QVariant::CString: + emitSimpleValue( QString("cstring"), val.toString() ); + break; + case QVariant::Bool: + emitSimpleValue( QString("bool"), + QString(val.toBool() ? "true" : "false") ); + break; + case QVariant::Int: + case QVariant::UInt: + emitSimpleValue( QString("number"), val.toString() ); + break; + case QVariant::Rect: + emitOpening( QString("rect") ); + emitSimpleValue( QString("x"), QString::number(val.toRect().x()) ); + emitSimpleValue( QString("y"), QString::number(val.toRect().y()) ); + emitSimpleValue( QString("width"), + QString::number(val.toRect().width()) ); + emitSimpleValue( QString("height"), + QString::number(val.toRect().height()) ); + emitClosing( QString("rect") ); + break; + case QVariant::Size: + emitOpening( QString("size") ); + emitSimpleValue( QString("width"), + QString::number(val.toSize().width()) ); + emitSimpleValue( QString("height"), + QString::number(val.toSize().height()) ); + emitClosing( QString("size") ); + break; + case QVariant::SizePolicy: + emitOpening( QString("sizepolicy") ); + emitSimpleValue( QString("hsizetype"), + QString::number((int) val.toSizePolicy() + .horData()) ); + emitSimpleValue( QString("vsizetype"), + QString::number((int) val.toSizePolicy() + .verData()) ); + emitClosing( QString("sizepolicy") ); + break; + default: + emitSimpleValue( QString("fnord"), QString::null ); + } + } +} + +void Glade2Ui::emitProperty( const QString& prop, const QVariant& val, + const QString& stringType ) +{ + emitOpening( QString("property"), attribute(QString("name"), prop) ); + emitVariant( val, stringType ); + emitClosing( QString("property") ); +} + +void Glade2Ui::emitFontProperty( const QString& prop, int pointSize, bool bold ) +{ + emitOpening( QString("property"), attribute(QString("name"), prop) ); + emitOpening( QString("font") ); + emitSimpleValue( QString("pointsize"), QString::number(pointSize) ); + if ( bold ) + emitSimpleValue( QString("bold"), QString("1") ); + emitClosing( QString("font") ); + emitClosing( QString("property") ); +} + +void Glade2Ui::emitAttribute( const QString& prop, const QVariant& val, + const QString& stringType ) +{ + emitOpening( QString("attribute"), attribute(QString("name"), prop) ); + emitVariant( val, stringType ); + emitClosing( QString("attribute") ); +} + +static QString accelerate( const QString& gtkLabel ) +{ + QString qtLabel = gtkLabel; + qtLabel.replace( '&', QString("&&") ); + // close but not quite right + qtLabel.replace( QChar('_'), QChar('&') ); + return qtLabel; +} + +static QString decelerate( const QString& gtkLabel ) +{ + QString qtLabel = gtkLabel; + // ditto + qtLabel.replace( '_', QString::null ); + return qtLabel; +} + +/* + Converting a GTK widget to a corresponding Qt widget is sometimes + hard. For example, a GtkScrolledWindow should sometimes be converted + into a QTextView, a QTextEdit, a QListView or whatever. What we do + is pretty hackish, but it mostly works. +*/ +QString Glade2Ui::gtk2qtClass( const QString& gtkClass, + const QValueList& childWidgets ) +{ + QRegExp gnomeXEntry( QString("Gnome(File|Number|Pixmap)?Entry") ); + + QString qtClass; + + if ( gtkClass == QString("GtkScrolledWindow") ) { + if ( childWidgets.count() == 1 ) { + QString g; + bool editable = FALSE; + bool showTitles = TRUE; + + QDomNode n = childWidgets.first().firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("class") ) { + g = getTextValue( n ); + } else if ( tagName == QString("editable") ) { + editable = isTrue( getTextValue(n) ); + } else if ( tagName.startsWith(QString("show_tit")) ) { + showTitles = isTrue( getTextValue(n) ); + } + n = n.nextSibling(); + } + + if ( g == QString("GnomeCanvas") || + g == QString("GtkDrawingArea") ) { + qtClass = QString( "QLabel" ); + } else if ( g == QString("GnomeIconList") ) { + qtClass = QString( "QIconView" ); + } else if ( g == QString("GtkCList") ) { + if ( showTitles ) + qtClass = QString( "QListView" ); + else + qtClass = QString( "QListBox" ); + } else if ( g == QString("GtkCTree") ) { + qtClass = QString( "QListView" ); + } else if ( g == QString("GtkList") ) { + qtClass = QString( "QListBox" ); + } else if ( g == QString("GtkText") ) { + if ( editable ) + qtClass = QString( "QTextEdit" ); + else + qtClass = QString( "QTextView" ); + } else if ( g == QString("GtkTree") ) { + qtClass = QString( "QListView" ); + } + // else too bad (qtClass is empty) + } + } else if ( gtkClass == QString("GtkWindow") ) { + qtClass = QString( "QDialog" ); + if ( childWidgets.count() == 1 ) { + QString g; + + QDomNode n = childWidgets.first().firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("class") ) + g = getTextValue( n ); + n = n.nextSibling(); + } + if ( g == QString("GnomeDruid") ) + qtClass = QString( "QWizard" ); + } + /* + GnomeEntry and friends are a wrapper around a GtkEntry. We only + want the GtkEntry child. + */ + } else if ( !gnomeXEntry.exactMatch(gtkClass) && + gtkClass != QString("GtkAlignment") && + gtkClass != QString("GtkEventBox") ) { + qtClass = yyClassNameMap[gtkClass]; + if ( qtClass.isEmpty() ) + qtClass = QString( "Unknown" ); + } + return qtClass; +} + +static QString gtk2qtScrollBarMode( const QString& scrollbarPolicy ) +{ + if ( scrollbarPolicy.endsWith(QString("_NEVER")) ) { + return QString( "AlwaysOff" ); + } else if ( scrollbarPolicy.endsWith(QString("_ALWAYS")) ) { + return QString( "AlwaysOn" ); + } else { + return QString( "Auto" ); + } +} + +static QString gtk2qtSelectionMode( const QString& selectionMode ) +{ + if ( selectionMode.endsWith(QString("_MULTIPLE")) ) + return QString( "Multi" ); + else if ( selectionMode.endsWith(QString("_EXTENDED")) ) + return QString( "Extended" ); + else + return QString( "Single" ); +} + +int Glade2Ui::matchAccelOnActivate( const QDomElement& accel ) +{ + QString key; + QString modifiers; + + QDomNode n = accel.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("key") ) { + key = getTextValue( n ); + if ( !key.startsWith(QString("GDK_")) ) + return 0; + } else if ( tagName == QString("modifiers") ) { + modifiers = getTextValue( n ); + } else if ( tagName == QString("signal") ) { + if ( getTextValue(n) != QString("activate") ) + return 0; + } + n = n.nextSibling(); + } + + int flags = 0; + + if ( key.length() == 5 ) { + flags = key[4].upper().latin1(); + } else if ( yyKeyMap.contains(key.mid(4)) ) { + flags = yyKeyMap[key.mid(4)]; + } else { + return 0; + } + + if ( modifiers.contains(QString("_CONTROL_")) ) + flags |= Qt::CTRL; + if ( modifiers.contains(QString("_SHIFT_")) ) + flags |= Qt::SHIFT; + if ( modifiers.contains(QString("_MOD1_")) ) + flags |= Qt::ALT; + return flags; +} + +void Glade2Ui::emitGtkMenu( const QDomElement& menu ) +{ + QRegExp gnomeuiinfoMenuXItem( QString("GNOMEUIINFO_MENU_(.+)_ITEM") ); + + QDomNode n = menu.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("widget") ) { + QString activateHandler; + QString gtkClass; + QString icon; + QString label; + QString name; + QString stockItem; + QString tooltip; + int qtAccel = 0; + + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + QString childTagName = child.toElement().tagName(); + if ( childTagName == QString("accelerator") ) { + qtAccel = matchAccelOnActivate( child.toElement() ); + } else if ( childTagName == QString("class") ) { + gtkClass = getTextValue( child ); + } else if ( childTagName == QString("icon") ) { + icon = getTextValue( child ); + } else if ( childTagName == QString("label") ) { + label = getTextValue( child ); + } else if ( childTagName == QString("name") ) { + name = getTextValue( child ); + } else if ( childTagName == QString("signal") ) { + QString signalName; + QString signalHandler; + + QDomNode grandchild = child.firstChild(); + while ( !grandchild.isNull() ) { + QString grandchildTagName = + grandchild.toElement().tagName(); + if ( grandchildTagName == QString("handler") ) { + signalHandler = getTextValue( grandchild ); + } else if ( grandchildTagName == QString("name") ) { + signalName = getTextValue( grandchild ); + } + grandchild = grandchild.nextSibling(); + } + if ( signalName == QString("activate") ) + activateHandler = signalHandler; + } else if ( childTagName == QString("stock_item") ) { + stockItem = getTextValue( child ); + } else if ( childTagName == QString("tooltip") ) { + tooltip = getTextValue( child ); + } + child = child.nextSibling(); + } + + if ( label.length() + stockItem.length() == 0 ) { + emitAtom( QString("separator") ); + } else { + if ( name.isEmpty() ) + name = QString( "action%1" ).arg( uniqueAction++ ); + emitAtom( QString("action"), attribute(QString("name"), name) ); + + if ( !activateHandler.isEmpty() ) { + QString slot = activateHandler + QString( "()" ); + GladeConnection c; + c.sender = name; + c.signal = QString( "activated()" ); + c.slot = slot; + yyConnections.push_back( c ); + yySlots.insert( slot, QString("public") ); + } + + QString x; + GladeAction a; + + if ( gnomeuiinfoMenuXItem.exactMatch(stockItem) ) { + x = gnomeuiinfoMenuXItem.cap( 1 ); + a.menuText = yyStockMap[x]; + if ( x == QString("EXIT") && qtAccel == 0 ) + qtAccel = Qt::CTRL + Qt::Key_Q; + } else { + a.menuText = accelerate( label ); + } + a.text = nonMenuText( a.menuText ); + a.toolTip = tooltip; + a.accel = qtAccel; + a.iconSet = icon; + yyActions.insert( name, a ); + if ( !x.isEmpty() ) + yyStockItemActions.insert( x, name ); + } + } + n = n.nextSibling(); + } +} + +void Glade2Ui::emitGtkMenuBarChildWidgets( + const QValueList& childWidgets ) +{ + QRegExp gnomeuiinfoMenuXTree( QString("GNOMEUIINFO_MENU_(.+)_TREE") ); + + emitOpening( QString("menubar") ); + emitProperty( QString("name"), + QString("MenuBar%1").arg(uniqueMenuBar++).latin1() ); + + QValueList::ConstIterator c = childWidgets.begin(); + while ( c != childWidgets.end() ) { + QValueList grandchildWidgets; + QString gtkClass; + QString label; + QString name; + QString stockItem; + + QDomNode n = (*c).firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("class") ) { + gtkClass = getTextValue( n ); + } else if ( tagName == QString("label") ) { + label = getTextValue( n ); + } else if ( tagName == QString("name") ) { + name = getTextValue( n ); + } else if ( tagName == QString("stock_item") ) { + stockItem = getTextValue( n ); + } else if ( tagName == QString("widget") ) { + grandchildWidgets.push_back( n.toElement() ); + } + n = n.nextSibling(); + } + + if ( gtkClass == QString("GtkMenuItem") && + grandchildWidgets.count() == 1 ) { + QString text; + if ( gnomeuiinfoMenuXTree.exactMatch(stockItem) ) { + text = gnomeuiinfoMenuXTree.cap( 1 ); + if ( text == QString("Files") ) + text = QString( "Fi&les" ); + else + text = QChar( '&' ) + text.left( 1 ) + + text.mid( 1 ).lower(); + } else { + text = accelerate( label ); + } + + AttributeMap attr; + attr.insert( QString("name"), name ); + attr.insert( QString("text"), text ); + + emitOpening( QString("item"), attr ); + emitGtkMenu( grandchildWidgets.first() ); + emitClosing( QString("item") ); + } + ++c; + } + emitClosing( QString("menubar") ); +} + +void Glade2Ui::emitGtkToolbarChildWidgets( + const QValueList& childWidgets ) +{ + QRegExp gnomeStockPixmapX( QString("GNOME_STOCK_PIXMAP_(.+)") ); + + emitOpening( QString("toolbar"), attribute(QString("dock"), QString("2")) ); + emitProperty( QString("name"), + QString("ToolBar%1").arg(uniqueToolBar++).latin1() ); + + QValueList::ConstIterator c = childWidgets.begin(); + while ( c != childWidgets.end() ) { + QString childName; + QString icon; + QString label; + QString name; + QString stockPixmap; + QString tooltip; + + QDomNode n = (*c).firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("child_name") ) { + childName = getTextValue( n ); + } else if ( tagName == QString("icon") ) { + icon = getTextValue( n ); + } else if ( tagName == QString("label") ) { + label = getTextValue( n ); + } else if ( tagName == QString("name") ) { + name = getTextValue( n ); + } else if ( tagName == QString("stock_pixmap") ) { + stockPixmap = getTextValue( n ); + } else if ( tagName == QString("tooltip") ) { + tooltip = getTextValue( n ); + } + n = n.nextSibling(); + } + + if ( childName == QString("Toolbar:button") ) { + QString actionName; + GladeAction a; + a.menuText = label; + a.text = label; + a.accel = 0; + a.iconSet = icon; + + if ( gnomeStockPixmapX.exactMatch(stockPixmap) ) { + QString x = gnomeStockPixmapX.cap( 1 ); + actionName = yyStockItemActions[x]; + } + if ( actionName.isEmpty() ) { + if ( name.isEmpty() ) + actionName = QString( "action%1" ).arg( uniqueAction++ ); + else + actionName = QString( "action_%1" ).arg( name ); + yyActions.insert( actionName, a ); + } + if ( !tooltip.isEmpty() ) + yyActions[actionName].toolTip = tooltip; + + emitAtom( QString("action"), attribute(QString("name"), + actionName) ); + } else { + emitAtom( QString("separator") ); + } + ++c; + } + emitClosing( QString("toolbar") ); +} + +void Glade2Ui::emitPushButton( const QString& text, const QString& name ) +{ + emitOpening( QString("widget"), + attribute(QString("class"), QString("QPushButton")) ); + emitProperty( QString("name"), name.latin1() ); + emitProperty( QString("text"), text ); + if ( name.contains(QString("ok")) > 0 ) { + emitProperty( QString("default"), QVariant(TRUE, 0) ); + } else if ( name.contains(QString("help")) > 0 ) { + emitProperty( QString("accel"), (int) Qt::Key_F1 ); + } + emitClosing( QString("widget") ); +} + +void Glade2Ui::attach( AttributeMap *attr, int leftAttach, int rightAttach, + int topAttach, int bottomAttach ) +{ + if ( leftAttach >= 0 ) { + attr->insert( QString("row"), QString::number(topAttach) ); + attr->insert( QString("column"), QString::number(leftAttach) ); + if ( bottomAttach - topAttach != 1 ) + attr->insert( QString("rowspan"), + QString::number(bottomAttach - topAttach) ); + if ( rightAttach - leftAttach != 1 ) + attr->insert( QString("colspan"), + QString::number(rightAttach - leftAttach) ); + } +} + +void Glade2Ui::emitSpacer( const QString& orientation, int leftAttach, + int rightAttach, int topAttach, int bottomAttach ) +{ + AttributeMap attr; + attach( &attr, leftAttach, rightAttach, topAttach, bottomAttach ); + emitOpening( QString("spacer"), attr ); + emitProperty( QString("name"), + QString("Spacer%1").arg(uniqueSpacer++).latin1() ); + emitProperty( QString("orientation"), orientation, QString("enum") ); + emitProperty( QString("sizeType"), QString("Expanding"), + QString("enum") ); + emitClosing( QString("spacer") ); +} + +void Glade2Ui::emitPixmap( const QString& imageName, int leftAttach, + int rightAttach, int topAttach, int bottomAttach ) +{ + emitOpeningWidget( QString("QLabel"), leftAttach, rightAttach, topAttach, + bottomAttach ); + emitProperty( QString("sizePolicy"), + QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) ); + emitProperty( QString("pixmap"), imageName, QString("pixmap") ); + emitClosing( QString("widget") ); +} + +void Glade2Ui::emitGnomeAbout( QString copyright, QString authors, + QString comments ) +{ + QString prog = yyProgramName; + if ( prog.isEmpty() ) + prog = QString( "Gnomovision 1.69" ); + if ( copyright.isEmpty() ) + copyright = QString( "(C) 2001 Jasmin Blanchette" ); + if ( authors.isEmpty() ) + authors = QString( "Jasmin Blanchette " ); + if ( comments.isEmpty() ) + comments = QString( "Gnomovision is the official GNU application." ); + + emitOpening( QString("hbox") ); + emitSpacer( QString("Horizontal") ); + emitOpeningWidget( QString("QLayoutWidget") ); + emitOpening( QString("vbox") ); + emitProperty( QString("spacing"), 17 ); + + /* + Emit the application name. + */ + emitOpeningWidget( QString("QLabel") ); + emitFontProperty( QString("font"), 24, TRUE ); + emitProperty( QString("text"), prog ); + emitProperty( QString("alignment"), QString("AlignAuto|AlignCenter"), + QString("set") ); + emitClosing( QString("widget") ); + + /* + Emit the copyright notice. + */ + emitOpeningWidget( QString("QLabel") ); + emitFontProperty( QString("font"), 12, TRUE ); + emitProperty( QString("text"), copyright ); + emitClosing( QString("widget") ); + + /* + Emit the authors' names. + */ + emitOpeningWidget( QString("QLayoutWidget") ); + emitOpening( QString("hbox") ); + + emitOpeningWidget( QString("QLabel") ); + emitFontProperty( QString("font"), 12, TRUE ); + emitProperty( QString("text"), QString("Authors:") ); + emitProperty( QString("alignment"), QString("AlignAuto|AlignTop"), + QString("set") ); + emitClosing( QString("widget") ); + + emitOpeningWidget( QString("QLabel") ); + emitFontProperty( QString("font"), 12, FALSE ); + emitProperty( QString("text"), authors ); + emitProperty( QString("alignment"), QString("AlignAuto|AlignTop"), + QString("set") ); + emitClosing( QString("widget") ); + + emitSpacer( QString("Horizontal") ); + + emitClosing( QString("hbox") ); + emitClosing( QString("widget") ); + + /* + Emit the comments. + */ + emitOpeningWidget( QString("QLabel") ); + emitFontProperty( QString("font"), 10, FALSE ); + emitProperty( QString("text"), comments ); + emitProperty( QString("alignment"), QString("AlignAuto|AlignTop"), + QString("set") ); + emitClosing( QString("widget") ); + + /* + Emit the spacer and the OK button. + */ + emitSpacer( QString("Vertical") ); + + emitOpeningWidget( QString("QLayoutWidget") ); + emitOpening( QString("hbox") ); + emitSpacer( QString("Horizontal") ); + + emitPushButton( QString("&OK"), QString("okButton") ); + + emitSpacer( QString("Horizontal") ); + emitClosing( QString("hbox") ); + emitClosing( QString("widget") ); + + emitClosing( QString("vbox") ); + emitClosing( QString("widget") ); + emitSpacer( QString("Horizontal") ); + emitClosing( QString("hbox") ); +} + +/* + GnomeApps are emitted in two passes, because some information goes + into the section, whereas other information goes into the + section. +*/ +void Glade2Ui::emitGnomeAppChildWidgetsPass1( + const QValueList& childWidgets ) +{ + QValueList::ConstIterator c = childWidgets.begin(); + while ( c != childWidgets.end() ) { + QValueList grandchildWidgets; + QString childName; + + QDomNode n = (*c).firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("child_name") ) { + childName = getTextValue( n ); + } else if ( tagName == QString("widget") ) { + grandchildWidgets.push_back( n.toElement() ); + } + n = n.nextSibling(); + } + + if ( childName == QString("GnomeDock:contents") ) { + emitWidget( *c, FALSE ); + } else { + emitGnomeAppChildWidgetsPass1( grandchildWidgets ); + } + ++c; + } +} + +void Glade2Ui::doPass2( const QValueList& childWidgets, + QValueList *menuBar, + QValueList > *toolBars ) +{ + QValueList::ConstIterator c = childWidgets.begin(); + while ( c != childWidgets.end() ) { + QValueList grandchildWidgets; + QString childName; + QString gtkClass; + + QDomNode n = (*c).firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("child_name") ) { + childName = getTextValue( n ); + } else if ( tagName == QString("class") ) { + gtkClass = getTextValue( n ); + } else if ( tagName == QString("widget") ) { + grandchildWidgets.push_back( n.toElement() ); + } + n = n.nextSibling(); + } + + if ( gtkClass == QString("GtkMenuBar") ) { + *menuBar = grandchildWidgets; + } else if ( gtkClass == QString("GtkToolbar") ) { + toolBars->push_back( grandchildWidgets ); + } else if ( childName != QString("GnomeDock:contents") ) { + doPass2( grandchildWidgets, menuBar, toolBars ); + } + ++c; + } +} + +void Glade2Ui::emitGnomeAppChildWidgetsPass2( + const QValueList& childWidgets ) +{ + QValueList menuBar; + QValueList > toolBars; + + doPass2( childWidgets, &menuBar, &toolBars ); + + emitGtkMenuBarChildWidgets( menuBar ); + if ( !toolBars.isEmpty() ) { + emitOpening( QString("toolbars") ); + while ( !toolBars.isEmpty() ) { + emitGtkToolbarChildWidgets( toolBars.first() ); + toolBars.remove( toolBars.begin() ); + } + emitClosing( QString("toolbars") ); + } +} + +void Glade2Ui::emitGtkButtonChildWidgets( QValueList childWidgets ) +{ + QValueList::ConstIterator c = childWidgets.begin(); + while ( c != childWidgets.end() ) { + QString label; + + QDomNode n = (*c).firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("label") ) { + label = getTextValue( n ); + } else if ( tagName == QString("widget") ) { + childWidgets.push_back( n.toElement() ); + } + n = n.nextSibling(); + } + + if ( !label.isEmpty() ) { + emitProperty( QString("text"), accelerate(label) ); + break; + } + ++c; + } +} + +void Glade2Ui::emitGtkComboChildWidgets( + const QValueList& childWidgets, const QStringList& items ) +{ + QString text; + + // there should be exactly one child, of type GtkEntry + if ( childWidgets.count() == 1 ) { + QDomNode n = childWidgets.first().firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("name") ) { + // grep 'elsewhere' + emitProperty( QString("name"), + fixedName(getTextValue(n).latin1()) ); + } else if ( tagName == QString("text") ) { + text = getTextValue( n ); + } + n = n.nextSibling(); + } + } + + int n = 0; + QStringList::ConstIterator s = items.begin(); + while ( s != items.end() ) { + if ( !text.isEmpty() && *s == text ) + emitProperty( QString("currentItem"), n ); + n++; + ++s; + } + +} + +void Glade2Ui::emitGtkNotebookChildWidgets( + const QValueList& childWidgets ) +{ + QStringList tabNames; + QStringList tabLabels; + + for ( int i = 0; i < (int) childWidgets.count(); i++ ) { + tabNames.push_back( QString("tab%1").arg(i + 1) ); + tabLabels.push_back( QString("Tab %1").arg(i + 1) ); + } + + QValueList::ConstIterator c; + c = childWidgets.begin(); + + QStringList::Iterator nam = tabNames.begin(); + QStringList::Iterator lab = tabLabels.begin(); + + while ( c != childWidgets.end() ) { + QString childName; + QString name; + QString label; + + QDomNode n = (*c).firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("child_name") ) { + childName = getTextValue( n ); + } else if ( tagName == QString("name") ) { + name = getTextValue( n ); + } else if ( tagName == QString("label") ) { + label = getTextValue( n ); + } + n = n.nextSibling(); + } + + if ( childName == QString("Notebook:tab") ) { + if ( !name.isEmpty() ) + *nam = name; + if ( !label.isEmpty() ) + *lab = label; + ++nam; + ++lab; + } + ++c; + } + + c = childWidgets.begin(); + while ( c != childWidgets.end() ) { + QString childName; + QString name; + QString label; + + QDomNode n = (*c).firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("child_name") ) + childName = getTextValue( n ); + n = n.nextSibling(); + } + + if ( childName != QString("Notebook:tab") ) { + emitOpeningWidget( QString("QWidget") ); + emitProperty( QString("name"), tabNames.first().latin1() ); + tabNames.remove( tabNames.begin() ); + emitAttribute( QString("title"), accelerate(tabLabels.first()) ); + tabLabels.remove( tabLabels.begin() ); + emitWidget( *c, FALSE ); + emitClosing( QString("widget") ); + } + ++c; + } +} + +void Glade2Ui::emitQListViewColumns( const QDomElement& qlistview ) +{ + QDomNode n = qlistview.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("widget") ) { + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + QString tagName = child.toElement().tagName(); + if ( tagName == QString("label") ) { + emitOpening( QString("column") ); + emitProperty( QString("text"), + decelerate(getTextValue(child)) ); + emitClosing( QString("column") ); + } + child = child.nextSibling(); + } + } else if ( tagName == QString("class") ) { + QString gtkClass = getTextValue( n ); + if ( gtkClass.endsWith(QString("Tree")) ) + emitProperty( QString("rootIsDecorated"), QVariant(TRUE, 0) ); + } else if ( tagName == QString("selection_mode") ) { + emitProperty( QString("selectionMode"), + gtk2qtSelectionMode(getTextValue(n)) ); + } + n = n.nextSibling(); + } +} + +void Glade2Ui::emitGtkScrolledWindowChildWidgets( + const QValueList& childWidgets, const QString& qtClass ) +{ + if ( childWidgets.count() == 1 ) { + if ( qtClass == QString("QIconView") || + qtClass == QString("QListBox") || + qtClass == QString("QListView") ) { + QDomNode n = childWidgets.first().firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("selection_mode") ) { + emitProperty( QString("selectionMode"), + gtk2qtSelectionMode(getTextValue(n)) ); + } + n = n.nextSibling(); + } + } + + if ( qtClass == QString("QListView") ) { + emitQListViewColumns( childWidgets.first() ); + } else if ( qtClass == QString("QTextEdit") || + qtClass == QString("QTextView") ) { + QDomNode n = childWidgets.first().firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("text") ) + emitProperty( QString("text"), getTextValue(n) ); + n = n.nextSibling(); + } + } + } +} + +void Glade2Ui::emitGnomeDruidPage( const QDomElement& druidPage ) +{ + QValueList childWidgets; + QString gtkClass; + QString logoImage; + QString name; + QString text; + QString title; + QString watermarkImage; + + emitOpeningWidget( QString("QWidget") ); + + QDomNode n = druidPage.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("class") ) { + gtkClass = getTextValue( n ); + } else if ( tagName == QString("logo_image") ) { + logoImage = getTextValue( n ); + } else if ( tagName == QString("name") ) { + name = getTextValue( n ); + } else if ( tagName == QString("text") ) { + text = getTextValue( n ); + } else if ( tagName == QString("title") ) { + title = getTextValue( n ); + } else if ( tagName == QString("watermark_image") ) { + watermarkImage = getTextValue( n ); + } else if ( tagName == QString("widget") ) { + childWidgets.push_back( n.toElement() ); + } + n = n.nextSibling(); + } + + if ( !name.isEmpty() ) + emitProperty( QString("name"), fixedName(name).latin1() ); + if ( title.isEmpty() ) + title = QString( "Page" ); + emitAttribute( QString("title"), title ); + + /* + We're striving to get the logoImage and/or the watermarkImage at + the right places with a grid layout. + */ + int leftAttach = 0; + int rightAttach = 0; + int topAttach = 0; + int bottomAttach = 0; + + int numImages = 0; + if ( !logoImage.isEmpty() ) { + topAttach = 1; + numImages++; + } + if ( !watermarkImage.isEmpty() ) { + leftAttach = 1; + numImages++; + } + rightAttach = leftAttach + numImages; + bottomAttach = topAttach + numImages; + + bool layouted = ( numImages > 0 ); + if ( layouted ) { + emitOpening( QString("grid") ); + if ( !logoImage.isEmpty() ) + emitPixmap( imageName(logoImage), numImages, numImages + 1, 0, 1 ); + if ( !watermarkImage.isEmpty() ) + emitPixmap( imageName(watermarkImage), 0, 1, numImages, + numImages + 1 ); + } else { + leftAttach = -1; + rightAttach = -1; + topAttach = -1; + bottomAttach = -1; + } + + if ( gtkClass.endsWith(QString("Standard")) ) { + emitChildWidgets( childWidgets, layouted, leftAttach, rightAttach, + topAttach, bottomAttach ); + } else if ( !text.isEmpty() ) { + if ( layouted ) + emitOpeningWidget( QString("QLayoutWidget"), leftAttach, + rightAttach, topAttach, bottomAttach ); + emitOpening( QString("hbox") ); + emitSpacer( QString("Horizontal") ); + emitOpeningWidget( QString("QLabel") ); + emitProperty( QString("text"), text ); + emitClosing( QString("widget") ); + emitSpacer( QString("Horizontal") ); + emitClosing( QString("hbox") ); + if ( layouted ) + emitClosing( QString("widget") ); + } + + if ( layouted ) + emitClosing( QString("grid") ); + emitClosing( QString("widget") ); +} + +void Glade2Ui::emitGtkWindowChildWidgets( + const QValueList& childWidgets, const QString& qtClass ) +{ + if ( childWidgets.count() == 1 && qtClass == QString("QWizard") ) { + emitFontProperty( QString("titleFont"), 18, FALSE ); + + QDomNode n = childWidgets.first().firstChild(); + while ( !n.isNull() ) { + if ( n.toElement().tagName() == QString("widget") ) + emitGnomeDruidPage( n.toElement() ); + n = n.nextSibling(); + } + } else { + emitChildWidgets( childWidgets, FALSE ); + } +} + +bool Glade2Ui::packEnd( const QDomElement& widget ) +{ + QDomNode n = widget.firstChild(); + while ( !n.isNull() ) { + if ( n.toElement().tagName() == QString("child") ) { + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == QString("pack") ) { + QString pack = getTextValue( child ); + return pack.endsWith( QString("_END") ); + } + child = child.nextSibling(); + } + } + n = n.nextSibling(); + } + return FALSE; +} + +void Glade2Ui::emitChildWidgets( const QValueList& childWidgets, + bool layouted, int leftAttach, int rightAttach, + int topAttach, int bottomAttach ) +{ + QValueList start; + QValueList end; + QValueList::ConstIterator e; + + if ( layouted ) { + e = childWidgets.begin(); + while ( e != childWidgets.end() ) { + if ( packEnd(*e) ) + end.push_front( *e ); + else + start.push_back( *e ); + ++e; + } + } else { + start = childWidgets; + } + + e = start.begin(); + while ( e != start.end() ) { + emitWidget( *e, layouted, leftAttach, rightAttach, topAttach, + bottomAttach ); + ++e; + } + e = end.begin(); + while ( e != end.end() ) { + emitWidget( *e, layouted, leftAttach, rightAttach, topAttach, + bottomAttach ); + ++e; + } +} + +void Glade2Ui::emitOpeningWidget( const QString& qtClass, int leftAttach, + int rightAttach, int topAttach, + int bottomAttach ) +{ + AttributeMap attr = attribute( QString("class"), qtClass ); + attach( &attr, leftAttach, rightAttach, topAttach, bottomAttach ); + emitOpening( QString("widget"), attr ); +} + +/* + Returns TRUE if the vbox containing childWidgets should have a + spacer at the end to prevent it from looking bad, otherwise returns + FALSE. + + The algorithm is very experimental. +*/ +bool Glade2Ui::shouldPullup( const QValueList& childWidgets ) +{ + QRegExp gtkSmallWidget( QString( + "G.*(?:Button|Combo|Dial|Entry|Label|OptionMenu|Picker|ProgressBar" + "|Separator|Statusbar|Toolbar|VBox)") ); + + QValueList::ConstIterator c = childWidgets.begin(); + while ( c != childWidgets.end() ) { + QValueList grandchildWidgets; + QString gtkClass; + + QDomNode n = (*c).firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( tagName == QString("class") ) { + gtkClass = getTextValue( n ); + } else if ( tagName == QString("widget") ) { + grandchildWidgets.push_back( n.toElement() ); + } + n = n.nextSibling(); + } + + if ( !gtkSmallWidget.exactMatch(gtkClass) || + !shouldPullup(grandchildWidgets) ) + return FALSE; + ++c; + } + return TRUE; +} + +QString Glade2Ui::emitWidget( const QDomElement& widget, bool layouted, + int leftAttach, int rightAttach, int topAttach, + int bottomAttach ) +{ + QRegExp gtkLayoutWidget( QString( + "Gtk(?:Packer|Table|Toolbar|[HV](?:(?:Button)?Box))") ); + QRegExp gtkOrientedWidget( QString( + "Gtk([HV])(?:Paned|Scale|Scrollbar|Separator)") ); + + QValueList childWidgets; + QString gtkClass; + QString name; + QString title; + int x = 0; + int y = 0; + int width = 0; + int height = 0; + int numRows = 0; + int numColumns = 0; + + bool active = FALSE; + QString authors; + QString childName; + QString comments; + QString copyright; + QString creationFunction; + bool editable = TRUE; + QString filename; + QString focusTarget; + QString hscrollbarPolicy; + QString icon; + int initialChoice = 0; + QStringList items; + QString justify; + QString label; + QString logoImage; + int lower = -123456789; + int page = 10; + int pageSize = 10; + QString selectionMode; + QString shadowType( "GTK_SHADOW_NONE" ); + bool showText = TRUE; + bool showTitles = TRUE; + int step = 1; + QString tabPos; + QString text; + int textMaxLength = 0; + bool textVisible = TRUE; + QString tooltip; + QString type; + int upper = 123456789; + int value = 123456789; + bool valueInList = TRUE; + QString vscrollbarPolicy; + QString watermarkImage; + bool wrap = FALSE; + + bool topLevel = yyFormName.isEmpty(); + if ( topLevel ) + name = QString( "Form%1" ).arg( uniqueForm++ ); + + QDomNode n = widget.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + if ( !tagName.isEmpty() ) { + /* + Recognize the properties and stores them in variables. + This step is a bit silly, and if this function were to + be rewritten, almost everything would just be stored, as + strings, in a giant map, and looked up for when emitting + the properties. + */ + switch ( (uchar) tagName[0].cell() ) { + case 'a': + if ( tagName == QString("active") ) { + active = isTrue( getTextValue(n) ); + } else if ( tagName == QString("authors") ) { + authors = getTextValue( n ); + } + break; + case 'c': + if ( tagName == QString("child") ) { + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + QString childTagName = child.toElement().tagName(); + if ( childTagName == QString("left_attach") ) { + leftAttach = getTextValue( child ).toInt(); + } else if ( childTagName == QString("right_attach") ) { + rightAttach = getTextValue( child ).toInt(); + } else if ( childTagName == QString("top_attach") ) { + topAttach = getTextValue( child ).toInt(); + } else if ( childTagName == QString("bottom_attach") ) { + bottomAttach = getTextValue( child ).toInt(); + } + child = child.nextSibling(); + } + } else if ( tagName == QString("child_name") ) { + childName = getTextValue( n ); + } else if ( tagName == QString("class") ) { + gtkClass = getTextValue( n ); + } else if ( tagName == QString("climb_rate") ) { + step = getTextValue( n ).toInt(); + } else if ( tagName == QString("columns") ) { + numColumns = getTextValue( n ).toInt(); + } else if ( tagName == QString("comments") ) { + comments = getTextValue( n ); + } else if ( tagName == QString("copyright") ) { + copyright = getTextValue( n ); + } else if ( tagName == QString("creation_function") ) { + creationFunction = getTextValue( n ); + } + break; + case 'd': + if ( tagName == QString("default_focus_target") ) { + if ( focusTarget.isEmpty() ) + focusTarget = getTextValue( n ); + } + break; + case 'e': + if ( tagName == QString("editable") ) + editable = isTrue( getTextValue(n) ); + break; + case 'f': + if ( tagName == QString("filename") ) { + filename = getTextValue( n ); + } else if ( tagName == QString("focus_target") ) { + focusTarget = getTextValue( n ); + } + break; + case 'h': + if ( tagName == QString("height") ) { + height = getTextValue( n ).toInt(); + } else if ( tagName == QString("hscrollbar_policy") ) { + hscrollbarPolicy = getTextValue( n ); + } + break; + case 'i': + if ( tagName == QString("icon") ) { + icon = getTextValue( n ); + } else if ( tagName == QString("initial_choice") ) { + initialChoice = getTextValue( n ).toInt(); + } else if ( tagName == QString("items") ) { + items = QStringList::split( QChar('\n'), getTextValue(n) ); + } + break; + case 'j': + if ( tagName == QString("justify") ) + justify = getTextValue( n ); + break; + case 'l': + if ( tagName == QString("label") ) { + label = getTextValue( n ); + } else if ( tagName == QString("logo_image") ) { + logoImage = getTextValue( n ); + } else if ( tagName == QString("lower") ) { + lower = getTextValue( n ).toInt(); + } + break; + case 'n': + if ( tagName == QString("name") ) + name = getTextValue( n ); + break; + case 'p': + if ( tagName == QString("page") ) { + page = getTextValue( n ).toInt(); + } else if ( tagName == QString("page_size") ) { + pageSize = getTextValue( n ).toInt(); + } + break; + case 'r': + if ( tagName == QString("rows") ) + numRows = getTextValue( n ).toInt(); + break; + case 's': + if ( tagName == QString("selection_mode") ) { + selectionMode = getTextValue( n ); + } else if ( tagName == QString("shadow_type") ) { + shadowType = getTextValue( n ); + } else if ( tagName == QString("show_text") ) { + showText = isTrue( getTextValue(n) ); + } else if ( tagName == QString(QString("show_titles")) ) { + showTitles = isTrue( getTextValue(n) ); + } else if ( tagName == QString("step") ) { + step = getTextValue( n ).toInt(); + } else if ( tagName == QString("stock_button") ) { + /* + Let's cheat: We convert the symbolic name into a + button label. + */ + label = getTextValue( n ); + int k = label.findRev( QChar('_') ); + if ( k != -1 ) + label = label.mid( k + 1 ); + if ( !label.isEmpty() && label != QString("OK") ) + label = label.left( 1 ) + label.mid( 1 ).lower(); + } + break; + case 't': + if ( tagName == QString("tab_pos") ) { + tabPos = getTextValue( n ); + } else if ( tagName == QString("text") ) { + text = getTextValue( n ); + } else if ( tagName == QString("textMaxLength") ) { + textMaxLength = getTextValue( n ).toInt(); + } else if ( tagName == QString("textVisible") ) { + textVisible = isTrue( getTextValue(n) ); + } else if ( tagName == QString("title") ) { + title = getTextValue( n ); + } else if ( tagName == QString("tooltip") ) { + tooltip = getTextValue( n ); + } else if ( tagName == QString("type") ) { + type = getTextValue( n ); + } + break; + case 'u': + if ( tagName == QString("upper") ) + upper = getTextValue( n ).toInt(); + break; + case 'v': + if ( tagName == QString("value") ) { + value = getTextValue( n ).toInt(); + } else if ( tagName == QString("value_in_list") ) { + valueInList = isTrue( getTextValue(n) ); + } else if ( tagName == QString("vscrollbar_policy") ) { + vscrollbarPolicy = getTextValue( n ); + } + break; + case 'w': + if ( tagName == QString("watermark_image") ) { + watermarkImage = getTextValue( n ); + } else if ( tagName == QString("widget") ) + childWidgets.push_back( n.toElement() ); + else if ( tagName == QString("width") ) + width = getTextValue( n ).toInt(); + else if ( tagName == QString("wrap") ) + wrap = isTrue( getTextValue(n) ); + break; + case 'x': + if ( tagName == QString("x") ) + x = getTextValue( n ).toInt(); + break; + case 'y': + if ( tagName == QString("y") ) + y = getTextValue( n ).toInt(); + } + } + n = n.nextSibling(); + } + + if ( topLevel ) { + yyFormName = name; + emitSimpleValue( QString("class"), yyFormName ); + } + + if ( gtkLayoutWidget.exactMatch(gtkClass) ) { + QString boxKind; + QString orientation; + + if ( gtkClass.startsWith(QString("GtkH")) || + gtkClass == QString(QString("GtkToolbar")) ) { + /* + GtkToolbar, right. Toolbars may appear anywhere in a + widget, but then they really are just a row of buttons. + */ + boxKind = QString( "hbox" ); + orientation = QString( "Horizontal" ); + } else if ( gtkClass.startsWith(QString("GtkV")) || + gtkClass == QString("GtkPacker") ) { + /* + We don't support the GtkPacker, whose trails lead to + destruction. + */ + boxKind = QString( "vbox" ); + orientation = QString( "Vertical" ); + } else { + boxKind = QString( "grid" ); + } + + if ( layouted ) + emitOpeningWidget( QString("QLayoutWidget"), leftAttach, + rightAttach, topAttach, bottomAttach ); + emitOpening( boxKind ); + emitProperty( QString("name"), fixedName(name).latin1() ); + if ( gtkClass == QString("GtkHButtonBox") || + childName == QString("Dialog:action_area") ) + emitSpacer( orientation ); + emitChildWidgets( childWidgets, TRUE ); + + if ( gtkClass == QString("GtkVButtonBox") || + childName == QString("Dialog:action_area") || + (boxKind == QString("vbox") && shouldPullup(childWidgets)) ) { + emitSpacer( orientation ); + } else if ( boxKind == QString("grid") && shouldPullup(childWidgets) ) { + emitSpacer( QString("Vertical"), 0, numColumns, numRows, + numRows + 1 ); + } + + emitClosing( boxKind ); + if ( layouted ) + emitClosing( QString("widget") ); + } else if ( gtkClass == QString("GtkFixed") && !layouted ) { + emitChildWidgets( childWidgets, FALSE ); + /* + Placeholders in a grid are typically needless. + */ + } else if ( !(leftAttach >= 0 && gtkClass == QString("Placeholder")) ) { + bool needFakeLayout = ( !layouted && !topLevel && x == 0 && y == 0 && + width == 0 && height == 0 ); + QString qtClass = gtk2qtClass( gtkClass, childWidgets ); + bool unknown = FALSE; + + if ( qtClass == QString("QFrame") && !label.isEmpty() ) { + qtClass = QString( "QButtonGroup" ); + } else if ( qtClass == QString("QListView") && !showTitles && + gtkClass.endsWith(QString("List")) ) { + qtClass = QString( "QListBox" ); + } else if ( qtClass == QString("Custom") ) { + qtClass = creationFunction; + yyCustomWidgets.insert( qtClass, QString::null ); + } else if ( qtClass == QString("Unknown") ) { + qtClass = QString( "QLabel" ); + unknown = TRUE; + } + + if ( qtClass.isEmpty() ) { + emitChildWidgets( childWidgets, layouted, leftAttach, rightAttach, + topAttach, bottomAttach ); + } else { + if ( needFakeLayout ) { + emitOpening( QString("vbox") ); + emitProperty( QString("margin"), 11 ); + } + emitOpeningWidget( qtClass, leftAttach, rightAttach, topAttach, + bottomAttach ); + + // grep 'elsewhere' + if ( gtkClass != QString("GtkCombo") ) + emitProperty( QString("name"), fixedName(name).latin1() ); + if ( !title.isEmpty() ) + emitProperty( QString("caption"), title ); + if ( !layouted && (x != 0 || y != 0 || width != 0 || height != 0) ) + emitProperty( QString("geometry"), QRect(x, y, width, height) ); + if ( gtkClass == QString("GtkToggleButton") ) { + emitProperty( QString("toggleButton"), QVariant(TRUE, 0) ); + if ( active ) + emitProperty( QString("on"), QVariant(TRUE, 0) ); + } else { + if ( active ) + emitProperty( QString("checked"), QVariant(TRUE, 0) ); + } + + if ( !editable ) + emitProperty( QString("readOnly"), QVariant(TRUE, 0) ); + if ( !focusTarget.isEmpty() ) + emitProperty( QString("buddy"), + fixedName(focusTarget).latin1() ); + if ( !hscrollbarPolicy.isEmpty() ) + emitProperty( QString("hScrollBarMode"), + gtk2qtScrollBarMode(hscrollbarPolicy), + QString("enum") ); + if ( !vscrollbarPolicy.isEmpty() ) + emitProperty( QString("vScrollBarMode"), + gtk2qtScrollBarMode(vscrollbarPolicy), + QString("enum") ); + if ( !justify.isEmpty() || + (wrap && gtkClass != QString("GtkSpinButton")) ) { + QStringList flags; + if ( wrap ) + flags.push_back( QString("WordBreak") ); + + if ( justify.endsWith(QString("_CENTER")) ) { + flags.push_back( QString("AlignCenter") ); + } else { + if ( justify.endsWith(QString("_RIGHT")) ) + flags.push_back( QString("AlignRight") ); + flags.push_back( QString("AlignVCenter") ); + } + + if ( !flags.isEmpty() ) + emitProperty( QString("alignment"), flags.join(QChar('|')), + QString("set") ); + } + if ( !label.isEmpty() ) { + if ( gtkClass.endsWith(QString("Frame")) ) { + emitProperty( QString("title"), label ); + } else { + emitProperty( QString("text"), accelerate(label) ); + } + } + if ( lower != -123456789 ) + emitProperty( QString("minValue"), lower ); + if ( upper != 123456789 ) + emitProperty( QString("maxValue"), upper ); + if ( value != 123456789 ) { + if ( gtkClass == QString("GtkProgressBar") ) { + emitProperty( QString("progress"), value ); + } else { + emitProperty( QString("value"), value ); + } + } + if ( QMAX(page, pageSize) != 10 && + gtkClass.endsWith(QString("Scrollbar")) ) + emitProperty( QString("pageStep"), QMAX(page, pageSize) ); + if ( !selectionMode.isEmpty() ) + emitProperty( QString("selectionMode"), + gtk2qtSelectionMode(selectionMode), + QString("enum") ); + if ( !shadowType.endsWith(QString("_NONE")) ) { + QString shape = shadowType.contains( QString("_ETCHED_") ) > 0 ? + QString( "Box" ) : QString( "WinPanel" ); + QString shadow = shadowType.endsWith( QString("_IN") ) ? + QString( "Sunken" ) : QString( "Raised" ); + emitProperty( QString("frameShape"), shape, QString("enum") ); + emitProperty( QString("frameShadow"), shadow, QString("enum") ); + } + if ( !showText ) + emitProperty( QString("percentageVisible"), + QVariant(FALSE, 0) ); + if ( step != 1 ) + emitProperty( QString("lineStep"), step ); + if ( tabPos.endsWith(QString("_BOTTOM")) || + tabPos.endsWith(QString("_RIGHT")) ) + emitProperty( QString("tabPosition"), QString("Bottom") ); + if ( !text.isEmpty() ) + emitProperty( QString("text"), text ); + if ( textMaxLength != 0 ) + emitProperty( QString("maxLength"), textMaxLength ); + if ( !textVisible ) + emitProperty( QString("echoMode"), QString("Password"), + QString("enum") ); + if ( !tooltip.isEmpty() ) + emitProperty( QString("toolTip"), tooltip ); + if ( !valueInList ) + emitProperty( QString("editable"), QVariant(TRUE, 0) ); + if ( wrap && gtkClass == QString("GtkSpinButton") ) + emitProperty( QString("wrapping"), QVariant(TRUE, 0) ); + + if ( gtkClass.endsWith(QString("Tree")) ) { + emitProperty( QString("rootIsDecorated"), QVariant(TRUE, 0) ); + } else if ( gtkOrientedWidget.exactMatch(gtkClass) ) { + QString s = ( gtkOrientedWidget.cap(1) == QChar('H') ) ? + QString( "Horizontal" ) : QString( "Vertical" ); + emitProperty( QString("orientation"), s, QString("enum") ); + } + + if ( qtClass == QString("QListView") ) + emitProperty( QString("resizeMode"), QString("AllColumns"), + QString("enum") ); + + while ( !items.isEmpty() ) { + emitOpening( QString("item") ); + emitProperty( QString("text"), items.first() ); + emitClosing( QString("item") ); + items.remove( items.begin() ); + } + if ( initialChoice != 0 ) + emitProperty( QString("currentItem"), initialChoice ); + + if ( !icon.isEmpty() ) + emitProperty( QString("pixmap"), imageName(icon), + QString("pixmap") ); + + if ( gtkClass == QString("GnomeAbout") ) { + emitGnomeAbout( copyright, authors, comments ); + } else if ( gtkClass == QString("GnomeApp") ) { + emitGnomeAppChildWidgetsPass1( childWidgets ); + } else if ( gtkClass == QString("GnomePropertyBox") ) { + emitOpening( QString("vbox") ); + emitChildWidgets( childWidgets, TRUE ); + emitOpeningWidget( QString("QLayoutWidget") ); + emitOpening( QString("hbox") ); + emitPushButton( QString("&Help"), QString("helpButton") ); + emitSpacer( QString("Horizontal") ); + emitPushButton( QString("&OK"), QString("okButton") ); + emitPushButton( QString("&Apply"), QString("applyButton") ); + emitPushButton( QString("&Close"), QString("closeButton") ); + emitClosing( QString("hbox") ); + emitClosing( QString("widget") ); + emitClosing( QString("vbox") ); + } else if ( gtkClass.endsWith(QString("Button")) ) { + if ( label.isEmpty() ) + emitGtkButtonChildWidgets( childWidgets ); + } else if ( gtkClass == QString("GtkCombo") ) { + emitGtkComboChildWidgets( childWidgets, items ); + } else if ( gtkClass == QString("GtkNotebook") ) { + emitGtkNotebookChildWidgets( childWidgets ); + } else if ( gtkClass == QString("GtkWindow") ) { + emitGtkWindowChildWidgets( childWidgets, qtClass ); + } else if ( gtkClass == QString("GtkScrolledWindow") ) { + emitGtkScrolledWindowChildWidgets( childWidgets, qtClass ); + } else if ( qtClass == QString("QListView") ) { + emitQListViewColumns( widget ); + } else if ( unknown || gtkClass == QString("Placeholder") ) { + QString prefix; + if ( unknown ) + prefix = gtkClass; + emitProperty( QString("text"), + QString("%1?") + .arg(prefix) ); + emitProperty( QString("alignment"), + QString("AlignAuto|AlignCenter"), + QString("set") ); + } else if ( qtClass != QString("QListBox") ) { + emitChildWidgets( childWidgets, FALSE ); + } + + emitClosing( QString("widget") ); + if ( needFakeLayout ) + emitClosing( QString("vbox") ); + if ( gtkClass == QString("GnomeApp") ) + emitGnomeAppChildWidgetsPass2( childWidgets ); + } + } + return name; +} + +QStringList Glade2Ui::convertGladeFile( const QString& fileName ) +{ + QStringList outFileNames; + + yyFileName = fileName; + + QDomDocument doc( QString("GTK-Interface") ); + QFile f( fileName ); + if ( !f.open(IO_ReadOnly) ) { + error( QString("Cannot open file for reading.") ); + return QStringList(); + } + if ( !doc.setContent(&f) ) { + error( QString("File is not an XML file.") ); + f.close(); + return QStringList(); + } + f.close(); + + QDomElement root = doc.documentElement(); + if ( root.tagName() != QString("GTK-Interface") ) { + error( QString("File is not a Glade XML file.") ); + return QStringList(); + } + + int widgetNo = 0; + int numWidgets = 0; + QDomNode n = root.firstChild(); + while ( !n.isNull() ) { + if ( n.toElement().tagName() == QString("widget") ) + numWidgets++; + n = n.nextSibling(); + } + + QProgressDialog fremskritt( QString("Converting Glade files..."), + QString("Abort Conversion"), numWidgets, 0, + "fremskritt", TRUE ); + + n = root.firstChild(); + while ( !n.isNull() ) { + QString tagName = n.toElement().tagName(); + + if ( tagName == QString("project") ) { + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + QString childTagName = child.toElement().tagName(); + if ( childTagName == QString("pixmaps_directory") ) { + yyPixmapDirectory = getTextValue( child ); + } else if ( childTagName == QString("program_name") ) { + yyProgramName = getTextValue( child ); + } + child = child.nextSibling(); + } + } else if ( tagName == QString("widget") ) { + yyOut = QString::null; + yyCustomWidgets.clear(); + yyStockItemActions.clear(); + yyActions.clear(); + yyConnections.clear(); + yySlots.clear(); + yyFormName = QString::null; + yyImages.clear(); + + uniqueAction = 1; + uniqueForm = 1; + uniqueMenuBar = 1; + uniqueSpacer = 1; + uniqueToolBar = 1; + + emitHeader(); + QString name = emitWidget( n.toElement(), FALSE ); + + if ( !yyCustomWidgets.isEmpty() ) { + emitOpening( QString("customwidgets") ); + + QMap::Iterator c = yyCustomWidgets.begin(); + while ( c != yyCustomWidgets.end() ) { + emitOpening( QString("customwidget") ); + emitSimpleValue( QString("class"), c.key() ); + if ( !(*c).isEmpty() ) + emitSimpleValue( QString("header"), *c, + attribute(QString("location"), + QString("local")) ); + emitClosing( QString("customwidget") ); + ++c; + } + emitClosing( QString("customwidgets") ); + } + + if ( !yyActions.isEmpty() ) { + emitOpening( QString("actions") ); + + QMap::Iterator a = yyActions.begin(); + while ( a != yyActions.end() ) { + emitOpening( QString("action") ); + emitProperty( QString("name"), + fixedName(a.key()).latin1() ); + emitProperty( QString("text"), (*a).text ); + emitProperty( QString("menuText"), (*a).menuText ); + if ( (*a).toolTip ) + emitProperty( QString("toolTip"), (*a).toolTip ); + if ( (*a).accel != 0 ) + emitProperty( QString("accel"), (*a).accel ); + if ( !(*a).iconSet.isEmpty() ) + emitProperty( QString("iconSet"), + imageName((*a).iconSet), + QString("iconset") ); + emitClosing( QString("action") ); + ++a; + } + emitClosing( QString("actions") ); + } + + if ( !yyImages.isEmpty() ) { + uint maxLength = 524288; + char *data = new char[maxLength]; + + QString dir = yyFileName; + dir.truncate( dir.findRev(QChar('/')) + 1 ); + dir += yyPixmapDirectory; + + emitOpening( QString("images") ); + + QMap::ConstIterator im = yyImages.begin(); + while ( im != yyImages.end() ) { + uint length = 0; + const char *format = 0; + + QString fn = dir + QChar( '/' ) + im.key(); + QFile f( fn ); + if ( !f.open(IO_ReadOnly) ) { + error( QString("Cannot open image '%1' for reading.") + .arg(fn) ); + } else { + length = f.readBlock( data, maxLength ); + f.at( 0 ); + format = QImageIO::imageFormat( &f ); + f.close(); + } + if ( format == 0 ) + format = "XPM"; + + AttributeMap attr; + attr.insert( QString("format"), QString(format) ); + attr.insert( QString("length"), QString::number(length) ); + + emitOpening( QString("image"), + attribute(QString("name"), *im) ); + emitSimpleValue( QString("data"), hexed(data, length), + attr ); + emitClosing( QString("image") ); + ++im; + } + emitClosing( QString("images") ); + delete[] data; + } + + if ( yyConnections.count() + yySlots.count() > 0 ) { + emitOpening( QString("connections") ); + + QValueList::Iterator c = yyConnections.begin(); + while ( c != yyConnections.end() ) { + emitOpening( QString("connection") ); + emitSimpleValue( QString("sender"), (*c).sender ); + emitSimpleValue( QString("signal"), (*c).signal ); + emitSimpleValue( QString("receiver"), yyFormName ); + emitSimpleValue( QString("slot"), (*c).slot ); + emitClosing( QString("connection") ); + ++c; + } + + QMap::Iterator s = yySlots.begin(); + while ( s != yySlots.end() ) { + AttributeMap attr; + attr.insert( QString("access"), *s ); + attr.insert( QString("language"), QString("C++") ); + attr.insert( QString("returntype"), QString("void") ); + emitSimpleValue( QString("slot"), s.key(), attr ); + ++s; + } + emitClosing( QString("connections") ); + } + emitFooter(); + + QString outFileName = fileName; + int k = outFileName.findRev( "." ); + if ( k != -1 ) + outFileName.truncate( k ); + if ( widgetNo != 0 ) + outFileName += QString::number( widgetNo + 1 ); + outFileName += QString( ".ui" ); + FILE *out = fopen( outFileName.latin1(), "w" ); + if ( out == 0 ) { + qWarning( "glade2ui: Could not open file '%s'", + outFileName.latin1() ); + } else { + if ( !yyOut.isEmpty() ) + fprintf( out, "%s", yyOut.latin1() ); + fclose( out ); + outFileNames.push_back( outFileName ); + } + yyOut = QString::null; + widgetNo++; + + qApp->processEvents(); + if ( fremskritt.wasCancelled() ) + break; + fremskritt.setProgress( widgetNo ); + } + n = n.nextSibling(); + } + return outFileNames; +} diff --git a/tools/designer/plugins/glade/glade2ui.h b/tools/designer/plugins/glade/glade2ui.h new file mode 100644 index 0000000..e688428 --- /dev/null +++ b/tools/designer/plugins/glade/glade2ui.h @@ -0,0 +1,169 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef GLADE2UI_H +#define GLADE2UI_H + +#include +#include +#include +#include + +typedef QMap AttributeMap; + +struct GladeAction +{ + QString text; + QString menuText; + QString toolTip; + int accel; + QString iconSet; +}; + +struct GladeConnection +{ + QString sender; + QString signal; + QString slot; +}; + +class Glade2Ui +{ +public: + Glade2Ui(); + + QStringList convertGladeFile( const QString& fileName ); + +private: + QString imageName( const QString& fileName ); + QString opening( const QString& tag, + const AttributeMap& attr = AttributeMap() ); + QString closing( const QString& tag ); + QString atom( const QString& tag, + const AttributeMap& attr = AttributeMap() ); + void error( const QString& message ); + void syntaxError(); + QString getTextValue( const QDomNode& node ); + void emitHeader(); + void emitFooter(); + void emitSimpleValue( const QString& tag, const QString& value, + const AttributeMap& attr = AttributeMap() ); + void emitOpening( const QString& tag, + const AttributeMap& attr = AttributeMap() ); + void emitClosing( const QString& tag ); + void emitAtom( const QString& tag, + const AttributeMap& attr = AttributeMap() ); + void emitVariant( const QVariant& val, + const QString& stringType = "string" ); + void emitProperty( const QString& prop, const QVariant& val, + const QString& stringType = "string" ); + void emitFontProperty( const QString& prop, int pointSize, bool bold ); + void emitAttribute( const QString& prop, const QVariant& val, + const QString& stringType = "string" ); + QString gtk2qtClass( const QString& gtkClass, + const QValueList& childWidgets ); + + int matchAccelOnActivate( const QDomElement& accel ); + void emitGtkMenu( const QDomElement& menu ); + void emitGtkMenuBarChildWidgets( + const QValueList& childWidgets ); + void emitGtkToolbarChildWidgets( + const QValueList& childWidgets ); + void emitPushButton( const QString& text, const QString& name ); + void attach( AttributeMap *attr, int leftAttach, int rightAttach, + int topAttach, int bottomAttach ); + void emitSpacer( const QString& orientation, int leftAttach = -1, + int rightAttach = -1, int topAttach = -1, + int bottomAttach = -1 ); + void emitPixmap( const QString& imageName, int leftAttach = -1, + int rightAttach = -1, int topAttach = -1, + int bottomAttach = -1 ); + void emitGnomeAbout( QString copyright, QString authors, QString comments ); + void emitGnomeAppChildWidgetsPass1( + const QValueList& childWidgets ); + void doPass2( const QValueList& childWidgets, + QValueList *menuBar, + QValueList > *toolBars ); + void emitGnomeAppChildWidgetsPass2( + const QValueList& childWidgets ); + void emitGtkButtonChildWidgets( QValueList childWidgets ); + void emitGtkComboChildWidgets( const QValueList& childWidgets, + const QStringList& items ); + void emitGtkNotebookChildWidgets( + const QValueList& childWidgets ); + void emitQListViewColumns( const QDomElement& qlistview ); + void emitGtkScrolledWindowChildWidgets( + const QValueList& childWidgets, + const QString& qtClass ); + void emitGnomeDruidPage( const QDomElement& druidPage ); + void emitGtkWindowChildWidgets( const QValueList& childWidgets, + const QString& qtClass ); + bool packEnd( const QDomElement& widget ); + void emitChildWidgets( const QValueList& childWidgets, + bool layouted, int leftAttach = -1, + int rightAttach = -1, int topAttach = -1, + int bottomAttach = -1 ); + void emitOpeningWidget( const QString& qtClass, int leftAttach = -1, + int rightAttach = -1, int topAttach = -1, + int bottomAttach = -1 ); + bool shouldPullup( const QValueList& childWidgets ); + QString emitWidget( const QDomElement& widget, bool layouted, + int leftAttach = -1, int rightAttach = -1, + int topAttach = -1, int bottomAttach = -1 ); + + QString yyOut; + QString yyIndentStr; + QString yyFileName; + QString yyProgramName; + QString yyPixmapDirectory; + QMap yyClassNameMap; + QMap yyStockMap; + QMap yyKeyMap; + QMap yyCustomWidgets; + QMap yyStockItemActions; + QMap yyActions; + QValueList yyConnections; + QMap yySlots; + QString yyFormName; + QMap yyImages; + + int numErrors; + int uniqueAction; + int uniqueForm; + int uniqueMenuBar; + int uniqueSpacer; + int uniqueToolBar; +}; + +#endif diff --git a/tools/designer/plugins/glade/main.cpp b/tools/designer/plugins/glade/main.cpp new file mode 100644 index 0000000..7ed71bb --- /dev/null +++ b/tools/designer/plugins/glade/main.cpp @@ -0,0 +1,109 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include + +#include "glade2ui.h" + +class GladeFilter : public ImportFilterInterface, public QLibraryInterface +{ +public: + GladeFilter(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface **iface ); + Q_REFCOUNT; + + QStringList featureList() const; + QStringList import( const QString& filter, const QString& filename ); + + bool init(); + void cleanup(); + bool canUnload() const; + +}; + +GladeFilter::GladeFilter() +{ +} + +QRESULT GladeFilter::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)(ImportFilterInterface*)this; + else if ( uuid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( uuid == IID_ImportFilter ) + *iface = (ImportFilterInterface*)this; + else if ( uuid == IID_QLibrary ) + *iface = (QLibraryInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QStringList GladeFilter::featureList() const +{ + QStringList list; + list << "Glade Files (*.glade)" ; + return list; +} + +QStringList GladeFilter::import( const QString &, const QString& filename ) +{ + Glade2Ui g; + return g.convertGladeFile( filename ); +} + +bool GladeFilter::init() +{ + return TRUE; +} + +void GladeFilter::cleanup() +{ +} + +bool GladeFilter::canUnload() const +{ + return TRUE; +} + +Q_EXPORT_COMPONENT() +{ + Q_CREATE_INSTANCE( GladeFilter ) +} diff --git a/tools/designer/plugins/kdevdlg/kdevdlg.pro b/tools/designer/plugins/kdevdlg/kdevdlg.pro new file mode 100644 index 0000000..d90d646 --- /dev/null +++ b/tools/designer/plugins/kdevdlg/kdevdlg.pro @@ -0,0 +1,11 @@ +TEMPLATE = lib +CONFIG += qt warn_on release plugin +HEADERS = kdevdlg2ui.h +SOURCES = main.cpp kdevdlg2ui.cpp +DESTDIR = ../../../../plugins/designer +TARGET = kdevdlgplugin +INCLUDEPATH += ../../interfaces + + +target.path += $$plugins.path/designer +INSTALLS += target diff --git a/tools/designer/plugins/kdevdlg/kdevdlg2ui.cpp b/tools/designer/plugins/kdevdlg/kdevdlg2ui.cpp new file mode 100644 index 0000000..bce7fb2 --- /dev/null +++ b/tools/designer/plugins/kdevdlg/kdevdlg2ui.cpp @@ -0,0 +1,524 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "kdevdlg2ui.h" +#include +#include +#include + +/// some little helpers /// + +void KDEVDLG2UI::wi() +{ + for ( int i = 0; i < indentation; i++ ) + *out << " "; +} + +void KDEVDLG2UI::indent() +{ + indentation++; +} + +void KDEVDLG2UI::undent() +{ + indentation--; +} + +void KDEVDLG2UI::writeClass( const QString& name ) +{ + wi(); *out << "" << name << "" << endl; +} + +void KDEVDLG2UI::writeWidgetStart( const QString& qclass ) +{ + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeWidgetEnd() +{ + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeCString( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeString( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeRect( const QString& name, int x, int y, int w, int h ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << endl; indent(); + wi(); *out << "" << x << "" << endl; + wi(); *out << "" << y << "" << endl; + wi(); *out << "" << w << "" << endl; + wi(); *out << "" << h << "" << endl; undent(); + wi(); *out << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeFont( const QString& family, int pointsize ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "font" << endl; + wi(); *out << "" << endl; indent(); + wi(); *out << "" << family << "" << endl; + wi(); *out << "" << pointsize << "" << endl; undent(); + wi(); *out << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeBool( const QString& name, bool value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << (value ? "true" : "false") << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeNumber( const QString& name, int value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeEnum( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeSet( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeItem( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + writeString( name, value ); undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeColumn( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + writeString( name, value ); undent(); + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeColor( const QString& name, const QString& value ) +{ + int color = value.toInt(); + + int r = color & 0x00ff0000 >> 16; + int g = color & 0x0000ff00 >> 8; + int b = color & 0x000000ff; + + wi(); *out << "" << endl; indent(); //###FIX + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << endl; indent(); + wi(); *out << "" << r << "" << endl; + wi(); *out << "" << g << "" << endl; + wi(); *out << "" << b << "" << endl; undent(); + wi(); *out << "" << endl; + wi(); *out << "" << endl; +} + +void KDEVDLG2UI::writeStyles( const QStringList styles, bool isFrame ) +{ + if ( isFrame ) { + bool defineFrame = FALSE; + QString shadow = "NoFrame"; + QString shape = "StyledPanel"; + int width = 2; + if ( styles.contains( "WS_EX_STATICEDGE" ) ) { + shadow = "Plain"; + width = 1; + defineFrame = TRUE; + } + if ( styles.contains( "WS_EX_CLIENTEDGE" ) ) { + shadow = "Sunken"; + defineFrame = TRUE; + } + if ( styles.contains( "WS_EX_DLGMODALFRAME" ) ) { + shadow = "Raised"; + defineFrame = TRUE; + } + if ( !styles.contains( "WS_BORDER" ) ) { + shape = "NoFrame"; + defineFrame = TRUE; + } + + if ( defineFrame ) { + writeEnum( "frameShape", "StyledPanel" ); + writeEnum( "frameShadow", shadow ); + writeNumber( "lineWidth", width ); + } + } + + if ( styles.contains("WS_DISABLED") ) + writeBool("enabled", FALSE ); + if ( styles.contains("WS_EX_ACCEPTFILES") ) + writeBool("acceptDrops", TRUE ); + if ( styles.contains("WS_EX_TRANSPARENT") ) + writeBool("autoMask", TRUE ); + if ( !styles.contains("WS_TABSTOP") ) + writeEnum("focusPolicy", "NoFocus"); +} + +/*! + Constructs a KDEVDLG2UI object +*/ + +KDEVDLG2UI::KDEVDLG2UI( QTextStream* input, const QString& name ) +{ + className = name; + writeToFile = TRUE; + in = input; + indentation = 0; + out = 0; +} + +/*! + Destructs the KDEVDLG2UI object +*/ + +KDEVDLG2UI::~KDEVDLG2UI() +{ +} + +/*! + Parses the input stream and writes the output to files. +*/ + +bool KDEVDLG2UI::parse() +{ + QFile fileOut; + QString buffer; + + if ( writeToFile ) { + + QString outputFile = QString( className ) + ".ui"; + fileOut.setName( outputFile ); + if (!fileOut.open( IO_WriteOnly ) ) + qFatal( "kdevdlg2ui: Could not open output file '%s'", outputFile.latin1() ); + out = new QTextStream( &fileOut ); + targetFiles.append( outputFile ); + } else { + out = new QTextStream( &buffer, IO_WriteOnly ); + } + + writeDialog( className ); + + delete out; + out = 0; + + return TRUE; +} + +/*! + Parses the input stream and writes the output in \a get. +*/ +bool KDEVDLG2UI::parse( QStringList& get ) +{ + writeToFile = FALSE; + bool result = parse(); + get = target; + return result; +} + +/*! + Replaces characters like '&', '<' and '>' with the proper encoding. +*/ +void KDEVDLG2UI::cleanString( QString * text ) +{ + if ( !text ) return; + text->replace( "\\n", "\n" ); + text->replace( "\\t", "\t" ); + text->replace( "&", "&" ); + text->replace( "<", "<" ); + text->replace( ">", ">" ); +} + +/*! + Builds a number of UI dialog out of the current input stream +*/ +bool KDEVDLG2UI::writeDialog( const QString& name ) +{ + *out << "" << endl; + writeClass( name ); + + while ( !in->eof() ) { + + line = in->readLine().simplifyWhiteSpace(); + + if ( line.left( 4 ) == "data" ) { + // ignore data section + while ( line.left( 1 ) != "}" && !in->eof() ) { + line = in->readLine(); + } + } else if ( line.left( 4 ) == "item" ) { + writeWidgetStart( line.section( "//", 0, 0 ).section( " ", 1, 1 ) ); + } else if ( line.left( 1 ) == "{" ) { + indent(); + } else if ( line.left( 1 ) == "}" ) { + undent(); + writeWidgetEnd(); + } else if ( line.left( 4 ) == "Name" ) { + QString name = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + writeString( "name", name ); + } else if ( line.left( 4 ) == "Font" ) { + QString font = line.section( "//", 0, 0 ).section( "\"", 1 ); + QString family = font.section("\"", 1, 1 ); + int pointSize = font.section("\"", 3, 3 ).toInt(); + //int weight = font.section("\"", 5, 5 ).toInt(); + //bool italic = ( font.section("\"", 7, 7 ) == "TRUE" ); + writeFont( family, pointSize ); // weight, italic ? + } else if ( line.left( 9 ) == "IsEnabled" ) { + bool isEnabled = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "enabled", isEnabled ); + } else if ( line.left( 12 ) == "AcceptsDrops" ) { + bool acceptDrops = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "acceptDrops", acceptDrops ); + } else if ( line.left( 12 ) == "isAutoResize" ) { + bool isAutoResize = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "autoResize", isAutoResize ); //###FIX: obsolete + } else if ( line.left( 12 ) == "isAutoRepeat" ) { + bool isAutoRepeat = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "autoRepeat", isAutoRepeat ); + } else if ( line.left( 9 ) == "isDefault" ) { + bool isDefault = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "default", isDefault ); + } else if ( line.left( 13 ) == "isAutoDefault" ) { + bool isAutoDefault = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "autoDefault", isAutoDefault ); + } else if ( line.left( 14 ) == "isToggleButton" ) { + bool isToggleButton = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "toggleButton", isToggleButton ); + } else if ( line.left( 11 ) == "isToggledOn" ) { + bool isToggledOn = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "on", isToggledOn ); + } else if ( line.left( 8 ) == "hasFrame" ) { + bool hasFrame = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "frame", hasFrame ); + } else if ( line.left( 10 ) == "isReadOnly" ) { + bool isReadOnly = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "readOnly", isReadOnly ); + } else if ( line.left( 9 ) == "isChecked" ) { + bool isChecked = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "checked", isChecked ); + } else if ( line.left( 16 ) == "isAutoCompletion" ) { + bool isAutoCompl = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "autoCompletion", isAutoCompl ); + } else if ( line.left( 8 ) == "EditText" ) { + bool editText = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "editable", editText ); + } else if ( line.left( 10 ) == "isTracking" ) { + bool isTracking = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "tracking", isTracking ); + } else if ( line.left( 16 ) == "isMultiSelection" ) { + bool isMultiSel = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "multiSelection", isMultiSel ); + } else if ( line.left( 21 ) == "isAllColumnsShowFocus" ) { + bool isAllColsShowFocus = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "allColumnsShowFocus", isAllColsShowFocus ); + } else if ( line.left( 16 ) == "isRootDecorated" ) { + bool isRootDec = + ( line.section( "//", 0, 0 ).section("\"", 1, 1 ) == "true" ); + writeBool( "rootIsDecorated", isRootDec ); + } else if ( line.left( 1 ) == "X" ) { + int x = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + line = in->readLine().stripWhiteSpace(); + int y = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + line = in->readLine().stripWhiteSpace(); + int w = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + line = in->readLine().stripWhiteSpace(); + int h = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeRect( "geometry", x, y, w, h ); + } else if ( line.left( 8 ) == "MinWidth" ) { + int minw = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "minimumWidth", minw ); + } else if ( line.left( 9 ) == "MinHeight" ) { + int minh = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "minimumHeight", minh ); + } else if ( line.left( 8 ) == "MaxWidth" ) { + int maxw = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "maximumWidth", maxw ); + } else if ( line.left( 9 ) == "MaxHeight" ) { + int maxh = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "maximumHeight", maxh ); + } else if ( line.left( 4 ) == "Text" ) { + QString text = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & text ); + writeString( "text", text ); + } else if ( line.left( 5 ) == "Title" ) { + QString title = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & title ); + writeString( "title", title ); + } else if ( line.left( 5 ) == "Buddy" ) { + QString buddy = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + writeString( "buddy", buddy ); + } else if ( line.left( 14 ) == "SpecialValText" ) { + QString text = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + writeString( "specialValueText", text ); + } else if ( line.left( 6 ) == "Prefix" ) { + QString text = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + writeString( "prefix", text ); + } else if ( line.left( 6 ) == "Suffix" ) { + QString text = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + writeString( "suffix", text ); + } else if ( line.left( 5 ) == "Value" ) { + int v = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "value", v ); + } else if ( line.left( 8 ) == "MinValue" ) { + int minv = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "minValue", minv ); + } else if ( line.left( 8 ) == "MaxValue" ) { + int maxv = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "maxValue", maxv ); + } else if ( line.left( 9 ) == "SizeLimit" ) { + int limit = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "sizeLimit", limit ); + } else if ( line.left( 9 ) == "MaxLength" ) { + int maxl = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "maxLength", maxl ); + } else if ( line.left( 8 ) == "MaxCount" ) { + int maxc = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "maxCount", maxc ); + } else if ( line.left( 14 ) == "CursorPosition" ) { + int pos = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "cursorPosition", pos ); + } else if ( line.left( 9 ) == "NumDigits" ) { + int digits = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "numDigits", digits ); + } else if ( line.left( 10 ) == "TotalSteps" ) { + int steps = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "totalSteps", steps ); + } else if ( line.left( 12 ) == "TreeStepSize" ) { + int stepSize = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "treeStepSize", stepSize ); + } else if ( line.left( 10 ) == "ItemMargin" ) { + int margin = line.section( "//", 0, 0 ).section("\"", 1, 1 ).toInt(); + writeNumber( "itemMargin", margin ); + } else if ( line.left( 7 ) == "ToolTip" ) { + QString text = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + writeString( "toolTip", text ); + } else if ( line.left( 9 ) == "QuickHelp" ) { + QString text = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & text ); + writeString( "whatsThis", text ); + } else if ( line.left( 15 ) == "InsertionPolicy" ) { + QString policy = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & policy ); + writeEnum( "insertionPolicy", policy ); //###FIX: QComboBox:: + } else if ( line.left( 11 ) == "Orientation" ) { + QString orientation = + line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & orientation ); + if ( orientation == "V" ) + writeEnum( "orientation", "Qt::Vertical" ); + else if ( orientation == "H" ) + writeEnum( "orientation", "Qt::Horizontal" ); + } else if ( line.left( 14 ) == "vScrollBarMode" ) { + QString mode = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & mode ); + writeEnum( "vScrollBarMode", mode ); + } else if ( line.left( 14 ) == "hScrollBarMode" ) { + QString mode = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & mode ); + writeEnum( "hScrollBarMode", mode ); + } else if ( line.left( 7 ) == "Entries" ) { + QString entries = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & entries ); + QStringList l = QStringList::split( '\n', entries ); + for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) + writeItem( "text", *it ); + } else if ( line.left( 7 ) == "Columns" ) { + QString columns = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & columns ); + QStringList l = QStringList::split( '\n', columns ); + for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) + writeColumn( "text", *it ); + } else if ( line.left( 6 ) == "BgMode" ) { + QString mode = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & mode ); + writeString( "backgroundMode", mode ); //###FIX: QWidget::: + } else if ( line.left( 10 ) == "BgPalColor" ) { + QString color = line.section( "//", 0, 0 ).section("\"", 1, 1 ); + cleanString( & color ); + writeColor( "paletteBackgroundColor", color ); + } //else { + //if ( line.length() ) + //qDebug( "IGNORED: %s", line.latin1() ); + //} + } + *out << "" << endl; + return TRUE; +} + diff --git a/tools/designer/plugins/kdevdlg/kdevdlg2ui.h b/tools/designer/plugins/kdevdlg/kdevdlg2ui.h new file mode 100644 index 0000000..448e850 --- /dev/null +++ b/tools/designer/plugins/kdevdlg/kdevdlg2ui.h @@ -0,0 +1,90 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef KDEVDLG2UI_H +#define KDEVDLG2UI_H + +#include +#include +#include + +class KDEVDLG2UI +{ +public: + KDEVDLG2UI( QTextStream* input, const QString& name = "dialog" ); + ~KDEVDLG2UI(); + + bool parse(); + bool parse ( QStringList& get ); + + QStringList targetFiles; + +protected: + + bool writeDialog( const QString& name ); + + QString className; + QString line; + QTextStream *in; + QStringList target; + + void cleanString( QString* text ); + + void indent(); + void undent(); + void wi(); + + void writeClass( const QString& name ); + void writeCString( const QString& name, const QString& value ); + void writeString( const QString& name, const QString& value ); + void writeRect( const QString& name, int x, int y, int w, int h ); + void writeFont( const QString& family, int pointsize ); + void writeBool( const QString& name, bool value ); + void writeNumber( const QString& name, int value ); + void writeEnum( const QString& name, const QString& value ); + void writeSet( const QString& name, const QString& value ); + void writeItem( const QString& name, const QString& value ); + void writeColumn( const QString& name, const QString& value ); + void writeColor( const QString& name, const QString& value ); + void writeStyles( const QStringList styles, bool isFrame ); + void writeWidgetStart( const QString& qclass ); + void writeWidgetEnd(); + +private: + int indentation; + bool writeToFile; + QTextStream* out; +}; + +#endif diff --git a/tools/designer/plugins/kdevdlg/main.cpp b/tools/designer/plugins/kdevdlg/main.cpp new file mode 100644 index 0000000..1247f3d --- /dev/null +++ b/tools/designer/plugins/kdevdlg/main.cpp @@ -0,0 +1,120 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +#include +#include +#include + +#include "kdevdlg2ui.h" + +class KDevDlgFilter : public ImportFilterInterface, public QLibraryInterface +{ +public: + KDevDlgFilter(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface **iface ); + Q_REFCOUNT; + + QStringList featureList() const; + QStringList import( const QString& filter, const QString& filename ); + + bool init(); + void cleanup(); + bool canUnload() const; +}; + +KDevDlgFilter::KDevDlgFilter() +{ +} + +QRESULT KDevDlgFilter::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)(ImportFilterInterface*)this; + else if ( uuid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( uuid == IID_ImportFilter ) + *iface = (ImportFilterInterface*)this; + else if ( uuid == IID_QLibrary ) + *iface = (QLibraryInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QStringList KDevDlgFilter::featureList() const +{ + QStringList list; + list << "KDevelop Dialog Files (*.kdevdlg)" ; + return list; +} + +QStringList KDevDlgFilter::import( const QString &, const QString& filename ) +{ + QFile file( filename ); + if ( !file.open( IO_ReadOnly ) ) + qWarning( "uic: Could not open file '%s' ", filename.latin1() ); + QTextStream in; + in.setDevice( &file ); + + QString name = filename.right( filename.length() - filename.findRev( QDir::separator() ) - 1 ).section( ".", 0, 0 ); + KDEVDLG2UI c( &in, name ); + QStringList files; + c.parse(); + return c.targetFiles; +} + +bool KDevDlgFilter::init() +{ + return TRUE; +} + +void KDevDlgFilter::cleanup() +{ +} + +bool KDevDlgFilter::canUnload() const +{ + return TRUE; +} + +Q_EXPORT_COMPONENT() +{ + Q_CREATE_INSTANCE( KDevDlgFilter ) +} diff --git a/tools/designer/plugins/plugins.pro b/tools/designer/plugins/plugins.pro new file mode 100644 index 0000000..355f5d0 --- /dev/null +++ b/tools/designer/plugins/plugins.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs +PLUGIN_DIRS = wizards \ + cppeditor \ + dlg \ + glade \ + rc \ + kdevdlg +shared:SUBDIRS *= $$PLUGIN_DIRS +dll:SUBDIRS *= $$PLUGIN_DIRS diff --git a/tools/designer/plugins/rc/main.cpp b/tools/designer/plugins/rc/main.cpp new file mode 100644 index 0000000..f2e9abb --- /dev/null +++ b/tools/designer/plugins/rc/main.cpp @@ -0,0 +1,117 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +#include + +#include "rc2ui.h" + +class RCFilter : public ImportFilterInterface, public QLibraryInterface +{ +public: + RCFilter(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface **iface ); + Q_REFCOUNT; + + QStringList featureList() const; + QStringList import( const QString& filter, const QString& filename ); + + bool init(); + void cleanup(); + bool canUnload() const; +}; + +RCFilter::RCFilter() +{ +} + +QRESULT RCFilter::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)(ImportFilterInterface*)this; + else if ( uuid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( uuid == IID_ImportFilter ) + *iface = (ImportFilterInterface*)this; + else if ( uuid == IID_QLibrary ) + *iface = (QLibraryInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QStringList RCFilter::featureList() const +{ + QStringList list; + list << "Microsoft Resource Files (*.rc)" ; + return list; +} + +QStringList RCFilter::import( const QString &, const QString& filename ) +{ + QFile file( filename ); + if ( !file.open( IO_ReadOnly ) ) + qWarning( "uic: Could not open file '%s' ", filename.latin1() ); + QTextStream in; + in.setDevice( &file ); + + RC2UI c( &in ); + QStringList files; + c.parse(); + return c.targetFiles; +} + +bool RCFilter::init() +{ + return TRUE; +} + +void RCFilter::cleanup() +{ +} + +bool RCFilter::canUnload() const +{ + return TRUE; +} + +Q_EXPORT_COMPONENT() +{ + Q_CREATE_INSTANCE( RCFilter ) +} diff --git a/tools/designer/plugins/rc/rc.pro b/tools/designer/plugins/rc/rc.pro new file mode 100644 index 0000000..27ad444 --- /dev/null +++ b/tools/designer/plugins/rc/rc.pro @@ -0,0 +1,11 @@ +TEMPLATE = lib +CONFIG += qt warn_on release plugin +HEADERS = rc2ui.h +SOURCES = main.cpp rc2ui.cpp +DESTDIR = ../../../../plugins/designer +TARGET = rcplugin +INCLUDEPATH += ../../interfaces + + +target.path += $$plugins.path/designer +INSTALLS += target diff --git a/tools/designer/plugins/rc/rc2ui.cpp b/tools/designer/plugins/rc/rc2ui.cpp new file mode 100644 index 0000000..b3e48dd --- /dev/null +++ b/tools/designer/plugins/rc/rc2ui.cpp @@ -0,0 +1,888 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "rc2ui.h" +#include + +/// some little helpers /// + +void RC2UI::wi() +{ + for ( int i = 0; i < indentation; i++ ) + *out << " "; +} + +void RC2UI::indent() +{ + indentation++; +} + +void RC2UI::undent() +{ + indentation--; +} + +QString RC2UI::stripQM( const QString& string ) +{ + return string.mid( 1, string.length()-2 ); +} + +QStringList RC2UI::splitStyles( const QString& styles, char sep ) +{ + QString s = styles; + QString style; + QStringList l; + while ( s.find( sep ) > -1 ) { + style = s.left( s.find( sep ) ); + l << style.stripWhiteSpace(); + s = s.right( s.length() - style.length() -1 ); + } + if ( !s.isEmpty() ) + l << s.stripWhiteSpace(); + return l; +} + +QString RC2UI::parseNext( QString& arg, char sep ) +{ + QString next = arg.left( arg.find(sep) ); + arg = arg.right( arg.length() - next.length() - 1 ); + return next; +} + +void RC2UI::writeClass( const QString& name ) +{ + wi(); *out << "" << name << "" << endl; +} + +void RC2UI::writeCString( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void RC2UI::writeString( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void RC2UI::writeRect( const QString& name, int x, int y, int w, int h ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << endl; indent(); + wi(); *out << "" << int(double(x)*1.5) << "" << endl; + wi(); *out << "" << int(double(y)*1.65) << "" << endl; + wi(); *out << "" << int(double(w)*1.5) << "" << endl; + wi(); *out << "" << int(double(h)*1.65) << "" << endl; undent(); + wi(); *out << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void RC2UI::writeFont( const QString& family, int pointsize ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "font" << endl; + wi(); *out << "" << endl; indent(); + wi(); *out << "" << family << "" << endl; + wi(); *out << "" << pointsize << "" << endl; undent(); + wi(); *out << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void RC2UI::writeBool( const QString& name, bool value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << (value ? "true" : "false") << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void RC2UI::writeNumber( const QString& name, int value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void RC2UI::writeEnum( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void RC2UI::writeSet( const QString& name, const QString& value ) +{ + wi(); *out << "" << endl; indent(); + wi(); *out << "" << name << "" << endl; + wi(); *out << "" << value << "" << endl; undent(); + wi(); *out << "" << endl; +} + +void RC2UI::writeStyles( const QStringList styles, bool isFrame ) +{ + if ( isFrame ) { + bool defineFrame = FALSE; + QString shadow = "NoFrame"; + QString shape = "StyledPanel"; + int width = 2; + if ( styles.contains( "WS_EX_STATICEDGE" ) ) { + shadow = "Plain"; + width = 1; + defineFrame = TRUE; + } + if ( styles.contains( "WS_EX_CLIENTEDGE" ) ) { + shadow = "Sunken"; + defineFrame = TRUE; + } + if ( styles.contains( "WS_EX_DLGMODALFRAME" ) ) { + shadow = "Raised"; + defineFrame = TRUE; + } + if ( !styles.contains( "WS_BORDER" ) ) { + shape = "NoFrame"; + defineFrame = TRUE; + } + + if ( defineFrame ) { + writeEnum( "frameShape", "StyledPanel" ); + writeEnum( "frameShadow", shadow ); + writeNumber( "lineWidth", width ); + } + } + + if ( styles.contains("WS_DISABLED") ) + writeBool("enabled", FALSE ); + if ( styles.contains("WS_EX_ACCEPTFILES") ) + writeBool("acceptDrops", TRUE ); + if ( styles.contains("WS_EX_TRANSPARENT") ) + writeBool("autoMask", TRUE ); + if ( !styles.contains("WS_TABSTOP") ) + writeEnum("focusPolicy", "NoFocus"); +} + +/*! + Constructs a RC2UI object +*/ + +RC2UI::RC2UI( QTextStream* input ) +: blockStart1( "/////////////////////////////////////////////////////////////////////////////" ), + blockStart2( "//" ) +{ + writeToFile = TRUE; + in = input; + indentation = 0; + out = 0; +} + +/*! + Destructs the RC2UI object +*/ + +RC2UI::~RC2UI() +{ +} + +/*! + Parses the input stream and writes the output to files. +*/ + +bool RC2UI::parse() +{ + while ( !in->eof() ) { + while ( line != blockStart1 && !in->eof() ) + line = in->readLine(); + if ( in->eof() ) + return FALSE; + while ( line != blockStart2 && !in->eof() ) + line = in->readLine(); + if ( in->eof() ) + return FALSE; + + line = in->readLine(); + + if ( line.left(3) == "// " && !in->eof() ) { + QString type = line.right( line.length() - 3 ); + if ( in->readLine() == "//" && in->readLine().isEmpty() && !in->eof() ) { + if ( type == "Dialog" ) { + if ( !makeDialog() ) + return FALSE; + } +/* + else if ( type == "Bitmap" ) { + if ( !makeBitmap() ) + return FALSE; + } else if ( type == "String Table" ) { + if ( !makeStringTable() ) + return FALSE; + } else if ( type == "Accelerator" ) { + if ( !makeAccelerator() ) + return FALSE; + } else if ( type == "Cursor" ) { + if ( !makeCursor() ) + return FALSE; + } else if ( type == "HTML" ) { + if ( !makeHTML() ) + return FALSE; + } else if ( type == "Icon" ) { + if ( !makeIcon() ) + return FALSE; + } else if ( type == "Version" ) { + if ( !makeVersion() ) + return FALSE; + } +*/ + } + } else + return FALSE; + } + return TRUE; +} + +/*! + Parses the input stream and writes the output in \a get. +*/ + +bool RC2UI::parse( QStringList& get ) +{ + writeToFile = FALSE; + bool result = parse(); + get = target; + return result; +} + +/*! + Retrieves a unique name starting with \a start +*/ +QString RC2UI::useName( const QString& start ) +{ + QString name = start; + int id = 1; + + while ( usedNames.contains( name ) ) { + name = start + QString( "%1" ).arg( id ); + id++; + } + + usedNames.append(name); + + return name; +} + + +/*! + Builds a number of UI dialog out of the current input stream +*/ + +bool RC2UI::makeDialog() +{ + line = in->readLine(); + do { + QFile fileOut; + QString buffer; + int count; + QCString className; + uint x, y, w, h; + uint endDesc; + bool space = FALSE; + for ( endDesc = 0; endDesc < line.length() ; endDesc++ ) { + char c = (QChar)line.at(endDesc); + if ( space && (c >= '0') && (c <= '9') ) + break; + space = c==' '; + } + + QString desc = line.left(endDesc-1); + line = line.right( line.length() - endDesc ); + + className = parseNext( desc, ' ' ); + + count = sscanf( line, "%u, %u, %u, %u", &x, &y, &w, &h ); + + if ( !count && count == EOF ) + return FALSE; + + char property[256]; + QStringList styles; + QStringList extendedStyles; + QString caption = ""; + QString baseClass = ""; + QString widgetType; + QString widgetName; + QString arguments; + int pointsize = 10; + QString fontname; + do { + line = ""; + do { + if ( in->eof() ) + return TRUE; + line += in->readLine(); + } while ( line[(int)line.length()-1] == '|' || + line[(int)line.length()-1] == ',' ); + count = sscanf( line, "%s", property ); + line = line.right( line.length() - line.find(" ") -1 ); + if ( QString(property) == "STYLE" ) { + styles = splitStyles(line); + if ( styles.contains( "WS_CAPTION" ) ) + baseClass = "QDialog"; + else + baseClass = "QWidget"; + } else if ( QString(property) == "CAPTION" ) { + caption = stripQM( line ); + } else if ( QString(property) == "FONT" ) { + QString pt = line.left( line.find(",") ); + pointsize = pt.toInt(); + fontname = stripQM(line.right( line.length() - line.find(",") - 2 )); + } + } while ( line != "BEGIN" ); + + if ( writeToFile ) { + + QString outputFile = QString(className) + ".ui"; + fileOut.setName( outputFile ); + if (!fileOut.open( IO_WriteOnly ) ) + qFatal( "rc2ui: Could not open output file '%s'", outputFile.latin1() ); + out = new QTextStream( &fileOut ); + targetFiles.append( outputFile ); + } else { + out = new QTextStream( &buffer, IO_WriteOnly ); + } + + *out << "" << endl; + writeClass( className ); + wi(); *out << ""<< endl; indent(); + writeClass( baseClass ); + writeCString( "name", className ); + writeRect( "geometry", x, y, w, h ); + writeString( "caption", caption ); + writeFont( fontname, pointsize ); + + do { + if ( in->eof() ) + return TRUE; + + line = in->readLine().stripWhiteSpace(); + if ( line == "END" ) + continue; + + widgetType = parseNext(line, ' '); + arguments = line.stripWhiteSpace(); + while ( arguments[(int)arguments.length()-1] == ',' || + arguments[(int)arguments.length()-1] == '|' ) + arguments += " "+in->readLine().stripWhiteSpace(); + + wi(); *out << "" << endl; indent(); + + WidgetType ID = IDUnknown; + QString controlType; + QString widgetID; + QString widgetText; + bool hasText = FALSE; + bool isControl = FALSE; + bool isFrame = FALSE; + + if ( widgetType == "PUSHBUTTON" ) { + ID = IDPushButton; + hasText = TRUE; + } else if ( widgetType == "DEFPUSHBUTTON" ) { + ID = IDPushButton; + hasText = TRUE; + } else if ( widgetType == "LTEXT" ) { + ID = IDLabel; + hasText = TRUE; + } else if ( widgetType == "CTEXT" ) { + ID = IDLabel; + hasText = TRUE; + } else if ( widgetType == "RTEXT" ) { + ID = IDLabel; + hasText = TRUE; + } else if ( widgetType == "EDITTEXT" ) { + ID = IDLineEdit; + } else if ( widgetType == "GROUPBOX" ) { + ID = IDGroupBox; + hasText = TRUE; + } else if ( widgetType == "COMBOBOX" ) { + ID = IDComboBox; + } else if ( widgetType == "LISTBOX" ) { + ID = IDListBox; + } else if ( widgetType == "SCROLLBAR" ) { + ID = IDScrollBar; + } else if ( widgetType == "CHECKBOX" ) { + ID = IDCheckBox; + hasText = TRUE; + } else if ( widgetType == "RADIOBUTTON" ) { + ID = IDRadioButton; + hasText = TRUE; + } else if ( widgetType == "CONTROL" ) { + isControl = TRUE; + widgetText = stripQM(parseNext( arguments )); + widgetID = parseNext( arguments ); + controlType = stripQM(parseNext( arguments )); + styles = splitStyles(parseNext( arguments )); + + if ( controlType == "Static" ) { + ID = IDLabel; + } else if ( controlType == "Button" ) { + if ( styles.contains("BS_AUTOCHECKBOX") || + styles.contains("BS_3STATE") ) + ID = IDCheckBox; + else if ( styles.contains("BS_AUTORADIOBUTTON") ) + ID = IDRadioButton; + } else if ( controlType == "msctls_updown32" ) { + ID = IDSpinBox; + } else if ( controlType == "msctls_progress32" ) { + ID = IDProgressBar; + } else if ( controlType == "msctls_trackbar32" ) { + ID = IDSlider; + } else if ( controlType == "SysListView32" ) { + ID = IDIconView; + } else if ( controlType == "SysTreeView32" ) { + ID = IDListView; + } else if ( controlType == "SysTabControl32" ) { + ID = IDTabWidget; + } else if ( controlType == "SysAnimate32" ) { + ID = IDLabel; + } else if ( controlType == "RICHEDIT" ) { + ID = IDMultiLineEdit; + } else if ( controlType == "ComboBoxEx32" ) { + ID = IDComboBox; + } else if ( controlType == "" ) { + ID = IDCustom; + } else { + ID = IDUnknown; + } + } else + ID = IDUnknown; + + if ( hasText ) + widgetText = stripQM(parseNext( arguments )); + + if ( isControl ) { + x = parseNext( arguments ).toInt(); + y = parseNext( arguments ).toInt(); + w = parseNext( arguments ).toInt(); + h = parseNext( arguments ).toInt(); + } else { + widgetID = parseNext( arguments ); + x = parseNext( arguments ).toInt(); + y = parseNext( arguments ).toInt(); + w = parseNext( arguments ).toInt(); + h = parseNext( arguments ).toInt(); + styles.clear(); + } + + do { + extendedStyles = splitStyles(parseNext( arguments )); + for ( uint i = 0; i < extendedStyles.count(); i++ ) + styles << (*extendedStyles.at(i)); + } while ( arguments.find(',') > -1 ); + + switch ( ID ) { + case IDWidget: + break; + case IDPushButton: + { + writeClass("QPushButton"); + writeCString( "name", useName("PushButton_"+widgetID) ); + writeRect( "geometry", x, y, w, h ); + writeString( "text", widgetText ); + if ( widgetType == "DEFPUSHBUTTON" ) + writeBool( "default", TRUE ); + } + break; + case IDLabel: + { + isFrame = TRUE, + writeClass("QLabel"); + writeCString( "name", useName("Label_"+widgetID) ); + writeRect( "geometry", x,y,w,h ); + writeString( "text", widgetText ); + QString align; + if ( !styles.contains("SS_CENTERIMAGE") ) + align += "|AlignTop"; + else + align += "|AlignVCenter"; + if ( widgetType == "LTEXT" ) { + align += "|AlignLeft"; + } else if ( widgetType == "CTEXT") { + align += "|AlignHCenter"; + } else if ( widgetType == "RTEXT") { + align += "|AlignRight"; + } + writeSet("alignment", align ); + } + break; + case IDCheckBox: + { + writeClass("QCheckBox"); + writeCString("name", useName("CheckBox_"+widgetID) ); + writeRect("geometry", x,y,w,h); + writeString("text", widgetText ); + if ( styles.contains( "BS_3STATE" ) ) + writeBool( "tristate", TRUE ); + } + break; + case IDRadioButton: + { + writeClass("QRadioButton"); + writeCString("name", useName("RadioButton_"+widgetID) ); + writeRect("geometry", x,y,w,h); + writeString("text", widgetText ); + } + break; + case IDGroupBox: + { + isFrame = TRUE; + writeClass("QGroupBox"); + writeCString( "name", useName("GroupBox_"+widgetID) ); + writeRect( "geometry", x,y,w,h ); + writeString( "title", widgetText ); + if ( !styles.contains( "WS_BORDER" ) ) + styles.append( "WS_BORDER" ); + } + break; + case IDLineEdit: + { + if ( !styles.contains("ES_MULTILINE") ) { + writeClass("QLineEdit"); + writeCString( "name", useName("LineEdit_"+widgetID) ); + } else { + writeClass("QMultiLineEdit"); + writeCString( "name", useName("MultiLineEdit_"+widgetID) ); + } + writeRect( "geometry", x,y,w,h ); + QString align = "AlignTop"; + if ( styles.contains("ES_CENTER") ) + align+="|AlignHCenter"; + else if ( styles.contains("ES_RIGHT") ) + align+="|AlignRight"; + else + align+="|AlignLeft"; + writeSet("alignment", align); + } + break; + case IDMultiLineEdit: + { + writeClass("QMultiLineEdit"); + writeCString("name", useName("MultiLineEdit_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + } + break; + case IDIconView: + { + isFrame = TRUE; + writeClass("QIconView"); + writeCString("name", useName("IconView_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + if ( !styles.contains( "LVS_SINGLESEL" ) ) + writeEnum( "selectionMode", "Extended" ); + if ( styles.contains( "LVS_NOLABELWRAP" ) ) + writeBool("wordWrapIconText", FALSE ); + } + break; + case IDListView: + { + isFrame = TRUE; + writeClass("QListView"); + writeCString("name", useName("ListView_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + if ( styles.contains( "TVS_LINESATROOT" ) ) + writeBool( "rootIsDecorated", TRUE ); + if ( styles.contains( "TVS_FULLROWSELECT" ) ) + writeBool( "allColumnsShowFocus", TRUE ); + } + break; + case IDProgressBar: + { + isFrame = TRUE; + writeClass("QProgressBar"); + writeCString("name", useName("ProgressBar_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + if ( styles.contains("TBS_VERT") ) + writeEnum("orientation", "Vertical"); + else + writeEnum("orientation", "Horizontal"); + } + break; + case IDTabWidget: + { + writeClass("QTabWidget"); + writeCString("name", useName("TabWidget_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + wi(); *out << "" << endl; indent(); + writeClass("QWidget"); + wi(); *out << "" << endl; indent(); + wi(); *out << "title" << endl; + wi(); *out << "Tab1" << endl; undent(); + wi(); *out << "" << endl; undent(); + wi(); *out << "" << endl; + } + break; + case IDSpinBox: + { + isFrame = TRUE; + writeClass("QSpinBox"); + writeCString("name", useName("SpinBox_"+widgetID) ); + writeRect("geometry", x,y,w,h); + } + break; + case IDSlider: + { + writeClass("QSlider"); + writeCString("name", useName("Slider_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + if ( styles.contains("TBS_VERT") ) + writeEnum("orientation", "Vertical"); + else + writeEnum("orientation", "Horizontal"); + if ( !styles.contains("TBS_NOTICKS") ) + writeEnum("tickmarks", "Left" ); + } + break; + case IDComboBox: + { + writeClass("QComboBox"); + writeCString("name", useName("ComboBox_"+widgetID) ); + if ( isControl ) + writeRect( "geometry", x,y,w,14 ); + else + writeRect( "geometry", x,y,w,h ); + } + break; + case IDListBox: + { + isFrame = TRUE; + writeClass("QListBox"); + writeCString("name", useName("ListBox_"+widgetID) ); + writeRect( "geometry", x,y,w,h ); + if ( styles.contains("WS_HSCROLL") ) + writeEnum("hScrollBarMode", "Auto"); + else + writeEnum("hScrollBarMode", "AlwaysOff"); + if ( styles.contains("WS_VSCROLL") ) + writeEnum("vScrollBarMode", "Auto"); + else + writeEnum("vScrollBarMode", "AlwaysOff"); + if ( styles.contains("LBS_EXTENDEDSEL") ) + writeEnum("selectionMode", "Extended"); + else if ( styles.contains("LBS_MULTIPLESEL") ) + writeEnum("selectionMode", "Multi"); + else if ( styles.contains("LBS_NOSEL") ) + writeEnum("selectionMode", "NoSelection"); + else + writeEnum("selectionMode", "Single"); + if ( !styles.contains( "NO WS_BORDER" ) ) + styles.append( "WS_BORDER" ); + } + break; + case IDScrollBar: + { + writeClass("QScrollBar"); + writeCString("name", useName("ScrollBar_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + if ( styles.contains("SBS_VERT") ) + writeEnum("orientation", "Vertical"); + else + writeEnum("orientation", "Horizontal"); + } + break; + case IDCustom: + { + writeClass("QLabel"); + writeCString("name", useName("Custom_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + writeString("text", "Create a custom widget and place it here." ); + } + default: + { + writeClass("QLabel"); + writeCString("name", useName("Unknown_"+widgetID) ); + writeRect("geometry", x,y,w,h ); + writeString("text", QString("No support for %1.").arg(controlType) ); + } + break; + } + + writeStyles( styles, isFrame ); + + styles.clear(); + + undent(); + wi(); *out << "" << endl; + } while ( line != "END" ); + + undent(); + wi(); *out << "" << endl; + *out << "" << endl; + + do { + line = in->readLine(); + } while ( line.isEmpty() ); + + if ( !writeToFile ) + target.append( buffer.copy() ); + + if (out) { + delete out; + out = 0; + } + fileOut.close(); + + } while ( line != blockStart1 ); + + return TRUE; +} + +/*! Not yet implemented +*/ + +bool RC2UI::makeBitmap() +{ + return TRUE; +} + +/*! Not yet implemented +*/ + +bool RC2UI::makeAccelerator() +{ + return TRUE; +} + +/*! Not yet implemented +*/ + +bool RC2UI::makeCursor() +{ + return TRUE; +} + +/*! Not yet implemented +*/ + +bool RC2UI::makeHTML() +{ + return TRUE; +} + +/*! Not yet implemented +*/ + +bool RC2UI::makeIcon() +{ + return TRUE; +} + +/*! + Writes a stringtable from the input stream to a c++ header file. + All strings are assigned using QT_TR_NOOP to enable easy translation. +*/ + +bool RC2UI::makeStringTable() +{ + if ( !writeToFile ) + return TRUE; + + QFile fileOut; + line = in->readLine(); + do { + char stringtable[256]; + char discard[12]; + sscanf( line, "%s %s", stringtable, discard ); + if ( QString(stringtable) != "STRINGTABLE" ) + return TRUE; + do { + line = in->readLine(); + } while ( line != "BEGIN" ); + + QString outputFile = QString(stringtable).lower() + ".h"; + if (outputFile ) { + fileOut.setName( outputFile ); + if (!fileOut.open( IO_WriteOnly ) ) + qFatal( "rc2ui: Could not open output file '%s'", outputFile.latin1() ); + out = new QTextStream( &fileOut ); + } + + *out << "#ifndef STRINGTABLE_H" << endl; + *out << "#define STRINGTABLE_H" << endl; + *out << endl; + *out << "#include " << endl; + *out << "#include " << endl; + *out << endl; + + QString ID; + QString value; + do { + line = in->readLine().stripWhiteSpace(); + if ( line == "END" ) + continue; + + ID = parseNext(line, ' '); + value = parseNext(line).stripWhiteSpace(); + + *out << "static const QString " << ID << "= QT_TR_NOOP(" << value << ");" << endl; + + } while ( line != "END" ); + + *out << endl; + *out << "#endif // STRINGTABLE_H" << endl; + + do { + line = in->readLine(); + } while ( line.isEmpty() ); + + if ( out ) { + delete out; + out = 0; + } + } while ( line != blockStart1 ); + + return TRUE; +} + +/*! Not yet implemented +*/ + +bool RC2UI::makeVersion() +{ + return TRUE; +} diff --git a/tools/designer/plugins/rc/rc2ui.h b/tools/designer/plugins/rc/rc2ui.h new file mode 100644 index 0000000..8f3b1c6 --- /dev/null +++ b/tools/designer/plugins/rc/rc2ui.h @@ -0,0 +1,103 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef RC2UI_H +#define RC2UI_H + +#include +#include +#include + +class RC2UI +{ +public: + RC2UI( QTextStream* input ); + ~RC2UI(); + + bool parse(); + bool parse ( QStringList& get ); + + QStringList targetFiles; + +protected: + enum WidgetType { IDWidget, IDPushButton, IDLabel, IDCheckBox, IDRadioButton, + IDGroupBox, IDLineEdit, IDMultiLineEdit, IDIconView, IDListView, + IDProgressBar, IDTabWidget, IDSpinBox, IDSlider, IDComboBox, + IDListBox, IDScrollBar, IDCustom, IDUnknown = 0x0100 }; + bool makeDialog(); + bool makeBitmap(); + bool makeStringTable(); + bool makeAccelerator(); + bool makeCursor(); + bool makeHTML(); + bool makeIcon(); + bool makeVersion(); + + QString line; + QTextStream *in; + QStringList target; + + void indent(); + void undent(); + + QString stripQM( const QString& string ); + QString parseNext( QString& arg, char sep = ',' ); + QStringList splitStyles( const QString& styles, char sep = '|' ); + void wi(); + + void writeClass( const QString& name ); + void writeCString( const QString& name, const QString& value ); + void writeString( const QString& name, const QString& value ); + void writeRect( const QString& name, int x, int y, int w, int h ); + void writeFont( const QString& family, int pointsize ); + void writeBool( const QString& name, bool value ); + void writeNumber( const QString& name, int value ); + void writeEnum( const QString& name, const QString& value ); + void writeSet( const QString& name, const QString& value ); + + void writeStyles( const QStringList styles, bool isFrame ); +private: + int indentation; + bool writeToFile; + QTextStream* out; + + QString useName( const QString& ); + + QStringList usedNames; + + const QString blockStart1; + const QString blockStart2; +}; + +#endif diff --git a/tools/designer/plugins/wizards/images/qtwizards_menu_1.png b/tools/designer/plugins/wizards/images/qtwizards_menu_1.png new file mode 100644 index 0000000..9a62ab9 Binary files /dev/null and b/tools/designer/plugins/wizards/images/qtwizards_menu_1.png differ diff --git a/tools/designer/plugins/wizards/images/qtwizards_menu_2.png b/tools/designer/plugins/wizards/images/qtwizards_menu_2.png new file mode 100644 index 0000000..fd52607 Binary files /dev/null and b/tools/designer/plugins/wizards/images/qtwizards_menu_2.png differ diff --git a/tools/designer/plugins/wizards/images/qtwizards_menu_3.png b/tools/designer/plugins/wizards/images/qtwizards_menu_3.png new file mode 100644 index 0000000..7cf15ac Binary files /dev/null and b/tools/designer/plugins/wizards/images/qtwizards_menu_3.png differ diff --git a/tools/designer/plugins/wizards/images/qtwizards_table_1.png b/tools/designer/plugins/wizards/images/qtwizards_table_1.png new file mode 100644 index 0000000..425b133 Binary files /dev/null and b/tools/designer/plugins/wizards/images/qtwizards_table_1.png differ diff --git a/tools/designer/plugins/wizards/images/qtwizards_table_2.png b/tools/designer/plugins/wizards/images/qtwizards_table_2.png new file mode 100644 index 0000000..f729542 Binary files /dev/null and b/tools/designer/plugins/wizards/images/qtwizards_table_2.png differ diff --git a/tools/designer/plugins/wizards/images/qtwizards_table_3.png b/tools/designer/plugins/wizards/images/qtwizards_table_3.png new file mode 100644 index 0000000..472f267 Binary files /dev/null and b/tools/designer/plugins/wizards/images/qtwizards_table_3.png differ diff --git a/tools/designer/plugins/wizards/images/qtwizards_table_4.png b/tools/designer/plugins/wizards/images/qtwizards_table_4.png new file mode 100644 index 0000000..493b12e Binary files /dev/null and b/tools/designer/plugins/wizards/images/qtwizards_table_4.png differ diff --git a/tools/designer/plugins/wizards/images/re-sort.png b/tools/designer/plugins/wizards/images/re-sort.png new file mode 100644 index 0000000..43a8234 Binary files /dev/null and b/tools/designer/plugins/wizards/images/re-sort.png differ diff --git a/tools/designer/plugins/wizards/images/small/editcopy.png b/tools/designer/plugins/wizards/images/small/editcopy.png new file mode 100644 index 0000000..080db08 Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/editcopy.png differ diff --git a/tools/designer/plugins/wizards/images/small/editcut.png b/tools/designer/plugins/wizards/images/small/editcut.png new file mode 100644 index 0000000..f8bd744 Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/editcut.png differ diff --git a/tools/designer/plugins/wizards/images/small/editpaste.png b/tools/designer/plugins/wizards/images/small/editpaste.png new file mode 100644 index 0000000..dc7915e Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/editpaste.png differ diff --git a/tools/designer/plugins/wizards/images/small/filenew.png b/tools/designer/plugins/wizards/images/small/filenew.png new file mode 100644 index 0000000..4e5a172 Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/filenew.png differ diff --git a/tools/designer/plugins/wizards/images/small/fileopen.png b/tools/designer/plugins/wizards/images/small/fileopen.png new file mode 100644 index 0000000..cb18a2c Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/fileopen.png differ diff --git a/tools/designer/plugins/wizards/images/small/filesave.png b/tools/designer/plugins/wizards/images/small/filesave.png new file mode 100644 index 0000000..ad3f6f8 Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/filesave.png differ diff --git a/tools/designer/plugins/wizards/images/small/print.png b/tools/designer/plugins/wizards/images/small/print.png new file mode 100644 index 0000000..8a3640b Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/print.png differ diff --git a/tools/designer/plugins/wizards/images/small/redo.png b/tools/designer/plugins/wizards/images/small/redo.png new file mode 100644 index 0000000..3a504a2 Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/redo.png differ diff --git a/tools/designer/plugins/wizards/images/small/searchfind.png b/tools/designer/plugins/wizards/images/small/searchfind.png new file mode 100644 index 0000000..900156d Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/searchfind.png differ diff --git a/tools/designer/plugins/wizards/images/small/undo.png b/tools/designer/plugins/wizards/images/small/undo.png new file mode 100644 index 0000000..2fc8d26 Binary files /dev/null and b/tools/designer/plugins/wizards/images/small/undo.png differ diff --git a/tools/designer/plugins/wizards/main.cpp b/tools/designer/plugins/wizards/main.cpp new file mode 100644 index 0000000..617ad65 --- /dev/null +++ b/tools/designer/plugins/wizards/main.cpp @@ -0,0 +1,142 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#ifndef QT_NO_SQL +#include "sqlformwizardimpl.h" +#endif +#include "mainwindowwizard.h" +#include + +class StandardTemplateWizardInterface : public TemplateWizardInterface, public QLibraryInterface +{ +public: + StandardTemplateWizardInterface(); + virtual ~StandardTemplateWizardInterface(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT; + + QStringList featureList() const; + + void setup( const QString &templ, QWidget *widget, DesignerFormWindow *fw, QUnknownInterface *aIface ); + + bool init(); + void cleanup(); + bool canUnload() const; + +private: + bool inUse; +}; + +StandardTemplateWizardInterface::StandardTemplateWizardInterface() + : inUse( FALSE ) +{ +} + +StandardTemplateWizardInterface::~StandardTemplateWizardInterface() +{ +} + +bool StandardTemplateWizardInterface::init() +{ + return TRUE; +} + +void StandardTemplateWizardInterface::cleanup() +{ +} + +bool StandardTemplateWizardInterface::canUnload() const +{ + return !inUse; +} + +QStringList StandardTemplateWizardInterface::featureList() const +{ + QStringList list; +#ifndef QT_NO_SQL + list << "QDataBrowser" << "QDesignerDataBrowser" << "QDataView" << \ + "QDesignerDataView" << "QDataTable"; +#endif + list << "QMainWindow"; + + return list; +} + +void StandardTemplateWizardInterface::setup( const QString &templ, QWidget *widget, DesignerFormWindow *fw, QUnknownInterface *aIface ) +{ + inUse = TRUE; +#ifndef QT_NO_SQL + if ( templ == "QDesignerDataView" || + templ == "QDesignerDataBrowser" || + templ == "QDataView" || + templ == "QDataBrowser" || + templ == "QDataTable" ) { + SqlFormWizard wizard( aIface, widget, qApp->mainWidget(), fw, 0, TRUE ); + wizard.exec(); + } +#endif + if ( templ == "QMainWindow" ) { + MainWindowWizardBase wizard( qApp->mainWidget(), 0, TRUE ); + wizard.setAppInterface( aIface, fw, widget ); + wizard.exec(); + } + inUse = FALSE; +} + +QRESULT StandardTemplateWizardInterface::queryInterface( const QUuid& uuid, QUnknownInterface** iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)(TemplateWizardInterface*) this; + else if ( uuid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( uuid == IID_TemplateWizard ) + *iface = (TemplateWizardInterface*)this; + else if ( uuid == IID_QLibrary ) + *iface = (QLibraryInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +Q_EXPORT_COMPONENT() +{ + Q_CREATE_INSTANCE( StandardTemplateWizardInterface ) +} diff --git a/tools/designer/plugins/wizards/mainwindowwizard.ui b/tools/designer/plugins/wizards/mainwindowwizard.ui new file mode 100644 index 0000000..52bc752 --- /dev/null +++ b/tools/designer/plugins/wizards/mainwindowwizard.ui @@ -0,0 +1,757 @@ + +MainWindowWizardBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* +designerinterface.h +qiconset.h +qaction.h +qpixmap.h +qdict.h +mainwindowwizard.ui.h +struct DesignerFormWindow; +struct DesignerInterface; +struct QUnknownInterface; +class QWidget; +QWidget *widget; +DesignerInterface *dIface; +DesignerFormWindow *dfw; + + + + + MainWindowWizardBase + + + + 0 + 0 + 604 + 392 + + + + Main Window Wizard + + + + + + menuToolbarPage + + + Choose available menus and toolbars + + + + unnamed + + + 0 + + + 6 + + + + Spacer7 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + TextLabel4_2 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_menu_1.png + + + + + GroupBox1 + + + File Actions + + + + unnamed + + + 11 + + + 6 + + + + checkFileMenu + + + Menu + + + true + + + + + checkFileToolbar + + + Toolbar + + + true + + + + + Spacer4 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + checkCreateConnectionsFile + + + Create Slots and Connections for the actions + + + true + + + + + TextLabel2 + + + like New, Open File, Save, Print, etc. + + + + + + + GroupBox2 + + + Edit Actions + + + + unnamed + + + 11 + + + 6 + + + + checkEditToolbar + + + Toolbar + + + true + + + + + checkEditMenu + + + Menu + + + true + + + + + Spacer5 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + checkCreateConnectionsEdit + + + Create Slots and Connections for the actions + + + true + + + + + TextLabel2_2 + + + + 3 + 5 + 0 + 0 + + + + like Cut, Copy, Paste, Undo and Redo, etc. + + + + + + + GroupBox3 + + + Help Actions + + + + unnamed + + + 11 + + + 6 + + + + TextLabel2_2_2 + + + + 3 + 5 + 0 + 0 + + + + like Contents and About, etc. + + + + + checkHelpMenu + + + Menu + + + true + + + + + checkHelpToolbar + + + Toolbar + + + true + + + + + Spacer6 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + checkCreateConnectionsHelp + + + Create Slots and Connections for the actions + + + true + + + + + + + + + toolbarsPage + + + Setup Toolbar + + + + unnamed + + + 0 + + + 6 + + + + buttonToolbarActionUp + + + + + + designer_up.png + + + + + TextLabel4_3_2 + + + &Toolbar + + + listToolbar + + + + + buttonToolbarActionDown + + + + + + designer_down.png + + + + + listToolbarActions + + + + + listToolbar + + + + + Layout20_2 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel5_2 + + + &Category + + + comboToolbar + + + + + comboToolbar + + + + 7 + 0 + 0 + 0 + + + + + + + + TextLabel4_4 + + + &Actions + + + listToolbarActions + + + + + buttonToolbarRemoveAction + + + + + + designer_left.png + + + + + TextLabel4_2_2_2 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_menu_2.png + + + + + buttonToolbarAddAction + + + + + + designer_right.png + + + + + Spacer11 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Spacer12 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Spacer13 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + finishPage + + + Finish + + + + unnamed + + + 0 + + + 6 + + + + TextLabel4_2_2_2_2 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_menu_3.png + + + + + TextLabel1_5 + + + Press Finish to populate the main window. + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Spacer1_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + comboToolbar + activated(const QString&) + MainWindowWizardBase + currentToolbarChanged(const QString&) + + + buttonToolbarAddAction + clicked() + MainWindowWizardBase + toolbarAddAction() + + + buttonToolbarRemoveAction + clicked() + MainWindowWizardBase + toolbarRemoveAction() + + + buttonToolbarActionUp + clicked() + MainWindowWizardBase + toolbarActionUp() + + + buttonToolbarActionDown + clicked() + MainWindowWizardBase + toolbarActionDown() + + + MainWindowWizardBase + selected(const QString&) + MainWindowWizardBase + pageSelected(const QString&) + + + checkHelpMenu + toggled(bool) + MainWindowWizardBase + currentSettingChanged() + + + checkHelpToolbar + toggled(bool) + MainWindowWizardBase + currentSettingChanged() + + + checkEditMenu + toggled(bool) + MainWindowWizardBase + currentSettingChanged() + + + checkEditToolbar + toggled(bool) + MainWindowWizardBase + currentSettingChanged() + + + checkFileMenu + toggled(bool) + MainWindowWizardBase + currentSettingChanged() + + + checkFileToolbar + toggled(bool) + MainWindowWizardBase + currentSettingChanged() + + init() + destroy() + currentSettingChanged() + setupToolbarPage() + toolbarActionDown() + toolbarActionUp() + toolbarAddAction() + toolbarRemoveAction() + accept() + currentToolbarChanged( const QString & s ) + getPixmap( const QString & n, QPixmap & pix ) + pageSelected( const QString & ) + setAppInterface( QUnknownInterface * iface, DesignerFormWindow * fw, QWidget * w ) + + + checkFileMenu + checkFileToolbar + checkEditMenu + checkEditToolbar + checkHelpMenu + checkHelpToolbar + comboToolbar + listToolbarActions + buttonToolbarAddAction + buttonToolbarRemoveAction + buttonToolbarActionUp + buttonToolbarActionDown + listToolbar + + diff --git a/tools/designer/plugins/wizards/mainwindowwizard.ui.h b/tools/designer/plugins/wizards/mainwindowwizard.ui.h new file mode 100644 index 0000000..8155e62 --- /dev/null +++ b/tools/designer/plugins/wizards/mainwindowwizard.ui.h @@ -0,0 +1,321 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +void MainWindowWizardBase::init() +{ + dIface = 0; + dfw = 0; + widget = 0; + setHelpEnabled( menuToolbarPage, FALSE ); + setHelpEnabled( toolbarsPage, FALSE ); + setHelpEnabled( finishPage, FALSE ); + setFinishEnabled( finishPage, TRUE ); +} + +void MainWindowWizardBase::destroy() +{ + if ( dIface ) + dIface->release(); +} + +void MainWindowWizardBase::currentSettingChanged() +{ + bool appr = checkFileToolbar->isChecked() || checkEditToolbar->isChecked() || checkHelpToolbar->isChecked(); + setAppropriate( toolbarsPage, appr ); +} + +void MainWindowWizardBase::setupToolbarPage() +{ + if ( checkFileToolbar->isChecked() ) + comboToolbar->insertItem( tr( "File" ) ); + if ( checkEditToolbar->isChecked() ) + comboToolbar->insertItem( tr( "Edit" ) ); + if ( checkHelpToolbar->isChecked() ) + comboToolbar->insertItem( tr( "Help" ) ); +} + +void MainWindowWizardBase::toolbarActionDown() +{ + if ( listToolbar->currentItem() < 0 || listToolbar->currentItem() >= (int)listToolbar->count() - 1 ) + return; + + int next = listToolbar->currentItem() + 1; + QString tmp = listToolbar->text( next ); + listToolbar->changeItem( listToolbar->text( next - 1 ), next ); + listToolbar->changeItem( tmp, next - 1 ); + listToolbar->setCurrentItem( next ); +} + +void MainWindowWizardBase::toolbarActionUp() +{ + if ( listToolbar->currentItem() < 1 || listToolbar->currentItem() > (int)listToolbar->count() - 1 ) + return; + + int prev = listToolbar->currentItem() - 1; + QString tmp = listToolbar->text( prev ); + listToolbar->changeItem( listToolbar->text( prev + 1 ), prev ); + listToolbar->changeItem( tmp, prev + 1 ); + listToolbar->setCurrentItem( prev ); +} + +void MainWindowWizardBase::toolbarAddAction() +{ + if ( listToolbarActions->text( listToolbarActions->currentItem() ).isEmpty() ) + return; + listToolbar->insertItem( listToolbarActions->text( listToolbarActions->currentItem() ) ); + listToolbar->setCurrentItem( listToolbar->count() - 1 ); + listToolbarActions->setCurrentItem( listToolbarActions->currentItem() + 1 ); +} + +void MainWindowWizardBase::toolbarRemoveAction() +{ + listToolbar->removeItem( listToolbar->currentItem() ); +} + +static void devNull( QtMsgType, const char * ) +{ +} + +void MainWindowWizardBase::accept() +{ + if ( !dfw || !dIface || !widget ) { + QWizard::accept(); + return; + } + + setFinishEnabled( finishPage, FALSE ); + + QPixmap pix; + + QDict actions; + QPtrList usedActions; + + QtMsgHandler oldMsgHandler = qInstallMsgHandler( devNull ); + + getPixmap( "filenew", pix ); + + QAction *fileNewAction = dfw->createAction( tr( "New" ), pix, tr( "&New" ), CTRL + Key_N, 0, "fileNewAction" ); + actions.insert( tr( "New" ), fileNewAction ); + getPixmap( "fileopen", pix ); + QAction *fileOpenAction = dfw->createAction( tr( "Open" ), pix, tr( "&Open..." ), CTRL + Key_O, 0, "fileOpenAction" ); + actions.insert( tr( "Open" ), fileOpenAction ); + getPixmap( "filesave", pix ); + QAction *fileSaveAction = dfw->createAction( tr( "Save" ), pix, tr( "&Save" ), CTRL + Key_S, 0, "fileSaveAction" ); + actions.insert( tr( "Save" ), fileSaveAction ); + QAction *fileSaveAsAction = dfw->createAction( tr( "Save As" ), QIconSet(), tr( "Save &As..." ), 0, 0, "fileSaveAsAction" ); + actions.insert( tr( "Save As" ), fileSaveAsAction ); + getPixmap( "print", pix ); + QAction *filePrintAction = dfw->createAction( tr( "Print" ), pix, tr( "&Print..." ), CTRL + Key_P, 0, "filePrintAction" ); + actions.insert( tr( "Print" ), filePrintAction ); + QAction *fileExitAction = dfw->createAction( tr( "Exit" ), QIconSet(), tr( "E&xit" ), 0, 0, "fileExitAction" ); + actions.insert( tr( "Exit" ), fileExitAction ); + + getPixmap( "undo", pix ); + QAction *editUndoAction = dfw->createAction( tr( "Undo" ), pix, tr( "&Undo" ), CTRL + Key_Z, 0, "editUndoAction" ); + actions.insert( tr( "Undo" ), editUndoAction ); + getPixmap( "redo", pix ); + QAction *editRedoAction = dfw->createAction( tr( "Redo" ), pix, tr( "&Redo" ), CTRL + Key_Y, 0, "editRedoAction" ); + actions.insert( tr( "Redo" ), editRedoAction ); + getPixmap( "editcut", pix ); + QAction *editCutAction = dfw->createAction( tr( "Cut" ), pix, tr( "Cu&t" ), CTRL + Key_X, 0, "editCutAction" ); + actions.insert( tr( "Cut" ), editCutAction ); + getPixmap( "editcopy", pix ); + QAction *editCopyAction = dfw->createAction( tr( "Copy" ), pix, tr( "&Copy" ), CTRL + Key_C, 0, "editCopyAction" ); + actions.insert( tr( "Copy" ), editCopyAction ); + getPixmap( "editpaste", pix ); + QAction *editPasteAction = dfw->createAction( tr( "Paste" ), pix, tr( "&Paste" ), CTRL + Key_V, 0, "editPasteAction" ); + actions.insert( tr( "Paste" ), editPasteAction ); + getPixmap( "searchfind", pix ); + QAction *editFindAction = dfw->createAction( tr( "Find" ), pix, tr( "&Find..." ), CTRL + Key_F, 0, "editFindAction" ); + actions.insert( tr( "Find" ), editFindAction ); + + QAction *helpAboutAction = dfw->createAction( tr( "About" ), QIconSet(), tr( "&About" ), 0, 0, "helpAboutAction" ); + actions.insert( tr( "About" ), helpAboutAction ); + QAction *helpContentsAction = dfw->createAction( tr( "Contents" ), QIconSet(), tr( "&Contents..." ), 0, 0, "helpContentsAction" ); + actions.insert( tr( "Contents" ), helpContentsAction ); + QAction *helpIndexAction = dfw->createAction( tr( "Index" ), QIconSet(), tr( "&Index..." ), 0, 0, "helpIndexAction" ); + actions.insert( tr( "Index" ), helpIndexAction ); + + if ( checkFileMenu->isChecked() ) { + dfw->addMenu( "&File", "fileMenu" ); + dfw->addMenuAction( "fileMenu", fileNewAction ); + dfw->addMenuAction( "fileMenu", fileOpenAction ); + dfw->addMenuAction( "fileMenu", fileSaveAction ); + dfw->addMenuAction( "fileMenu", fileSaveAsAction ); + dfw->addMenuSeparator( "fileMenu" ); + dfw->addMenuAction( "fileMenu", filePrintAction ); + dfw->addMenuSeparator( "fileMenu" ); + dfw->addMenuAction( "fileMenu", fileExitAction ); + dfw->addAction( fileNewAction ); + dfw->addAction( fileOpenAction ); + dfw->addAction( fileSaveAction ); + dfw->addAction( fileSaveAsAction ); + dfw->addAction( filePrintAction ); + dfw->addAction( fileExitAction ); + usedActions.append( fileNewAction ); + usedActions.append( fileOpenAction ); + usedActions.append( fileSaveAction ); + usedActions.append( fileSaveAsAction ); + usedActions.append( filePrintAction ); + usedActions.append( fileExitAction ); + } + + if ( checkEditMenu->isChecked() ) { + dfw->addMenu( "&Edit", "editMenu" ); + dfw->addMenuAction( "editMenu", editUndoAction ); + dfw->addMenuAction( "editMenu", editRedoAction ); + dfw->addMenuSeparator( "editMenu" ); + dfw->addMenuAction( "editMenu", editCutAction ); + dfw->addMenuAction( "editMenu", editCopyAction ); + dfw->addMenuAction( "editMenu", editPasteAction ); + dfw->addMenuSeparator( "editMenu" ); + dfw->addMenuAction( "editMenu", editFindAction ); + dfw->addAction( editUndoAction ); + dfw->addAction( editRedoAction ); + dfw->addAction( editCutAction ); + dfw->addAction( editCopyAction ); + dfw->addAction( editPasteAction ); + dfw->addAction( editFindAction ); + usedActions.append( editUndoAction ); + usedActions.append( editRedoAction ); + usedActions.append( editCutAction ); + usedActions.append( editCopyAction ); + usedActions.append( editPasteAction ); + usedActions.append( editFindAction ); + } + + if ( checkHelpMenu->isChecked() ) { + dfw->addMenu( "&Help", "helpMenu" ); + dfw->addMenuAction( "helpMenu", helpContentsAction ); + dfw->addMenuAction( "helpMenu", helpIndexAction ); + dfw->addMenuSeparator( "helpMenu" ); + dfw->addMenuAction( "helpMenu", helpAboutAction ); + dfw->addAction( helpContentsAction ); + dfw->addAction( helpIndexAction ); + dfw->addAction( helpAboutAction ); + usedActions.append( helpIndexAction ); + usedActions.append( helpContentsAction ); + usedActions.append( helpAboutAction ); + } + + if ( listToolbar->count() > 0 && appropriate( toolbarsPage ) ) { + dfw->addToolBar( "Tools", "toolBar" ); + for ( int i = 0; i < (int)listToolbar->count(); ++i ) { + if ( listToolbar->text( i ) == tr( "" ) ) { + dfw->addToolBarSeparator( "toolBar" ); + continue; + } + QAction *a = actions.find( listToolbar->text( i ) ); + if ( !a ) + continue; + dfw->addToolBarAction( "toolBar", a ); + dfw->addAction( a ); + if ( usedActions.findRef( a ) == -1 ) + usedActions.append( a ); + } + } + for ( QAction *ac = usedActions.first(); ac; ac = usedActions.next() ) { + if ( QString( ac->name() ).find( "file" ) != -1 && checkCreateConnectionsFile->isChecked() || + QString( ac->name() ).find( "edit" ) != -1 && checkCreateConnectionsEdit->isChecked() || + QString( ac->name() ).find( "help" ) != -1 && checkCreateConnectionsHelp->isChecked() ) { + QString slot = ac->name(); + slot.remove( slot.length() - 6, 6 ); + slot += "()"; + dfw->addFunction( slot.latin1(), "virtual", "public", "slot", dIface->currentProject()->language(), "void" ); + dfw->addConnection( ac, "activated()", widget, slot ); + } + } + + qInstallMsgHandler( oldMsgHandler ); + + QWizard::accept(); +} + +void MainWindowWizardBase::currentToolbarChanged( const QString & s ) +{ + if ( s == tr( "File" ) ) { + listToolbarActions->clear(); + listToolbarActions->insertItem( tr( "New" ) ); + listToolbarActions->insertItem( tr( "Open" ) ); + listToolbarActions->insertItem( tr( "Save" ) ); + listToolbarActions->insertItem( tr( "Save As" ) ); + listToolbarActions->insertItem( tr( "Print" ) ); + listToolbarActions->insertItem( tr( "Exit" ) ); + } else if ( s == tr( "Edit" ) ) { + listToolbarActions->clear(); + listToolbarActions->insertItem( tr( "Undo" ) ); + listToolbarActions->insertItem( tr( "Redo" ) ); + listToolbarActions->insertItem( tr( "Cut" ) ); + listToolbarActions->insertItem( tr( "Copy" ) ); + listToolbarActions->insertItem( tr( "Paste" ) ); + listToolbarActions->insertItem( tr( "Find" ) ); + } else if ( s == tr( "Help" ) ) { + listToolbarActions->clear(); + listToolbarActions->insertItem( tr( "Contents" ) ); + listToolbarActions->insertItem( tr( "Index" ) ); + listToolbarActions->insertItem( tr( "About" ) ); + } + listToolbarActions->insertItem( "" ); + listToolbarActions->setCurrentItem( 0 ); +} + +void MainWindowWizardBase::getPixmap( const QString & n, QPixmap & pix ) +{ + QString name = n + ".png"; + pix = QPixmap::fromMimeSource( name ); + DesignerProject *pro = dIface->currentProject(); + if ( !pro || pro->projectName() == "" ) + return; + pro->pixmapCollection()->addPixmap( pix, n, FALSE ); +} + +void MainWindowWizardBase::pageSelected( const QString & ) +{ + if ( currentPage() == toolbarsPage ) { + comboToolbar->clear(); + setupToolbarPage(); + listToolbarActions->clear(); + currentToolbarChanged( comboToolbar->text( comboToolbar->currentItem() ) ); + } +} + +void MainWindowWizardBase::setAppInterface( QUnknownInterface * iface, DesignerFormWindow * fw, QWidget * w ) +{ + DesignerInterface *d = 0; + iface->queryInterface( IID_Designer, (QUnknownInterface**)&d ); + dIface = d; + dfw = fw; + widget = w; +} + diff --git a/tools/designer/plugins/wizards/sqlformwizard.ui b/tools/designer/plugins/wizards/sqlformwizard.ui new file mode 100644 index 0000000..c4ee673 --- /dev/null +++ b/tools/designer/plugins/wizards/sqlformwizard.ui @@ -0,0 +1,1776 @@ + +SqlFormWizardBase +********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + SqlFormWizardBase + + + + 0 + 0 + 577 + 570 + + + + Sql Wizard + + + + + + + + + + + databasePage + + + Choose the Database and Table + + + + unnamed + + + 0 + + + 6 + + + + TextLabel4 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_table_1.png + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel3_2 + + + &Table: + + + listBoxTable + + + + + Layout4 + + + + unnamed + + + 0 + + + 6 + + + + PushButton5 + + + &Setup Database Connections... + + + Click here to manage your database connections + + + Here you can add, modify and delete your database connections + + + + + Spacer1_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + TextLabel3_3 + + + Database &Connection: + + + listBoxConnection + + + + + listBoxTable + + + Displays all tables inside the selected Database + + + + + listBoxConnection + + + Displays a list of available connections on your system + + + + + + + + + populatePage + + + Displayed Fields + + + + unnamed + + + 0 + + + 6 + + + + TextLabel4_2 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_table_2.png + + + + + Layout11 + + + + unnamed + + + 0 + + + 6 + + + + Spacer1_10 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonAddField_2 + + + + + + designer_right.png + + + Move field to list of displayed fields + + + Click here to add the selected field to the list of fields that will be displayed. + + + + + buttonRemoveField_2 + + + + + + designer_left.png + + + remove field from list of displayed fields + + + Click here to remove the selected field from the list of fields that will be displayed. + + + + + Spacer2_5 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonFieldUp_2 + + + + + + designer_up.png + + + Move Field up + + + Click here to move the selected field in the displayed fields list up. + + + + + Spacer3_3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + listBoxField + + + This is a list of all available fields in your selected table. Fields in this list will not be displayed. + + + + + buttonFieldDown_2 + + + + + + designer_down.png + + + Move field down + + + Click here to move the selected field in the displayed fields list down. + + + + + listBoxSelectedField + + + All fields in this list will be displayed. + + + + + TextLabel2_3 + + + Displayed Fields: + + + + + TextLabel1_7 + + + Available Fields: + + + + + + + + + navigPage + + + Navigation and Editing + + + + unnamed + + + 0 + + + 6 + + + + TextLabel4_2_2 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_table_3.png + + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + checkBoxNavig + + + &Include Navigation Buttons + + + true + + + Activates the navigation bar + + + Activates the navigation bar + + + + + GroupBox2 + + + + 5 + 7 + 0 + 0 + + + + &Navigation + + + + unnamed + + + 11 + + + 6 + + + + checkBoxPrev + + + &Previous + + + true + + + Toggles whether the "Previous" button will be displayed + + + Toggles whether the "Previous" button will be displayed + + + + + checkBoxNext + + + &Next + + + true + + + Toggles whether the "Next" button will be displayed + + + Toggles whether the "Next" button will be displayed + + + + + checkBoxFirst + + + &First + + + true + + + Toggles whether the "First" button will be displayed + + + Toggles whether the "First" button will be displayed + + + + + checkBoxLast + + + &Last + + + true + + + Toggles whether the "Last" button will be displayed + + + Toggles whether the "Last" button will be displayed + + + + + + + checkBoxEdit + + + In&clude Edit Buttons + + + true + + + Activates the edit bar + + + Activates the edit bar + + + + + GroupBox3 + + + + 5 + 7 + 0 + 0 + + + + &Editing + + + + unnamed + + + 11 + + + 6 + + + + checkBoxInsert + + + &Insert + + + true + + + User can insert new rows + + + User can insert new rows + + + + + checkBoxUpdate + + + &Update + + + true + + + user can edit existing rows + + + user can edit existing rows + + + + + checkBoxDelete + + + &Delete + + + true + + + user can delete rows + + + user can delete rows + + + + + + + Spacer1_3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + tablePropertiesPage + + + Table Properties + + + + unnamed + + + 0 + + + 6 + + + + TextLabel4_2_2_2_2 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_table_4.png + + + + + Spacer1_7 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + GroupBox5 + + + Editing + + + + unnamed + + + 11 + + + 6 + + + + checkBoxReadOnly + + + &Read-Only + + + Table will be read-only + + + Activate this to prevent editing, deleting and adding of rows + + + + + GroupBox4 + + + Confirmations + + + + unnamed + + + 11 + + + 6 + + + + checkBoxConfirmInserts + + + Confirm &Inserts + + + Query user on inserting rows + + + User will be asked for confirmation if he inserts a new row + + + + + checkBoxConfirmUpdates + + + Confirm &Updates + + + Query user on editing rows + + + User will be asked for confirmation if he edits a row + + + + + checkBoxConfirmCancels + + + Confirm &Cancels + + + Query user on canceling + + + User will be asked for confirmation if he cancels an action + + + + + checkBoxConfirmDeletes + + + Confirm &Deletes + + + true + + + Query user on deleting rows + + + User will be asked for confirmation if he deletes a row + + + + + + + + + checkBoxSorting + + + Allow column &sorting + + + true + + + User may change sorting + + + User may change sorting of data by clicking on a field in the top row of the table + + + + + + + sqlPage + + + SQL + + + + unnamed + + + 0 + + + 6 + + + + TextLabel4_2_2_2 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_table_2.png + + + + + Layout8 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel3_2_2_2 + + + &Sort: + + + listBoxTable + + + + + Spacer1_5 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + Layout10 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel3_2_2 + + + &Filter: + + + listBoxTable + + + + + Spacer1_4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + Layout13 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1_3 + + + (a valid WHERE clause, e.g. id > 100) + + + + + editFilter + + + Enter a valid SQL WHERE statement, for example: +name like "qt%" +(name like "q%") and (version > 3) +((version > 3) and (price > 1000)) or (name like "%embed%") + + + + + + + Layout10 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel2 + + + Sort By + + + + + listBoxSortedField + + + Data will be sorted according to the selected fields. + + + + + + + Layout11 + + + + unnamed + + + 0 + + + 6 + + + + Spacer2_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonAddSortField + + + + + + designer_right.png + + + Move field to the right list + + + Klick here to add the currently selected field from the available fields list to the sorting criteria + + + + + buttonRemoveSortField + + + + + + designer_left.png + + + remove field from the right list + + + Klick here to remove the currently selected field from the sorting criteria + + + + + Spacer1_6 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonUpSortField + + + + + + designer_up.png + + + move field up + + + Move selected field in the sort by list up + + + + + buttonDownSortField + + + + + + designer_down.png + + + move field down + + + Move selected field in the sort by list down + + + + + Spacer2_3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buttonReSortField + + + + + + re-sort.png + + + Change field sort from ASC to DESC and back + + + Changes the field sort order from ascending to descending for the selected field in the sort by list. + + + + + + + Layout12 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1_4 + + + Available Fields + + + + + listBoxSortField + + + This is the list of all available fields in the selected table + + + + + + + + + layoutPage + + + Layout + + + + unnamed + + + 0 + + + 6 + + + + TextLabel4_2_2_2_3_2 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_table_3.png + + + + + Spacer1_9 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + ButtonGroup1 + + + &Labels + + + + unnamed + + + 11 + + + 6 + + + + radioLabelsLeft + + + true + + + Labels to &left + + + true + + + Create labels to the left of data entry fields. + + + + + TextLabel3 + + + + 3 + 1 + 0 + 0 + + + + Create labels above data entry fields. + + + + + TextLabel2_2 + + + + 3 + 1 + 0 + 0 + + + + Create labels to the left of data entry fields. + + + + + Spacer4 + + + Horizontal + + + Maximum + + + + 20 + 20 + + + + + + Spacer5 + + + Horizontal + + + Maximum + + + + 16 + 20 + + + + + + radioLabelsTop + + + Labels on &top + + + Create labels above data entry fields. + + + + + + + checkCreateLayouts + + + &Create layout for all + + + true + + + Create a BoxLayout around the whole widget + + + If you select this a BoxLayout will be created for the whole widget + + + + + checkCreateButtonLayout + + + Create layout for &buttons + + + true + + + Create a BoxLayout around the buttons + + + If you select this the designer will arrange all buttons inside an BoxLayout + + + + + checkCreateFieldLayout + + + Create layout for &fields + + + true + + + Create a BoxLayout around the fields + + + If you select this the designer will arrange all fields inside an BoxLayout + + + + + spinNumberOfColumns + + + 20 + + + 2 + + + Enter the number of desired columns + + + Enter the number of desired columns + + + + + TextLabel1_6 + + + Number of Columns: + + + + + Spacer3_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + finishPage + + + Finish + + + + unnamed + + + 0 + + + 6 + + + + TextLabel4_2_2_2_3 + + + + 0 + 7 + 0 + 0 + + + + + + + qtwizards_table_1.png + + + + + TextLabel1_5 + + + Press Finish to create the widget. + + + + + Spacer2_4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + checkBoxAutoEdit + + + &AutoEditing + + + Discard changes when user klicks into another row + + + This property holds whether the table automatically applies edits. When the user begins an insert or update in the table there are two possible outcomes when they navigate to another record +1.the insert or update is is performed -- this occurs if AutoEditing is on +2.the insert or update is abandoned -- this occurs if AutoEditing is off + + + + + + + + PushButton5 + clicked() + SqlFormWizardBase + setupDatabaseConnections() + + + checkBoxNavig + toggled(bool) + GroupBox2 + setEnabled(bool) + + + checkBoxEdit + toggled(bool) + GroupBox3 + setEnabled(bool) + + + buttonReSortField + clicked() + SqlFormWizardBase + reSortSortField() + + + buttonRemoveSortField + clicked() + SqlFormWizardBase + removeSortField() + + + buttonAddSortField + clicked() + SqlFormWizardBase + addSortField() + + + buttonUpSortField + clicked() + SqlFormWizardBase + sortFieldUp() + + + buttonDownSortField + clicked() + SqlFormWizardBase + sortFieldDown() + + + listBoxSortField + doubleClicked(QListBoxItem*) + SqlFormWizardBase + addSortField() + + + listBoxSortedField + doubleClicked(QListBoxItem*) + SqlFormWizardBase + removeSortField() + + + listBoxSortedField + rightButtonClicked(QListBoxItem*,const QPoint&) + SqlFormWizardBase + reSortSortField() + + + checkBoxReadOnly + toggled(bool) + GroupBox4 + setDisabled(bool) + + + listBoxConnection + highlighted(const QString&) + SqlFormWizardBase + connectionSelected(const QString&) + + + listBoxTable + highlighted(const QString&) + SqlFormWizardBase + tableSelected(const QString&) + + + buttonAddField_2 + released() + SqlFormWizardBase + addField() + + + buttonRemoveField_2 + clicked() + SqlFormWizardBase + removeField() + + + buttonFieldUp_2 + clicked() + SqlFormWizardBase + fieldUp() + + + buttonFieldDown_2 + clicked() + SqlFormWizardBase + fieldDown() + + + + PushButton5 + listBoxConnection + listBoxTable + checkBoxNavig + checkBoxPrev + checkBoxNext + checkBoxFirst + checkBoxLast + checkBoxEdit + checkBoxInsert + checkBoxUpdate + checkBoxDelete + checkBoxReadOnly + checkBoxConfirmInserts + checkBoxConfirmUpdates + checkBoxConfirmDeletes + checkBoxConfirmCancels + checkBoxSorting + editFilter + listBoxSortField + buttonAddSortField + buttonRemoveSortField + buttonUpSortField + buttonDownSortField + buttonReSortField + listBoxSortedField + spinNumberOfColumns + radioLabelsLeft + radioLabelsTop + checkCreateFieldLayout + checkCreateButtonLayout + checkCreateLayouts + + + init() + destroy() + addField() + addSortField() + fieldDown() + fieldUp() + reSortSortField() + removeField() + removeSortField() + setupDatabaseConnections() + sortFieldDown() + sortFieldUp() + connectionSelected( const QString & ) + tableSelected( const QString & ) + + + + diff --git a/tools/designer/plugins/wizards/sqlformwizardimpl.cpp b/tools/designer/plugins/wizards/sqlformwizardimpl.cpp new file mode 100644 index 0000000..7519877 --- /dev/null +++ b/tools/designer/plugins/wizards/sqlformwizardimpl.cpp @@ -0,0 +1,624 @@ + /********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "sqlformwizardimpl.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_SQL +#include +#include +#include +#include +#include +#include +#endif + +SqlFormWizard::SqlFormWizard( QUnknownInterface *aIface, QWidget *w, + QWidget* parent, DesignerFormWindow *fw, const char* name, bool modal, WFlags fl ) + : SqlFormWizardBase( parent, name, modal, fl ), widget( w ), appIface( aIface ), + mode( None ) +{ + appIface->addRef(); + formWindow = fw; + setFinishEnabled( finishPage, TRUE ); + + /* set mode of operation */ + if ( ::qt_cast(widget) ) { + setCaption( "Data Table Wizard" ); + mode = Table; + setAppropriate( navigPage, FALSE ); + setAppropriate( layoutPage, FALSE ); + checkBoxAutoEdit->setChecked( FALSE ); + } else if ( ::qt_cast(widget) ) { + setCaption( "Data Browser Wizard" ); + setAppropriate( tablePropertiesPage, FALSE ); + mode = Browser; + checkBoxAutoEdit->setChecked( TRUE ); + } else if ( ::qt_cast(widget) ) { + setCaption( "Data View Wizard" ); + setAppropriate( tablePropertiesPage, FALSE ); + setAppropriate( navigPage, FALSE ); + setAppropriate( sqlPage, FALSE); + checkCreateFieldLayout->hide(); + checkCreateButtonLayout->hide(); + checkBoxAutoEdit->hide(); + mode = View; + } + + connect( nextButton(), SIGNAL(clicked()), SLOT(nextPageClicked()) ); + setupPage1(); +} + + +SqlFormWizard::~SqlFormWizard() +{ + appIface->release(); +} + +void SqlFormWizard::nextPageClicked() +{ + if ( currentPage() == populatePage ) { + autoPopulate( TRUE ); + } +} + +void SqlFormWizard::connectionSelected( const QString &c ) +{ + if ( !appIface ) + return; + + DesignerProject *proIface = (DesignerProject*)( (DesignerInterface*)appIface )->currentProject(); + if ( !proIface ) + return; + + listBoxTable->clear(); + QPtrList databases = proIface->databaseConnections(); + for ( DesignerDatabase *d = databases.first(); d; d = databases.next() ) { + if ( d->name() == c || ( d->name() == "(default)" || d->name().isEmpty() ) && c == "(default)") + listBoxTable->insertStringList( d->tables() ); + } + setNextEnabled( databasePage, ( listBoxTable->currentItem() >= 0 ) ); +} + +void SqlFormWizard::tableSelected( const QString & ) +{ + if ( listBoxTable->currentItem() >= 0 ) { + setNextEnabled( databasePage, TRUE ); + } else { + setNextEnabled( databasePage, FALSE ); + } + +} + +void SqlFormWizard::autoPopulate( bool populate ) +{ + DesignerProject *proIface = (DesignerProject*)( (DesignerInterface*)appIface )->currentProject(); + if ( !proIface ) + return; + QPtrList databases = proIface->databaseConnections(); + listBoxField->clear(); + listBoxSortField->clear(); + listBoxSelectedField->clear(); + if ( populate ) { + for ( DesignerDatabase *d = databases.first(); d; d = databases.next() ) { + if ( d->name() == listBoxConnection->currentText() || + ( ( d->name() == "(default)" || d->name().isEmpty() ) && + listBoxConnection->currentText() == "(default)" ) ) { + QStringList lst = *d->fields().find( listBoxTable->currentText() ); + // remove primary index fields, if any + listBoxSortField->insertStringList( lst ); + d->open( FALSE ); +#ifndef QT_NO_SQL + QSqlCursor tab( listBoxTable->currentText(), TRUE, d->connection() ); + QSqlIndex pIdx = tab.primaryIndex(); + for ( uint i = 0; i < pIdx.count(); i++ ) { + listBoxField->insertItem( pIdx.field( i )->name() ); + lst.remove( pIdx.field( i )->name() ); + } +#endif + d->close(); + listBoxSelectedField->insertStringList( lst ); + } + } + } +} + +void SqlFormWizard::fieldDown() +{ + if ( listBoxSelectedField->currentItem() == -1 || + listBoxSelectedField->currentItem() == (int)listBoxSelectedField->count() - 1 || + listBoxSelectedField->count() < 2 ) + return; + int index = listBoxSelectedField->currentItem() + 1; + QListBoxItem *i = listBoxSelectedField->item( listBoxSelectedField->currentItem() ); + listBoxSelectedField->takeItem( i ); + listBoxSelectedField->insertItem( i, index ); + listBoxSelectedField->setCurrentItem( i ); +} + +void SqlFormWizard::fieldUp() +{ + if ( listBoxSelectedField->currentItem() <= 0 || + listBoxSelectedField->count() < 2 ) + return; + int index = listBoxSelectedField->currentItem() - 1; + QListBoxItem *i = listBoxSelectedField->item( listBoxSelectedField->currentItem() ); + listBoxSelectedField->takeItem( i ); + listBoxSelectedField->insertItem( i, index ); + listBoxSelectedField->setCurrentItem( i ); +} + +void SqlFormWizard::removeField() +{ + int i = listBoxSelectedField->currentItem(); + if ( i != -1 ) { + listBoxField->insertItem( listBoxSelectedField->currentText() ); + listBoxSelectedField->removeItem( i ); + } +} + +void SqlFormWizard::addField() +{ + int i = listBoxField->currentItem(); + if ( i == -1 ) + return; + QString f = listBoxField->currentText(); + if ( !f.isEmpty() ) + listBoxSelectedField->insertItem( f ); + listBoxField->removeItem( i ); +} + +void SqlFormWizard::addSortField() +{ + int i = listBoxSortField->currentItem(); + if ( i == -1 ) + return; + QString f = listBoxSortField->currentText(); + if ( !f.isEmpty() ) + listBoxSortedField->insertItem( f + " ASC" ); +} + +void SqlFormWizard::reSortSortField() +{ + int i = listBoxSortedField->currentItem(); + if ( i != -1 ) { + QString text = listBoxSortedField->currentText(); + if ( text.mid( text.length() - 3 ) == "ASC" ) + text = text.mid( 0, text.length() - 3 ) + "DESC"; + else if ( text.mid( text.length() - 4 ) == "DESC" ) + text = text.mid( 0, text.length() - 4 ) + "ASC"; + listBoxSortedField->removeItem( i ); + listBoxSortedField->insertItem( text, i ); + listBoxSortedField->setCurrentItem( i ); + } +} + +void SqlFormWizard::removeSortField() +{ + int i = listBoxSortedField->currentItem(); + if ( i != -1 ) { + listBoxSortedField->removeItem( i ); + } +} + +void SqlFormWizard::sortFieldUp() +{ + if ( listBoxSortedField->currentItem() <= 0 || + listBoxSortedField->count() < 2 ) + return; + int index = listBoxSortedField->currentItem() - 1; + QListBoxItem *i = listBoxSortedField->item( listBoxSortedField->currentItem() ); + listBoxSortedField->takeItem( i ); + listBoxSortedField->insertItem( i, index ); + listBoxSortedField->setCurrentItem( i ); +} + +void SqlFormWizard::sortFieldDown() +{ + if ( listBoxSortedField->currentItem() == -1 || + listBoxSortedField->currentItem() == (int)listBoxSortedField->count() - 1 || + listBoxSortedField->count() < 2 ) + return; + int index = listBoxSortedField->currentItem() + 1; + QListBoxItem *i = listBoxSortedField->item( listBoxSortedField->currentItem() ); + listBoxSortedField->takeItem( i ); + listBoxSortedField->insertItem( i, index ); + listBoxSortedField->setCurrentItem( i ); +} + +void SqlFormWizard::setupDatabaseConnections() +{ + if ( !appIface ) + return; + + DesignerProject *proIface = (DesignerProject*)( (DesignerInterface*)appIface )->currentProject(); + if ( !proIface ) + return; + proIface->setupDatabases(); + raise(); + setupPage1(); +} + +void SqlFormWizard::setupPage1() +{ + if ( !appIface ) + return; + + DesignerProject *proIface = (DesignerProject*)( (DesignerInterface*)appIface )->currentProject(); + if ( !proIface ) + return; + + listBoxTable->clear(); + listBoxConnection->clear(); + QPtrList databases = proIface->databaseConnections(); + QStringList lst; + for ( DesignerDatabase *d = databases.first(); d; d = databases.next() ) + lst << d->name(); + listBoxConnection->insertStringList( lst ); + if ( lst.count() ) + listBoxConnection->setCurrentItem( 0 ); + + setNextEnabled( databasePage, FALSE ); +} + +static QPushButton *create_widget( QWidget *parent, const char *name, + const QString &txt, const QRect &r, DesignerFormWindow *fw ) +{ + QPushButton *pb = (QPushButton*)fw->create( "QPushButton", parent, name ); + pb->setText( txt ); + pb->setGeometry( r ); + fw->setPropertyChanged( pb, "text", TRUE ); + fw->setPropertyChanged( pb, "geometry", TRUE ); + return pb; +} + +void SqlFormWizard::accept() +{ + if ( !appIface || mode == None ) + return; + +#ifndef QT_NO_SQL + DesignerProject *proIface = (DesignerProject*)( (DesignerInterface*)appIface )->currentProject(); + if ( !widget || !proIface ) { + SqlFormWizardBase::accept(); + return; + } + + QString conn = listBoxConnection->currentText(); + QString table = listBoxTable->currentText(); + QStringList lst; + lst << conn << table; + + if ( !conn.isEmpty() && !table.isEmpty() ) { + formWindow->setProperty( widget, "database", lst ); + formWindow->setPropertyChanged( widget, "database", TRUE ); + } + + if ( !editFilter->text().isEmpty() ) { + widget->setProperty( "filter", editFilter->text() ); + formWindow->setPropertyChanged( widget, "filter", TRUE ); + } + + if ( listBoxSortedField->count() ) { + QStringList lst; + for ( uint i = 0; i < listBoxSortedField->count(); ++i ) + lst << listBoxSortedField->text( i ); + widget->setProperty( "sort", lst ); + formWindow->setPropertyChanged( widget, "sort", TRUE ); + } + + QPtrList databases = proIface->databaseConnections(); + DesignerDatabase *database = 0; + for ( DesignerDatabase *d = databases.first(); d; d = databases.next() ) { + if ( d->name() == listBoxConnection->currentText() || ( d->name() == "(default)" || d->name().isEmpty() ) && listBoxConnection->currentText() == "(default)" ) { + database = d; + d->open( FALSE ); + break; + } + } + + if (!database) { + return; + } + QSqlCursor tab( listBoxTable->currentText(), TRUE, database->connection() ); + int columns = 2; + + QSqlEditorFactory * f = QSqlEditorFactory::defaultFactory(); + + QWidget * editorDummy; + QWidget * editor; + QLabel * label; + + int visibleFields = listBoxSelectedField->count(); + int numPerColumn = visibleFields / columns; + if( (visibleFields % columns) > 0) + numPerColumn++; + + int row = 0; + const int SPACING = 25; + const int COL_SPACING = SPACING*9; + + uint j; + switch ( mode ) { + case None: + break; + case View: + case Browser: { + + if ( mode == Browser && !checkBoxAutoEdit->isChecked() ) { + ((QDataBrowser*)widget)->setAutoEdit( FALSE ); + formWindow->setPropertyChanged( widget, "autoEdit", TRUE ); + } + + formWindow->clearSelection(); + bool createFieldLayout = checkCreateFieldLayout->isChecked(); + bool createButtonLayout = checkCreateButtonLayout->isChecked(); + bool createLayouts = checkCreateLayouts->isChecked(); + bool labelAbove = radioLabelsTop->isOn(); + uint numCols = spinNumberOfColumns->text().toInt(); + uint currentCol = 0; + uint fieldsPerCol = listBoxSelectedField->count(); + uint fieldsInCol = 0; + if ( listBoxSelectedField->count() ) + fieldsPerCol = listBoxSelectedField->count() / numCols; + /* labels and data field editors */ + for( j = 0; j < listBoxSelectedField->count(); j++ ){ + + QSqlField* field = tab.field( listBoxSelectedField->text( j ) ); + if ( !field ) + continue; + + /* label */ + QString labelName = field->name(); + labelName = labelName.mid(0,1).upper() + labelName.mid(1); + label = (QLabel*)formWindow->create( "QLabel", widget, + QString( "label" + labelName ) ); + label->setText( labelName ); + label->setGeometry( SPACING + currentCol*COL_SPACING, row+SPACING, + SPACING*3, SPACING ); + + formWindow->setPropertyChanged( label, "geometry", TRUE ); + formWindow->setPropertyChanged( label, "text", TRUE ); + + /* editor */ + editorDummy = f->createEditor( widget, field ); + editor = formWindow->create( editorDummy->className(), widget, + QString( QString( editorDummy->className() ) + + labelName) ); + delete editorDummy; + if ( labelAbove ) { + row += SPACING; + editor->setGeometry(SPACING + currentCol*COL_SPACING, row+SPACING, + SPACING*3, SPACING ); + } else { + editor->setGeometry(SPACING * 5 + currentCol*COL_SPACING, row+SPACING, + SPACING*3, SPACING ); + } + formWindow->setPropertyChanged( editor, "geometry", TRUE ); + if ( QString(editor->className()) == "QLineEdit" && + (field->type() == QVariant::Double || + field->type() == QVariant::Int || + field->type() == QVariant::UInt ) ) { + /* default right-align numerics */ + //## + ((QLineEdit*)editor)->setAlignment( Qt::AlignRight ); + formWindow->setPropertyChanged( editor, "alignment", TRUE ); + } + if ( ::qt_cast(editor) ) { + ( (QSpinBox*)editor )->setMaxValue( INT_MAX ); + formWindow->setPropertyChanged( editor, "maxValue", TRUE ); + } + QStringList lst; + lst << conn << table << field->name(); + formWindow->setProperty( editor, "database", lst ); + formWindow->setPropertyChanged( editor, "database", TRUE ); + + /* geometry */ + if ( createFieldLayout ) { + formWindow->selectWidget( label ); + formWindow->selectWidget( editor ); + } + + row += SPACING + 5; + fieldsInCol++; + if ( ( fieldsInCol >= fieldsPerCol ) && ( currentCol < numCols-1 ) ) { + currentCol++; + fieldsInCol = 0; + row = 0; + } + } + + if ( listBoxSelectedField->count() ) { + if ( createFieldLayout ) + formWindow->layoutG(); + row += SPACING; + } + + if ( mode == Browser ) { + if ( checkBoxNavig->isChecked() ) { + formWindow->clearSelection(); + currentCol = 0; + if ( checkBoxFirst->isChecked() ) { + QPushButton *pb = create_widget( widget, "PushButtonFirst", + "|< &First", + QRect( 3 * SPACING * currentCol, row+SPACING, SPACING * 3, SPACING ), + formWindow ); + formWindow->addConnection( pb, "clicked()", widget, "first()" ); + formWindow->addConnection( widget, "firstRecordAvailable( bool )", + pb, "setEnabled( bool )" ); + currentCol++; + formWindow->selectWidget( pb ); + } + if ( checkBoxPrev->isChecked() ) { + QPushButton *pb = create_widget( widget, "PushButtonPrev", + "<< &Prev", + QRect( 3 * SPACING * currentCol, row+SPACING, SPACING * 3, SPACING ), + formWindow ); + formWindow->addConnection( pb, "clicked()", widget, "prev()" ); + formWindow->addConnection( widget, "prevRecordAvailable( bool )", + pb, "setEnabled( bool )" ); + currentCol++; + formWindow->selectWidget( pb ); + } + if ( checkBoxNext->isChecked() ) { + QPushButton *pb = create_widget( widget, "PushButtonNext", + "&Next >>", + QRect( 3 * SPACING * currentCol, row+SPACING, SPACING * 3, SPACING ), + formWindow ); + formWindow->addConnection( pb, "clicked()", widget, "next()" ); + formWindow->addConnection( widget, "nextRecordAvailable( bool )", pb, + "setEnabled( bool )" ); + currentCol++; + formWindow->selectWidget( pb ); + } + if ( checkBoxLast->isChecked() ) { + QPushButton *pb = create_widget( widget, "PushButtonLast", "&Last >|", + QRect( 3 * SPACING * currentCol, row+SPACING, SPACING*3, SPACING ), formWindow ); + formWindow->addConnection( pb, "clicked()", widget, "last()" ); + formWindow->addConnection( widget, "lastRecordAvailable( bool )", pb, + "setEnabled( bool )" ); + currentCol++; + formWindow->selectWidget( pb ); + } + if ( createButtonLayout ) + formWindow->layoutH(); + } + if ( checkBoxEdit->isChecked() ) { + formWindow->clearSelection(); + row += SPACING; + currentCol = 0; + if ( checkBoxInsert->isChecked() ) { + QPushButton *pb = create_widget( widget, "PushButtonInsert", "&Insert", + QRect( 3 * SPACING * currentCol, row+SPACING, SPACING * 3, SPACING ), formWindow ); + formWindow->addConnection( pb, "clicked()", widget, "insert()" ); + currentCol++; + formWindow->selectWidget( pb ); + } + if ( checkBoxUpdate->isChecked() ) { + QPushButton *pb = create_widget( widget, "PushButtonUpdate", "&Update", + QRect( 3 * SPACING * currentCol, row+SPACING, SPACING * 3, SPACING ), formWindow ); + formWindow->addConnection( pb, "clicked()", widget, "update()" ); + currentCol++; + formWindow->selectWidget( pb ); + } + if ( checkBoxDelete->isChecked() ) { + QPushButton *pb = create_widget( widget, "PushButtonDelete", "&Delete", + QRect( 3 * SPACING * currentCol, row+SPACING, SPACING * 3, SPACING ), formWindow ); + formWindow->addConnection( pb, "clicked()", widget, "del()" ); + currentCol++; + formWindow->selectWidget( pb ); + } + if ( createButtonLayout ) + formWindow->layoutH(); + } + } + if ( createLayouts ) + formWindow->layoutGContainer( widget ); + formWindow->clearSelection(); + break; + } + case Table: + { + QDataTable* sqlTable = ((QDataTable*)widget); + if ( checkBoxAutoEdit->isChecked() ) { + sqlTable->setAutoEdit( TRUE ); + formWindow->setPropertyChanged( sqlTable, "autoEdit", TRUE ); + } + + if ( checkBoxReadOnly->isChecked() ) { + sqlTable->setReadOnly( TRUE ); + formWindow->setPropertyChanged( sqlTable, "readOnly", TRUE ); + } else { + if ( checkBoxConfirmInserts->isChecked() ) { + sqlTable->setConfirmInsert( TRUE ); + formWindow->setPropertyChanged( sqlTable, "confirmInsert", TRUE ); + } + if ( checkBoxConfirmUpdates->isChecked() ) { + sqlTable->setConfirmUpdate( TRUE ); + formWindow->setPropertyChanged( sqlTable, "confirmUpdate", TRUE ); + } + if ( checkBoxConfirmDeletes->isChecked() ) { + sqlTable->setConfirmDelete( TRUE ); + formWindow->setPropertyChanged( sqlTable, "confirmDelete", TRUE ); + } + if ( checkBoxConfirmCancels->isChecked() ) { + sqlTable->setConfirmCancels( TRUE ); + formWindow->setPropertyChanged( sqlTable, "confirmCancels", TRUE ); + } + } + if ( checkBoxSorting->isChecked() ) { + sqlTable->setSorting( TRUE ); + formWindow->setPropertyChanged( sqlTable, "sorting", TRUE ); + } + + QMap columnFields; + sqlTable->setNumCols( listBoxSelectedField->count() ); // no need to change property through mdbIface here, since QDataTable doesn't offer that through Designer + for( j = 0; j < listBoxSelectedField->count(); j++ ){ + + QSqlField* field = tab.field( listBoxSelectedField->text( j ) ); + if ( !field ) + continue; + + QString labelName = field->name(); + labelName = labelName.mid(0,1).upper() + labelName.mid(1); + + ((QTable*)widget)->horizontalHeader()->setLabel( j, labelName ); + + columnFields.insert( labelName, field->name() ); + } + formWindow->setColumnFields( widget, columnFields ); + break; + } + } + + database->close(); +#endif + + SqlFormWizardBase::accept(); +} diff --git a/tools/designer/plugins/wizards/sqlformwizardimpl.h b/tools/designer/plugins/wizards/sqlformwizardimpl.h new file mode 100644 index 0000000..c82a86e --- /dev/null +++ b/tools/designer/plugins/wizards/sqlformwizardimpl.h @@ -0,0 +1,87 @@ + /********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SQLFORMWIZARDIMPL_H +#define SQLFORMWIZARDIMPL_H + +#include "sqlformwizard.h" +#include +#include +#include + +class SqlFormWizard : public SqlFormWizardBase +{ + Q_OBJECT + +public: + SqlFormWizard( QUnknownInterface *aIface, QWidget *w, QWidget* parent = 0, DesignerFormWindow *fw = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~SqlFormWizard(); + + void accept() const; + +protected slots: + void connectionSelected( const QString & ); + void tableSelected( const QString & ); + void autoPopulate( bool populate ); + void fieldDown(); + void fieldUp(); + void removeField(); + void addField(); + void setupDatabaseConnections(); + void accept(); + void addSortField(); + void reSortSortField(); + void removeSortField(); + void sortFieldUp(); + void sortFieldDown(); + void nextPageClicked(); + +private: + void setupPage1(); + +private: + QWidget *widget; + QUnknownInterface *appIface; + DesignerFormWindow *formWindow; + enum Mode { + None, + View, + Browser, + Table + }; + Mode mode; + +}; + +#endif // SQLFORMWIZARDIMPL_H diff --git a/tools/designer/plugins/wizards/wizards.pro b/tools/designer/plugins/wizards/wizards.pro new file mode 100644 index 0000000..1e50693 --- /dev/null +++ b/tools/designer/plugins/wizards/wizards.pro @@ -0,0 +1,21 @@ +TEMPLATE = lib +CONFIG += qt warn_on release plugin + +SOURCES += main.cpp +FORMS = sqlformwizard.ui mainwindowwizard.ui + +sql { + HEADERS += sqlformwizardimpl.h + SOURCES += sqlformwizardimpl.cpp + } +DESTDIR = ../../../../plugins/designer + +PROJECTNAME = Wizards +IMAGES = images/qtwizards_menu_1.png images/qtwizards_menu_2.png images/qtwizards_menu_3.png images/qtwizards_table_1.png images/qtwizards_table_2.png images/qtwizards_table_3.png images/qtwizards_table_4.png images/re-sort.png images/small/editcopy.png images/small/editcut.png images/small/editpaste.png images/small/filenew.png images/small/fileopen.png images/small/filesave.png images/small/print.png images/small/redo.png images/small/searchfind.png images/small/undo.png +INCLUDEPATH += ../../interfaces +DBFILE = wizards.db +LANGUAGE = C++ + + +target.path += $$plugins.path/designer +INSTALLS += target diff --git a/tools/designer/shared/domtool.cpp b/tools/designer/shared/domtool.cpp new file mode 100644 index 0000000..51796e1 --- /dev/null +++ b/tools/designer/shared/domtool.cpp @@ -0,0 +1,460 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "domtool.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + \class DomTool domtool.h + \brief Tools for the dom + + A collection of static functions used by Resource (part of the + designer) and Uic. + +*/ + +/*! + Returns the contents of property \a name of object \a e as + variant or the variant passed as \a defValue if the property does + not exist. + + \sa hasProperty() +*/ +QVariant DomTool::readProperty( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + if ( n.attribute( "name" ) != name ) + continue; + return elementToVariant( n.firstChild().toElement(), defValue, comment ); + } + } + return defValue; +} + + +/*! + \overload + */ +QVariant DomTool::readProperty( const QDomElement& e, const QString& name, const QVariant& defValue ) +{ + QString comment; + return readProperty( e, name, defValue, comment ); +} + +/*! + Returns wheter object \a e defines property \a name or not. + + \sa readProperty() + */ +bool DomTool::hasProperty( const QDomElement& e, const QString& name ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + if ( n.attribute( "name" ) != name ) + continue; + return TRUE; + } + } + return FALSE; +} + +QStringList DomTool::propertiesOfType( const QDomElement& e, const QString& type ) +{ + QStringList result; + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + QDomElement n2 = n.firstChild().toElement(); + if ( n2.tagName() == type ) + result += n.attribute( "name" ); + } + } + return result; +} + + +QVariant DomTool::elementToVariant( const QDomElement& e, const QVariant& defValue ) +{ + QString dummy; + return elementToVariant( e, defValue, dummy ); +} + +/*! + Interprets element \a e as variant and returns the result of the interpretation. + */ +QVariant DomTool::elementToVariant( const QDomElement& e, const QVariant& defValue, QString &comment ) +{ + QVariant v; + if ( e.tagName() == "rect" ) { + QDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0, w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QRect( x, y, w, h ) ); + } else if ( e.tagName() == "point" ) { + QDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QPoint( x, y ) ); + } else if ( e.tagName() == "size" ) { + QDomElement n3 = e.firstChild().toElement(); + int w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QSize( w, h ) ); + } else if ( e.tagName() == "color" ) { + v = QVariant( readColor( e ) ); + } else if ( e.tagName() == "font" ) { + QDomElement n3 = e.firstChild().toElement(); + QFont f( defValue.toFont() ); + while ( !n3.isNull() ) { + if ( n3.tagName() == "family" ) + f.setFamily( n3.firstChild().toText().data() ); + else if ( n3.tagName() == "pointsize" ) + f.setPointSize( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "bold" ) + f.setBold( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "italic" ) + f.setItalic( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "underline" ) + f.setUnderline( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "strikeout" ) + f.setStrikeOut( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( f ); + } else if ( e.tagName() == "string" ) { + v = QVariant( e.firstChild().toText().data() ); + QDomElement n = e; + n = n.nextSibling().toElement(); + if ( n.tagName() == "comment" ) + comment = n.firstChild().toText().data(); + } else if ( e.tagName() == "cstring" ) { + v = QVariant( QCString( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "number" ) { + bool ok = TRUE; + v = QVariant( e.firstChild().toText().data().toInt( &ok ) ); + if ( !ok ) + v = QVariant( e.firstChild().toText().data().toDouble() ); + } else if ( e.tagName() == "bool" ) { + QString t = e.firstChild().toText().data(); + v = QVariant( t == "true" || t == "1", 0 ); + } else if ( e.tagName() == "pixmap" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "iconset" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "image" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "enum" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "set" ) { + v = QVariant( e.firstChild().toText().data() ); + } else if ( e.tagName() == "sizepolicy" ) { + QDomElement n3 = e.firstChild().toElement(); + QSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + sp.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + sp.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( sp ); + } else if ( e.tagName() == "cursor" ) { + v = QVariant( QCursor( e.firstChild().toText().data().toInt() ) ); + } else if ( e.tagName() == "stringlist" ) { + QStringList lst; + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) + lst << n.firstChild().toText().data(); + v = QVariant( lst ); + } else if ( e.tagName() == "date" ) { + QDomElement n3 = e.firstChild().toElement(); + int y, m, d; + y = m = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QDate( y, m, d ) ); + } else if ( e.tagName() == "time" ) { + QDomElement n3 = e.firstChild().toElement(); + int h, m, s; + h = m = s = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QTime( h, m, s ) ); + } else if ( e.tagName() == "datetime" ) { + QDomElement n3 = e.firstChild().toElement(); + int h, mi, s, y, mo, d ; + h = mi = s = y = mo = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + mi = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + mo = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = QVariant( QDateTime( QDate( y, mo, d ), QTime( h, mi, s ) ) ); + } + return v; +} + + +/*! Returns the color which is returned in the dom element \a e. + */ + +QColor DomTool::readColor( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + int r= 0, g = 0, b = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "red" ) + r = n.firstChild().toText().data().toInt(); + else if ( n.tagName() == "green" ) + g = n.firstChild().toText().data().toInt(); + else if ( n.tagName() == "blue" ) + b = n.firstChild().toText().data().toInt(); + n = n.nextSibling().toElement(); + } + + return QColor( r, g, b ); +} + +/*! + Returns the contents of attribute \a name of object \a e as + variant or the variant passed as \a defValue if the attribute does + not exist. + + \sa hasAttribute() + */ +QVariant DomTool::readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "attribute" ) { + if ( n.attribute( "name" ) != name ) + continue; + return elementToVariant( n.firstChild().toElement(), defValue, comment ); + } + } + return defValue; +} + +/*! + \overload +*/ +QVariant DomTool::readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue ) +{ + QString comment; + return readAttribute( e, name, defValue, comment ); +} + +/*! + Returns wheter object \a e defines attribute \a name or not. + + \sa readAttribute() + */ +bool DomTool::hasAttribute( const QDomElement& e, const QString& name ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "attribute" ) { + if ( n.attribute( "name" ) != name ) + continue; + return TRUE; + } + } + return FALSE; +} + +static bool toBool( const QString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +/*! + Convert Qt 2.x format to Qt 3.0 format if necessary +*/ +void DomTool::fixDocument( QDomDocument& doc ) +{ + QDomElement e; + QDomNode n; + QDomNodeList nl; + int i = 0; + + e = doc.firstChild().toElement(); + if ( e.tagName() != "UI" ) + return; + + // latest version, don't do anything + if ( e.hasAttribute("version") && e.attribute("version").toDouble() > 3.0 ) + return; + + nl = doc.elementsByTagName( "property" ); + + // in 3.0, we need to fix a spelling error + if ( e.hasAttribute("version") && e.attribute("version").toDouble() == 3.0 ) { + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement el = nl.item(i).toElement(); + QString s = el.attribute( "name" ); + if ( s == "resizeable" ) { + el.removeAttribute( "name" ); + el.setAttribute( "name", "resizable" ); + } + } + return; + } + + + // in versions smaller than 3.0 we need to change more + e.setAttribute( "version", 3.0 ); + + e.setAttribute("stdsetdef", 1 ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + if ( name == "resizeable" ) + e.setAttribute( "name", "resizable" ); + else + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + bool stdset = toBool( e.attribute( "stdset" ) ); + if ( stdset || name == "toolTip" || name == "whatsThis" || + name == "buddy" || + e.parentNode().toElement().tagName() == "item" || + e.parentNode().toElement().tagName() == "spacer" || + e.parentNode().toElement().tagName() == "column" + ) + e.removeAttribute( "stdset" ); + else + e.setAttribute( "stdset", 0 ); + } + + nl = doc.elementsByTagName( "attribute" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + } + + nl = doc.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "name" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "name", name ); + e.removeChild( n2 ); + } + } + + nl = doc.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + e = nl.item(i).toElement(); + QString name; + QDomElement n2 = e.firstChild().toElement(); + if ( n2.tagName() == "class" ) { + name = n2.firstChild().toText().data(); + e.setAttribute( "class", name ); + e.removeChild( n2 ); + } + } + +} + diff --git a/tools/designer/shared/domtool.h b/tools/designer/shared/domtool.h new file mode 100644 index 0000000..4fa561c --- /dev/null +++ b/tools/designer/shared/domtool.h @@ -0,0 +1,60 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef DOMTOOL_H +#define DOMTOOL_H + +#include +#include + +class QDomElement; +class QDomDocument; + +class DomTool : public Qt +{ +public: + static QVariant readProperty( const QDomElement& e, const QString& name, const QVariant& defValue ); + static QVariant readProperty( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ); + static bool hasProperty( const QDomElement& e, const QString& name ); + static QStringList propertiesOfType( const QDomElement& e, const QString& type ); + static QVariant elementToVariant( const QDomElement& e, const QVariant& defValue ); + static QVariant elementToVariant( const QDomElement& e, const QVariant& defValue, QString &comment ); + static QVariant readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue ); + static QVariant readAttribute( const QDomElement& e, const QString& name, const QVariant& defValue, QString& comment ); + static bool hasAttribute( const QDomElement& e, const QString& name ); + static QColor readColor( const QDomElement &e ); + static void fixDocument( QDomDocument& ); +}; + + +#endif // DOMTOOL_H diff --git a/tools/designer/shared/globaldefs.h b/tools/designer/shared/globaldefs.h new file mode 100644 index 0000000..09be46e --- /dev/null +++ b/tools/designer/shared/globaldefs.h @@ -0,0 +1,69 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef GLOBALDEFS_H +#define GLOBALDEFS_H + +#include +#include + +#define BOXLAYOUT_DEFAULT_MARGIN 11 +#define BOXLAYOUT_DEFAULT_SPACING 6 + +#ifndef NO_STATIC_COLORS +static QColor *backColor1 = 0; +static QColor *backColor2 = 0; +static QColor *selectedBack = 0; + +static void init_colors() +{ + if ( backColor1 ) + return; + +#if 0 // a calculated alternative for backColor1 + QColorGroup myCg = qApp->palette().active(); + int h1, s1, v1; + int h2, s2, v2; + myCg.color( QColorGroup::Base ).hsv( &h1, &s1, &v1 ); + myCg.color( QColorGroup::Background ).hsv( &h2, &s2, &v2 ); + QColor c( h1, s1, ( v1 + v2 ) / 2, QColor::Hsv ); +#endif + + backColor1 = new QColor( 250, 248, 235 ); + backColor2 = new QColor( 255, 255, 255 ); + selectedBack = new QColor( 230, 230, 230 ); +} + +#endif + +#endif diff --git a/tools/designer/shared/parser.cpp b/tools/designer/shared/parser.cpp new file mode 100644 index 0000000..dbc3816 --- /dev/null +++ b/tools/designer/shared/parser.cpp @@ -0,0 +1,79 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "parser.h" +#include +#include + +class NormalizeObject : public QObject +{ +public: + NormalizeObject() : QObject() {} + static QCString normalizeSignalSlot( const char *signalSlot ) { return QObject::normalizeSignalSlot( signalSlot ); } +}; + +QString Parser::cleanArgs( const QString &func ) +{ + QString slot( func ); + int begin = slot.find( "(" ) + 1; + QString args = slot.mid( begin ); + args = args.left( args.find( ")" ) ); + QStringList lst = QStringList::split( ',', args ); + QString res = slot.left( begin ); + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + if ( it != lst.begin() ) + res += ","; + QString arg = *it; + int pos = 0; + if ( ( pos = arg.find( "&" ) ) != -1 ) { + arg = arg.left( pos + 1 ); + } else if ( ( pos = arg.find( "*" ) ) != -1 ) { + arg = arg.left( pos + 1 ); + } else { + arg = arg.simplifyWhiteSpace(); + if ( ( pos = arg.find( ':' ) ) != -1 ) + arg = arg.left( pos ).simplifyWhiteSpace() + ":" + arg.mid( pos + 1 ).simplifyWhiteSpace(); + QStringList l = QStringList::split( ' ', arg ); + if ( l.count() == 2 ) { + if ( l[ 0 ] != "const" && l[ 0 ] != "unsigned" && l[ 0 ] != "var" ) + arg = l[ 0 ]; + } else if ( l.count() == 3 ) { + arg = l[ 0 ] + " " + l[ 1 ]; + } + } + res += arg; + } + res += ")"; + + return QString::fromLatin1( NormalizeObject::normalizeSignalSlot( res.latin1() ) ); +} diff --git a/tools/designer/shared/parser.h b/tools/designer/shared/parser.h new file mode 100644 index 0000000..642ff2c --- /dev/null +++ b/tools/designer/shared/parser.h @@ -0,0 +1,46 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PARSER_H +#define PARSER_H + +#include + +class Parser +{ +public: + static QString cleanArgs( const QString &func ); + +}; + +#endif diff --git a/tools/designer/shared/ui2uib.cpp b/tools/designer/shared/ui2uib.cpp new file mode 100644 index 0000000..e5b20dd --- /dev/null +++ b/tools/designer/shared/ui2uib.cpp @@ -0,0 +1,900 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "ui2uib.h" +#include "uib.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + The .uib file format is the binary counterpart of the .ui file + format. It is generated by the ui2uib converter and understood by + QWidgetFactory; in a future version, it might also be understood + by a uib2ui converter. Experiments show that .uib files are about + 2.5 times faster to load and 6 times smaller than .ui files. + + The .uib format, unlike the .ui format, is internal to Trolltech + and is not officially documented; it is assumed that anybody who + needs to understand the file format can read the ui2uib and + QWidgetFactory source code, with some guidance. And here's some + guidance. + + A .uib file starts with a 32-bit magic number that allows + QWidgetFactory to determine the file type. The magic number is + followed by '\n' (0x0a) and '\r' (0x0d), which ensure that the + file wasn't corrupted during transfer between different + platforms. For example, transferring a .ui file from Windows to + Unix using FTP with type ASCII will produce a file with '\r\n\r' + in place of '\n\r'. This is followed by the QDataStream format + version number used. + + The rest of the file is made up of blocks, each of which starts + with a block type (Block_XXX) and a block length. Block_Intro and + Block_Widget are mandatory; the others are optional. + QWidgetFactory makes certain assumptions about the order of the + blocks; for example, it expects Block_String before any other + block that refers to a string and Block_Images before + Block_Widget. The order generated by ui2uib is one of the orders + that make sense. Just after the last block, a Block_End marker + indicates the end of the file. + + The division of .uib files into blocks corresponds grossly to the + division of .ui files in top-level XML elements. Thus, + Block_Widget corresponds to and Block_Toolbars to + . The internal organization of each block also mimics + the organization of the corresponding XML elements. + + These are the major differences, all of which contribute to + making .uib files more compact: + + 1. The strings are gathered in Block_Strings, a string-table. + When a string is needed later, it is referenced by a 32-bit + index into that table. The UicStringTable class makes the + whole process of inserting and looking up strings very + simple. The advantage of this scheme is that if a string is + used more than once, it is stored only once. Also, the + string-table is preinitialized with very common strings, so + that these need not be stored along with .uib files. + + 2. QObjects are referred to by index in a table rather than by + name. The table itself is not stored in the .uib file; it is + rather build dynamically by ui2uib and QWidgetFactory as new + objects are specified. In ui2uib, the table is represented by + a UibIndexMap object; in QWidgetFactory, a plain array of + QObject pointers suffices. + + 3. The data is packed to take as little place as possible, + without slowing down QLayoutFactory too much. For example, an + index into the string-table is a 32-bit integer, but in + practice it is rarely above 65534, so only 16 bits are used + for them; when an index above 65534 is met, the index is + saved as 65535 followed by the 32-bit index, for a total of + 48 bits. + + 4. The name of a signal or slot and its signature are saved + separately. That way, if a signal 'foo(const QString&)' is + connected to a slot 'bar(const QString&)', the string-table + will only contain 'foo', 'bar', and '(const QString&)', + instead of the longer 'foo(const QString&)' and 'bar(const + QString&)'. The signatures are normalized beforehand to + ensure that trivial spacing problems don't result in multiple + string-table entries. + + 5. In a signal-to-slot connection, a sender, signal, receiver, + or slot is not repeated if it's the same as for the previous + connection. Bit flags indicate what is repeated and what is + specified. + + 6. Some of the information stored in a .ui file is useful only + by uic, not to QLayoutFactory. That information is, for now, + not taken along in the .uib file. Likewise, needless + QLayoutWidget objects are not taken along. + + The arbitrary constants related to the .uib file formats are + defined in uib.h. Constants such as Block_Actions and + Object_SubWidget are given values such as 'A' and 'W' to make + .uib files easier to read in a hexadecimal editor. + + The file format isn't designed to be extensible. Any extension + that prevents an older version of QLayoutWidget of reading the + file correctly must have a different magic number. The plan is to + use UibMagic + 1 for version 2, UibMagic + 2 for version 3, etc. +*/ + +static QCString layoutForTag( const QString& tag ) +{ + if ( tag == "grid" ) { + return "QGridLayout"; + } else if ( tag == "hbox" ) { + return "QHBoxLayout"; + } else if ( tag == "vbox" ) { + return "QVBoxLayout"; + } else { + return "QLayout"; + } +} + +class UibHack : public QObject +{ +public: + static QString normalize( const QString& member ) { + return QString::fromUtf8( QObject::normalizeSignalSlot(member.utf8()) ); + } +}; + +class UibIndexMap +{ +public: + UibIndexMap() : next( 0 ) { } + + void insert( const QString& name ) { setName( insert(), name ); } + int insert() { return next++; } + void setName( int no, const QString& name ); + + int find( const QString& name, int deflt = -1 ) const; + int count() const { return next; } + +private: + QMap nameMap; + QMap conflicts; + int next; +}; + +void UibIndexMap::setName( int no, const QString& name ) +{ + if ( !name.isEmpty() ) { + if ( *nameMap.insert(name, no, FALSE) != no ) + conflicts.insert( name, 0 ); + } +} + +int UibIndexMap::find( const QString& name, int deflt ) const +{ + QMap::ConstIterator no = nameMap.find( name ); + if ( no == nameMap.end() || conflicts.contains(name) ) { + return deflt; + } else { + return *no; + } +} + +static void packUInt16( QDataStream& out, Q_UINT16 n ) +{ + if ( n < 255 ) { + out << (Q_UINT8) n; + } else { + out << (Q_UINT8) 255; + out << n; + } +} + +static void packUInt32( QDataStream& out, Q_UINT32 n ) +{ + if ( n < 65535 ) { + out << (Q_UINT16) n; + } else { + out << (Q_UINT16) 65535; + out << n; + } +} + +static void packByteArray( QDataStream& out, const QByteArray& array ) +{ + packUInt32( out, array.size() ); + out.writeRawBytes( array.data(), array.size() ); +} + +static void packCString( UibStrTable& strings, QDataStream& out, + const char *cstr ) +{ + packUInt32( out, strings.insertCString(cstr) ); +} + +static void packString( UibStrTable& strings, QDataStream& out, + const QString& str ) +{ + packUInt32( out, strings.insertString(str) ); +} + +static void packStringSplit( UibStrTable& strings, QDataStream& out, + const QString& str, QChar sep ) +{ + int pos = str.find( sep ); + if ( pos == -1 ) + pos = str.length(); + packString( strings, out, str.left(pos) ); + packString( strings, out, str.mid(pos) ); +} + +static void packVariant( UibStrTable& strings, QDataStream& out, + QVariant value, QString tag = "" ) +{ + QStringList::ConstIterator s; + + Q_UINT8 type = value.type(); + if ( tag == "pixmap" ) { + type = QVariant::Pixmap; + } else if ( tag == "image" ) { + type = QVariant::Image; + } else if ( tag == "iconset" ) { + type = QVariant::IconSet; + } + out << type; + + switch ( type ) { + case QVariant::String: + case QVariant::Pixmap: + case QVariant::Image: + case QVariant::IconSet: + packString( strings, out, value.asString() ); + break; + case QVariant::StringList: + packUInt16( out, value.asStringList().count() ); + s = value.asStringList().begin(); + while ( s != value.asStringList().end() ) { + packString( strings, out, *s ); + ++s; + } + break; + case QVariant::Font: + out << value.asFont(); + break; + case QVariant::Rect: + packUInt16( out, value.asRect().x() ); + packUInt16( out, value.asRect().y() ); + packUInt16( out, value.asRect().width() ); + packUInt16( out, value.asRect().height() ); + break; + case QVariant::Size: + packUInt16( out, value.asSize().width() ); + packUInt16( out, value.asSize().height() ); + break; + case QVariant::Color: + out << value.asColor(); + break; + case QVariant::Point: + packUInt16( out, value.asPoint().x() ); + packUInt16( out, value.asPoint().y() ); + break; + case QVariant::Int: + packUInt32( out, value.asInt() ); + break; + case QVariant::Bool: + out << (Q_UINT8) value.asBool(); + break; + case QVariant::Double: + out << value.asDouble(); + break; + case QVariant::CString: + packCString( strings, out, value.asCString() ); + break; + case QVariant::Cursor: + out << value.asCursor(); + break; + case QVariant::Date: + out << value.asDate(); + break; + case QVariant::Time: + out << value.asTime(); + break; + case QVariant::DateTime: + out << value.asDateTime(); + break; + default: + out << value; + } +} + +static void outputProperty( QMap& buddies, int objectNo, + UibStrTable& strings, QDataStream& out, + QDomElement elem ) +{ + QCString name = elem.attribute( "name" ).latin1(); + QDomElement f = elem.firstChild().toElement(); + QString tag = f.tagName(); + QString comment; + QVariant value; + + if ( name == "resizeable" ) + name = "resizable"; + + if ( tag == "font" ) { + QString family; + Q_UINT16 pointSize = 65535; + Q_UINT8 fontFlags = 0; + + QDomElement g = f.firstChild().toElement(); + while ( !g.isNull() ) { + QString text = g.firstChild().toText().data(); + if ( g.tagName() == "family" ) { + fontFlags |= Font_Family; + family = text; + } else if ( g.tagName() == "pointsize" ) { + fontFlags |= Font_PointSize; + pointSize = (Q_UINT16) text.toUInt(); + } else { + if ( g.firstChild().toText().data().toInt() != 0 ) { + if ( g.tagName() == "bold" ) { + fontFlags |= Font_Bold; + } else if ( g.tagName() == "italic" ) { + fontFlags |= Font_Italic; + } else if ( g.tagName() == "underline" ) { + fontFlags |= Font_Underline; + } else if ( g.tagName() == "strikeout" ) { + fontFlags |= Font_StrikeOut; + } + } + } + g = g.nextSibling().toElement(); + } + + out << (Q_UINT8) Object_FontProperty; + packCString( strings, out, name ); + out << fontFlags; + if ( fontFlags & Font_Family ) + packString( strings, out, family ); + if ( fontFlags & Font_PointSize ) + packUInt16( out, pointSize ); + } else if ( tag == "palette" ) { + out << (Q_UINT8) Object_PaletteProperty; + packCString( strings, out, name ); + + QDomElement g = f.firstChild().toElement(); + while ( !g.isNull() ) { + QDomElement h = g.firstChild().toElement(); + while ( !h.isNull() ) { + value = DomTool::elementToVariant( h, Qt::gray ); + if ( h.tagName() == "color" ) { + out << (Q_UINT8) Palette_Color; + out << value.asColor(); + } else if ( h.tagName() == "pixmap" ) { + out << (Q_UINT8) Palette_Pixmap; + packVariant( strings, out, value, "pixmap" ); + } + h = h.nextSibling().toElement(); + } + + if ( g.tagName() == "active" ) { + out << (Q_UINT8) Palette_Active; + } else if ( g.tagName() == "inactive" ) { + out << (Q_UINT8) Palette_Inactive; + } else { + out << (Q_UINT8) Palette_Disabled; + } + g = g.nextSibling().toElement(); + } + out << (Q_UINT8) Palette_End; + } else { + value = DomTool::elementToVariant( f, value, comment ); + if ( value.isValid() ) { + if ( name == "buddy" ) { + buddies[objectNo] += value.asString(); + } else { + if ( tag == "string" ) { + out << (Q_UINT8) Object_TextProperty; + packCString( strings, out, name ); + packCString( strings, out, value.asString().utf8() ); + packCString( strings, out, comment.utf8() ); + } else { + out << (Q_UINT8) Object_VariantProperty; + packCString( strings, out, name ); + packVariant( strings, out, value, tag ); + } + } + } + } +} + +static void outputGridCell( QDataStream& out, QDomElement elem ) +{ + int column = elem.attribute( "column", "0" ).toInt(); + int row = elem.attribute( "row", "0" ).toInt(); + int colspan = elem.attribute( "colspan", "1" ).toInt(); + int rowspan = elem.attribute( "rowspan", "1" ).toInt(); + if ( colspan < 1 ) + colspan = 1; + if ( rowspan < 1 ) + rowspan = 1; + + if ( column != 0 || row != 0 || colspan != 1 || rowspan != 1 ) { + out << (Q_UINT8) Object_GridCell; + packUInt16( out, column ); + packUInt16( out, row ); + packUInt16( out, colspan ); + packUInt16( out, rowspan ); + } +} + +static int outputObject( QMap& buddies, + UibIndexMap& objects, UibStrTable& strings, + QDataStream& out, QDomElement elem, + QCString className = "" ); + +static void outputLayoutWidgetsSubLayout( QMap& buddies, + UibIndexMap& objects, + UibStrTable& strings, + QDataStream& out, QDomElement elem ) +{ + int subLayoutNo = -1; + QCString name; + QDomElement nameElem; + + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + QString tag = f.tagName(); + if ( tag == "grid" || tag == "hbox" || tag == "vbox" ) { + out << (Q_UINT8) Object_SubLayout; + subLayoutNo = outputObject( buddies, objects, strings, out, f, + layoutForTag(tag) ); + } else if ( tag == "property" ) { + if ( f.attribute("name") == "name" ) { + name = DomTool::elementToVariant( f, name ).asCString(); + nameElem = f; + } + } + f = f.nextSibling().toElement(); + } + + if ( subLayoutNo != -1 ) { + /* + Remove the sub-layout's Object_End marker, append the grid + cell and the correct name property, and put the Object_End + marker back. + */ + out.device()->at( out.device()->at() - 1 ); + outputGridCell( out, elem ); + outputProperty( buddies, subLayoutNo, strings, out, nameElem ); + out << (Q_UINT8) Object_End; + + objects.setName( subLayoutNo, name ); + } +} + +static int outputObject( QMap& buddies, + UibIndexMap& objects, UibStrTable& strings, + QDataStream& out, QDomElement elem, + QCString className ) +{ + bool isQObject = !className.isEmpty(); + + if ( className == "QToolBar" ) + out << (Q_UINT8) elem.attribute( "dock", "0" ).toInt(); + if ( className == "QWidget" ) + className = elem.attribute( "class", className ).latin1(); + + int objectNo = -1; + if ( isQObject ) { + packCString( strings, out, className ); + objectNo = objects.insert(); + } + + outputGridCell( out, elem ); + + // optimization: insert '&Foo' into string-table before 'Foo' + if ( className == "QAction" || className == "QActionGroup" ) { + QVariant value = DomTool::readProperty( elem, "menuText", QVariant() ); + if ( value.asString().startsWith("&") ) + strings.insertString( value.asString() ); + } + + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + QString tag = f.tagName(); + if ( tag == "action" ) { + if ( elem.tagName() == "item" || elem.tagName() == "toolbar" ) { + QString actionName = f.attribute( "name" ); + int no = objects.find( actionName ); + if ( no != -1 ) { + out << (Q_UINT8) Object_ActionRef; + packUInt16( out, no ); + } + } else { + out << (Q_UINT8) Object_SubAction; + outputObject( buddies, objects, strings, out, f, "QAction" ); + } + } else if ( tag == "actiongroup" ) { + out << (Q_UINT8) Object_SubAction; + outputObject( buddies, objects, strings, out, f, "QActionGroup" ); + } else if ( tag == "attribute" ) { + out << (Q_UINT8) Object_Attribute; + outputProperty( buddies, objectNo, strings, out, f ); + } else if ( tag == "column" ) { + out << (Q_UINT8) Object_Column; + outputObject( buddies, objects, strings, out, f ); + } else if ( tag == "event" ) { + out << (Q_UINT8) Object_Event; + packCString( strings, out, f.attribute("name").latin1() ); + packVariant( strings, out, + QStringList::split(',', f.attribute("functions")) ); + } else if ( tag == "grid" || tag == "hbox" || tag == "vbox" ) { + out << (Q_UINT8) Object_SubLayout; + outputObject( buddies, objects, strings, out, f, + layoutForTag(tag) ); + } else if ( tag == "item" ) { + if ( elem.tagName() == "menubar" ) { + out << (Q_UINT8) Object_MenuItem; + packCString( strings, out, f.attribute("name").latin1() ); + packCString( strings, out, f.attribute("text").utf8() ); + outputObject( buddies, objects, strings, out, f ); + } else { + out << (Q_UINT8) Object_Item; + outputObject( buddies, objects, strings, out, f ); + } + } else if ( tag == "property" ) { + outputProperty( buddies, objectNo, strings, out, f ); + } else if ( tag == "row" ) { + out << (Q_UINT8) Object_Row; + outputObject( buddies, objects, strings, out, f ); + } else if ( tag == "separator" ) { + out << (Q_UINT8) Object_Separator; + } else if ( tag == "spacer" ) { + out << (Q_UINT8) Object_Spacer; + outputObject( buddies, objects, strings, out, f ); + } else if ( tag == "widget" ) { + if ( f.attribute("class") == "QLayoutWidget" && + elem.tagName() != "widget" ) { + outputLayoutWidgetsSubLayout( buddies, objects, strings, out, + f ); + } else { + out << (Q_UINT8) Object_SubWidget; + outputObject( buddies, objects, strings, out, f, "QWidget" ); + } + } + f = f.nextSibling().toElement(); + } + out << (Q_UINT8) Object_End; + if ( isQObject ) + objects.setName( objectNo, + DomTool::readProperty(elem, "name", "").asString() ); + return objectNo; +} + +static void outputBlock( QDataStream& out, BlockTag tag, + const QByteArray& data ) +{ + if ( !data.isEmpty() ) { + out << (Q_UINT8) tag; + packByteArray( out, data ); + } +} + +void convertUiToUib( QDomDocument& doc, QDataStream& out ) +{ + QByteArray introBlock; + QByteArray actionsBlock; + QByteArray buddiesBlock; + QByteArray connectionsBlock; + QByteArray functionsBlock; + QByteArray imagesBlock; + QByteArray menubarBlock; + QByteArray slotsBlock; + QByteArray tabstopsBlock; + QByteArray toolbarsBlock; + QByteArray variablesBlock; + QByteArray widgetBlock; + + QDomElement actionsElem; + QDomElement connectionsElem; + QDomElement imagesElem; + QDomElement menubarElem; + QDomElement tabstopsElem; + QDomElement toolbarsElem; + QDomElement widgetElem; + + QMap buddies; + UibStrTable strings; + UibIndexMap objects; + int widgetNo = -1; + QCString className; + Q_INT16 defaultMargin = -32768; + Q_INT16 defaultSpacing = -32768; + Q_UINT8 introFlags = 0; + + QDomElement elem = doc.firstChild().toElement().firstChild().toElement(); + while ( !elem.isNull() ) { + QString tag = elem.tagName(); + + switch ( tag[0].latin1() ) { + case 'a': + if ( tag == "actions" ) + actionsElem = elem; + break; + case 'c': + if ( tag == "class" ) { + className = elem.firstChild().toText().data().latin1(); + } else if ( tag == "connections" ) { + connectionsElem = elem; + } + break; + case 'f': + if ( tag == "functions" ) { + QDataStream out2( functionsBlock, IO_WriteOnly ); + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "function" ) { + packStringSplit( strings, out2, + f.attribute("name").latin1(), '(' ); + packString( strings, out2, + f.firstChild().toText().data() ); + } + f = f.nextSibling().toElement(); + } + } + break; + case 'i': + if ( tag == "images" ) { + QDataStream out2( imagesBlock, IO_WriteOnly ); + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "image" ) { + QString name = f.attribute( "name" ); + QDomElement g = f.firstChild().toElement(); + if ( g.tagName() == "data" ) { + QString format = g.attribute( "format", "PNG" ); + QString hex = g.firstChild().toText().data(); + int n = hex.length() / 2; + QByteArray data( n ); + for ( int i = 0; i < n; i++ ) + data[i] = (char) hex.mid( 2 * i, 2 ) + .toUInt( 0, 16 ); + + packString( strings, out2, name ); + packString( strings, out2, format ); + packUInt32( out2, g.attribute("length").toInt() ); + packByteArray( out2, data ); + } + } + f = f.nextSibling().toElement(); + } + } + break; + case 'l': + if ( tag == "layoutdefaults" ) { + QString margin = elem.attribute( "margin" ); + if ( !margin.isEmpty() ) + defaultMargin = margin.toInt(); + QString spacing = elem.attribute( "spacing" ); + if ( !spacing.isEmpty() ) + defaultSpacing = spacing.toInt(); + } + break; + case 'm': + if ( tag == "menubar" ) + menubarElem = elem; + break; + case 'p': + if ( tag == "pixmapinproject" ) + introFlags |= Intro_Pixmapinproject; + break; + case 's': + if ( tag == "slots" ) { + QDataStream out2( slotsBlock, IO_WriteOnly ); + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "slot" ) { + QString language = f.attribute( "language", "C++" ); + QString slot = UibHack::normalize( + f.firstChild().toText().data() ); + packString( strings, out2, language ); + packStringSplit( strings, out2, slot, '(' ); + } + f = f.nextSibling().toElement(); + } + } + break; + case 't': + if ( tag == "tabstops" ) { + tabstopsElem = elem; + } else if ( tag == "toolbars" ) { + toolbarsElem = elem; + } + break; + case 'v': + if ( tag == "variable" ) { + QDataStream out2( variablesBlock, IO_WriteOnly | IO_Append ); + packString( strings, out2, elem.firstChild().toText().data() ); + } else if ( tag == "variables" ) { + QDataStream out2( variablesBlock, IO_WriteOnly ); + QDomElement f = elem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "variable" ) + packString( strings, out2, + f.firstChild().toText().data() ); + f = f.nextSibling().toElement(); + } + } + break; + case 'w': + if ( tag == "widget" ) + widgetElem = elem; + } + elem = elem.nextSibling().toElement(); + } + + { + QDataStream out2( widgetBlock, IO_WriteOnly ); + widgetNo = outputObject( buddies, objects, strings, out2, widgetElem, + "QWidget" ); + } + + if ( !tabstopsElem.isNull() ) { + QDataStream out2( tabstopsBlock, IO_WriteOnly ); + QDomElement f = tabstopsElem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "tabstop" ) { + QString widgetName = f.firstChild().toText().data(); + int no = objects.find( widgetName ); + if ( no != -1 ) + packUInt16( out2, no ); + } + f = f.nextSibling().toElement(); + } + } + + if ( !actionsElem.isNull() ) { + QDataStream out2( actionsBlock, IO_WriteOnly ); + outputObject( buddies, objects, strings, out2, actionsElem ); + } + + if ( !menubarElem.isNull() ) { + QDataStream out2( menubarBlock, IO_WriteOnly ); + outputObject( buddies, objects, strings, out2, menubarElem, + "QMenuBar" ); + } + + if ( !toolbarsElem.isNull() ) { + QDataStream out2( toolbarsBlock, IO_WriteOnly ); + QDomElement f = toolbarsElem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "toolbar" ) + outputObject( buddies, objects, strings, out2, f, "QToolBar" ); + f = f.nextSibling().toElement(); + } + } + + if ( !buddies.isEmpty() ) { + QDataStream out2( buddiesBlock, IO_WriteOnly ); + QMap::ConstIterator a = buddies.begin(); + while ( a != buddies.end() ) { + QStringList::ConstIterator b = (*a).begin(); + while ( b != (*a).end() ) { + int no = objects.find( *b ); + if ( no != -1 ) { + packUInt16( out2, a.key() ); + packUInt16( out2, no ); + } + ++b; + } + ++a; + } + } + + if ( !connectionsElem.isNull() ) { + QString prevLanguage = "C++"; + int prevSenderNo = 0; + QString prevSignal = "clicked()"; + int prevReceiverNo = 0; + QString prevSlot = "accept()"; + + QDataStream out2( connectionsBlock, IO_WriteOnly ); + QDomElement f = connectionsElem.firstChild().toElement(); + while ( !f.isNull() ) { + if ( f.tagName() == "connection" ) { + QMap argMap; + + QDomElement g = f.firstChild().toElement(); + while ( !g.isNull() ) { + argMap[g.tagName()] = g.firstChild().toText().data(); + g = g.nextSibling().toElement(); + } + + QString language = f.attribute( "language", "C++" ); + int senderNo = objects.find( argMap["sender"], widgetNo ); + int receiverNo = objects.find( argMap["receiver"], widgetNo ); + QString signal = UibHack::normalize( argMap["signal"] ); + QString slot = UibHack::normalize( argMap["slot"] ); + + Q_UINT8 connectionFlags = 0; + if ( language != prevLanguage ) + connectionFlags |= Connection_Language; + if ( senderNo != prevSenderNo ) + connectionFlags |= Connection_Sender; + if ( signal != prevSignal ) + connectionFlags |= Connection_Signal; + if ( receiverNo != prevReceiverNo ) + connectionFlags |= Connection_Receiver; + if ( slot != prevSlot ) + connectionFlags |= Connection_Slot; + out2 << connectionFlags; + + if ( connectionFlags & Connection_Language ) + packString( strings, out2, language ); + if ( connectionFlags & Connection_Sender ) + packUInt16( out2, senderNo ); + if ( connectionFlags & Connection_Signal ) + packStringSplit( strings, out2, signal, '(' ); + if ( connectionFlags & Connection_Receiver ) + packUInt16( out2, receiverNo ); + if ( connectionFlags & Connection_Slot ) + packStringSplit( strings, out2, slot, '(' ); + + prevLanguage = language; + prevSenderNo = senderNo; + prevSignal = signal; + prevReceiverNo = receiverNo; + prevSlot = slot; + } else if ( f.tagName() == "slot" ) { + // ### + } + f = f.nextSibling().toElement(); + } + } + + { + QDataStream out2( introBlock, IO_WriteOnly ); + out2 << introFlags; + out2 << defaultMargin; + out2 << defaultSpacing; + packUInt16( out2, objects.count() ); + packCString( strings, out2, className ); + } + + out << UibMagic; + out << (Q_UINT8) '\n'; + out << (Q_UINT8) '\r'; + out << (Q_UINT8) out.version(); + outputBlock( out, Block_Strings, strings.block() ); + outputBlock( out, Block_Intro, introBlock ); + outputBlock( out, Block_Images, imagesBlock ); + outputBlock( out, Block_Widget, widgetBlock ); + outputBlock( out, Block_Slots, slotsBlock ); + outputBlock( out, Block_Tabstops, tabstopsBlock ); + outputBlock( out, Block_Actions, actionsBlock ); + outputBlock( out, Block_Menubar, menubarBlock ); + outputBlock( out, Block_Toolbars, toolbarsBlock ); + outputBlock( out, Block_Variables, variablesBlock ); + outputBlock( out, Block_Functions, functionsBlock ); + outputBlock( out, Block_Buddies, buddiesBlock ); + outputBlock( out, Block_Connections, connectionsBlock ); + out << (Q_UINT8) Block_End; +} diff --git a/tools/designer/shared/ui2uib.h b/tools/designer/shared/ui2uib.h new file mode 100644 index 0000000..6b0c9d3 --- /dev/null +++ b/tools/designer/shared/ui2uib.h @@ -0,0 +1,42 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef UI2UIB_H +#define UI2UIB_H + +class QDataStream; +class QDomDocument; + +void convertUiToUib( QDomDocument& doc, QDataStream& out ); + +#endif diff --git a/tools/designer/shared/uib.cpp b/tools/designer/shared/uib.cpp new file mode 100644 index 0000000..74fbc0d --- /dev/null +++ b/tools/designer/shared/uib.cpp @@ -0,0 +1,49 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "uib.h" + +static const char commonStrings[] = + "\0()\0(bool)\0(const QString&)\0(int)\0C++\0Layout1\0PNG\0QCheckBox\0" + "QComboBox\0QDialog\0QFrame\0QGridLayout\0QGroupBox\0QHBoxLayout\0QLabel\0" + "QLineEdit\0QListView\0QPushButton\0QRadioButton\0QVBoxLayout\0QWidget\0" + "TextLabel1\0XPM.GZ\0accept\0autoDefault\0buddy\0caption\0clicked\0" + "default\0destroy\0frameShadow\0frameShape\0geometry\0init\0margin\0" + "maximumSize\0minimumSize\0name\0reject\0sizePolicy\0spacing\0text\0title\0" + "toolTip\0unnamed\0whatsThis"; + +UibStrTable::UibStrTable() + : out( table, IO_WriteOnly ), start( sizeof(commonStrings) ) +{ + out.writeRawBytes( commonStrings, start ); +} diff --git a/tools/designer/shared/uib.h b/tools/designer/shared/uib.h new file mode 100644 index 0000000..743c4b6 --- /dev/null +++ b/tools/designer/shared/uib.h @@ -0,0 +1,159 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef UIB_H +#define UIB_H + +#include + +const Q_UINT32 UibMagic = 0xb77c61d8; + +enum BlockTag { Block_End = '$', Block_Actions = 'A', Block_Buddies = 'B', + Block_Connections = 'C', Block_Functions = 'F', + Block_Images = 'G', Block_Intro = 'I', Block_Menubar = 'M', + Block_Slots = 'S', Block_Strings = 'Z', Block_Tabstops = 'T', + Block_Toolbars = 'O', Block_Variables = 'V', + Block_Widget = 'W' }; + +enum ObjectTag { Object_End = '$', Object_ActionRef = 'X', + Object_Attribute = 'B', Object_Column = 'C', + Object_Event = 'E', Object_FontProperty = 'F', + Object_GridCell = 'G', Object_Item = 'I', + Object_MenuItem = 'M', Object_PaletteProperty = 'P', + Object_Row = 'R', Object_Separator = 'S', Object_Spacer = 'Y', + Object_SubAction = 'A', Object_SubLayout = 'L', + Object_SubWidget = 'W', Object_TextProperty = 'T', + Object_VariantProperty = 'V' }; + +enum PaletteTag { Palette_End = '$', Palette_Active = 'A', + Palette_Inactive = 'I', Palette_Disabled = 'D', + Palette_Color = 'C', Palette_Pixmap = 'P' }; + +enum IntroFlag { Intro_Pixmapinproject = 0x1 }; + +enum FontFlag { Font_Family = 0x1, Font_PointSize = 0x2, Font_Bold = 0x4, + Font_Italic = 0x8, Font_Underline = 0x10, + Font_StrikeOut = 0x20 }; + +enum ConnectionFlag { Connection_Language = 0x1, Connection_Sender = 0x2, + Connection_Signal = 0x4, Connection_Receiver = 0x8, + Connection_Slot = 0x10 }; + +class UibStrTable +{ +public: + UibStrTable(); + + inline int insertCString( const char *cstr ); + inline int insertString( const QString& str ); + inline void readBlock( QDataStream& in, int size ); + + inline const char *asCString( int offset ) const; + inline QString asString( int offset ) const; + inline QByteArray block() const; + +private: + QCString table; + QDataStream out; + int start; +}; + +/* + uic uses insertCString(), insertString(), and block(); + QWidgetFactory uses readBlock(), asCString(), and asString(). By + implementing these functions inline, we ensure that the binaries + don't contain needless code. +*/ + +inline int UibStrTable::insertCString( const char *cstr ) +{ + if ( cstr == 0 || cstr[0] == 0 ) { + return 0; + } else { + int nextPos = table.size(); + int len = (int)strlen( cstr ); + int i; + for ( i = 0; i < nextPos - len; i++ ) { + if ( memcmp(table.data() + i, cstr, len + 1) == 0 ) + return i; + } + for ( i = 0; i < len + 1; i++ ) + out << (Q_UINT8) cstr[i]; + return nextPos; + } +} + +inline int UibStrTable::insertString( const QString& str ) +{ + if ( str.contains('\0') || str[0] == QChar(0x7f) ) { + int nextPos = table.size(); + out << (Q_UINT8) 0x7f; + out << str; + return nextPos; + } else { + return insertCString( str.utf8() ); + } +} + +inline void UibStrTable::readBlock( QDataStream& in, int size ) +{ + table.resize( start + size ); + in.readRawBytes( table.data() + start, size ); +} + +inline QString UibStrTable::asString( int offset ) const +{ + if ( table[offset] == 0x7f ) { + QDataStream in( table, IO_ReadOnly ); + in.device()->at( offset + 1 ); + QString str; + in >> str; + return str; + } else { + return QString::fromUtf8( asCString(offset) ); + } +} + +inline const char *UibStrTable::asCString( int offset ) const +{ + return table.data() + offset; +} + +inline QByteArray UibStrTable::block() const +{ + QByteArray block; + block.duplicate( table.data() + start, table.size() - start ); + return block; +} + +#endif diff --git a/tools/designer/shared/widgetdatabase.cpp b/tools/designer/shared/widgetdatabase.cpp new file mode 100644 index 0000000..1459818 --- /dev/null +++ b/tools/designer/shared/widgetdatabase.cpp @@ -0,0 +1,960 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "widgetdatabase.h" +#include "../interfaces/widgetinterface.h" + +#include +#define NO_STATIC_COLORS +#include +#include +#include +#include +#include +#include +#include + +#include + +const int dbsize = 300; +const int dbcustom = 200; +const int dbdictsize = 211; +static WidgetDatabaseRecord* db[ dbsize ]; +static QDict *className2Id = 0; +static int dbcount = 0; +static int dbcustomcount = 200; +static QStrList *wGroups; +static QStrList *invisibleGroups; +static bool whatsThisLoaded = FALSE; +static QPluginManager *widgetPluginManager = 0; +static bool plugins_set_up = FALSE; +static bool was_in_setup = FALSE; + +QCleanupHandler > cleanup_manager; + +WidgetDatabaseRecord::WidgetDatabaseRecord() +{ + isForm = FALSE; + isContainer = FALSE; + icon = 0; + nameCounter = 0; + isCommon = FALSE; + isPlugin = FALSE; +} + +WidgetDatabaseRecord::~WidgetDatabaseRecord() +{ + delete icon; +} + + +/*! + \class WidgetDatabase widgetdatabase.h + \brief The WidgetDatabase class holds information about widgets + + The WidgetDatabase holds information about widgets like toolTip(), + iconSet(), ... It works Id-based, so all access functions take the + widget id as parameter. To get the id for a widget (classname), use + idFromClassName(). + + All access functions are static. Having multiple widgetdatabases in + one application doesn't make sense anyway and so you don't need more + than an instance of the widgetdatabase. + + For creating widgets, layouts, etc. see WidgetFactory. +*/ + +/*! + Creates widget database. Does nothing. +*/ + +WidgetDatabase::WidgetDatabase() +{ +} + +/*! Sets up the widget database. If the static widgetdatabase already + exists, the functions returns immediately. +*/ + +void WidgetDatabase::setupDataBase( int id ) +{ + was_in_setup = TRUE; +#ifndef UIC + Q_UNUSED( id ) + if ( dbcount ) + return; +#else + if ( dbcount && id != -2 ) + return; + if ( dbcount && !plugins_set_up ) { + setupPlugins(); + return; + } + if ( dbcount && plugins_set_up) + return; +#endif + + wGroups = new QStrList; + invisibleGroups = new QStrList; + invisibleGroups->append( "Forms" ); + invisibleGroups->append( "Temp" ); + className2Id = new QDict( dbdictsize ); + className2Id->setAutoDelete( TRUE ); + + WidgetDatabaseRecord *r = 0; + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_pushbutton.png"; + r->name = "QPushButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Push Button"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_toolbutton.png"; + r->name = "QToolButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Tool Button"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_radiobutton.png"; + r->name = "QRadioButton"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Radio Button"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_checkbox.png"; + r->name = "QCheckBox"; + r->group = widgetGroup( "Buttons" ); + r->toolTip = "Check Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_groupbox.png"; + r->name = "QGroupBox"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Group Box"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_buttongroup.png"; + r->name = "QButtonGroup"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Button Group"; + r->isContainer = TRUE; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_frame.png"; + r->name = "QFrame"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Frame"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "QTabWidget"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Tabwidget"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_widgetstack.png"; + r->name = "QWidgetStack"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Widget Stack"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_toolbox.png"; + r->name = "QToolBox"; + r->group = widgetGroup( "Containers" ); + r->toolTip = "Tool Box"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_listbox.png"; + r->name = "QListBox"; + r->group = widgetGroup( "Views" ); + r->toolTip = "List Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_listview.png"; + r->name = "QListView"; + r->group = widgetGroup( "Views" ); + r->toolTip = "List View"; + + append( r ); + +#if !defined(QT_NO_ICONVIEW) || defined(UIC) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_iconview.png"; + r->name = "QIconView"; + r->group = widgetGroup( "Views" ); + r->toolTip = "Icon View"; + + append( r ); +#endif + +#if !defined(QT_NO_TABLE) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_table.png"; + r->name = "QTable"; + r->group = widgetGroup( "Views" ); + r->toolTip = "Table"; + + append( r ); +#endif + +#if !defined(QT_NO_SQL) + r = new WidgetDatabaseRecord; + r->iconSet = "designer_datatable.png"; + r->includeFile = "qdatatable.h"; + r->name = "QDataTable"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data Table"; + + append( r ); +#endif + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_lineedit.png"; + r->name = "QLineEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Line Edit"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_spinbox.png"; + r->name = "QSpinBox"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Spin Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_dateedit.png"; + r->name = "QDateEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Date Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_timeedit.png"; + r->name = "QTimeEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Time Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_datetimeedit.png"; + r->name = "QDateTimeEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Date-Time Edit"; + r->includeFile = "qdatetimeedit.h"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_multilineedit.png"; + r->name = "QMultiLineEdit"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Multi Line Edit"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_richtextedit.png"; + r->name = "QTextEdit"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Rich Text Edit"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_combobox.png"; + r->name = "QComboBox"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Combo Box"; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_slider.png"; + r->name = "QSlider"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Slider"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_scrollbar.png"; + r->name = "QScrollBar"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Scrollbar"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_dial.png"; + r->name = "QDial"; + r->group = widgetGroup( "Input" ); + r->toolTip = "Dial"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_label.png"; + r->name = "QLabel"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Label"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_label.png"; + r->name = "TextLabel"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Text Label"; + r->whatsThis = "The Text Label provides a widget to display static text."; + r->isCommon = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_pixlabel.png"; + r->name = "PixmapLabel"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Pixmap Label"; + r->whatsThis = "The Pixmap Label provides a widget to display pixmaps."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_lcdnumber.png"; + r->name = "QLCDNumber"; + r->group = widgetGroup( "Display" ); + r->toolTip = "LCD Number"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_line.png"; + r->name = "Line"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Line"; + r->includeFile = "qframe.h"; + r->whatsThis = "The Line widget provides horizontal and vertical lines."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_progress.png"; + r->name = "QProgressBar"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Progress Bar"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_textview.png"; + r->name = "QTextView"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Text View"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_textbrowser.png"; + r->name = "QTextBrowser"; + r->group = widgetGroup( "Display" ); + r->toolTip = "Text Browser"; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_spacer.png"; + r->name = "Spacer"; + r->group = widgetGroup( "Temp" ); + r->toolTip = "Spacer"; + r->whatsThis = "The Spacer provides horizontal and vertical spacing to be able to manipulate the behaviour of layouts."; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QWidget"; + r->isForm = TRUE; + r->group = widgetGroup( "Forms" ); + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QDialog"; + r->group = widgetGroup( "Forms" ); + r->isForm = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QWizard"; + r->group = widgetGroup( "Forms" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QDesignerWizard"; + r->group = widgetGroup( "Forms" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QLayoutWidget"; + r->group = widgetGroup( "Temp" ); + r->includeFile = ""; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->name = "QSplitter"; + r->group = widgetGroup( "Temp" ); + r->includeFile = "qsplitter.h"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "QDesignerTabWidget"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "QDesignerWidget"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = "designer_tabwidget.png"; + r->name = "QDesignerDialog"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QMainWindow"; + r->includeFile = "qmainwindow.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDesignerAction"; + r->includeFile = "qaction.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = FALSE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDesignerActionGroup"; + r->includeFile = "qaction.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = FALSE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QScrollView"; + r->includeFile = "qscrollview.h"; + r->group = widgetGroup( "Temp" ); + r->isContainer = TRUE; + + append( r ); + +#ifndef QT_NO_SQL + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDataBrowser"; + r->includeFile = "qdatabrowser.h"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data Browser"; + r->iconSet = "designer_databrowser.png"; + r->isContainer = TRUE; + + append( r ); + + r = new WidgetDatabaseRecord; + r->iconSet = ""; + r->name = "QDataView"; + r->includeFile = "qdataview.h"; + r->group = widgetGroup( "Database" ); + r->toolTip = "Data View"; + r->iconSet = "designer_dataview.png"; + r->isContainer = TRUE; + + append( r ); +#endif + +#ifndef UIC + setupPlugins(); +#endif +} + +void WidgetDatabase::setupPlugins() +{ + if ( plugins_set_up ) + return; + plugins_set_up = TRUE; + QStringList widgets = widgetManager()->featureList(); + for ( QStringList::Iterator it = widgets.begin(); it != widgets.end(); ++it ) { + if ( hasWidget( *it ) ) + continue; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + WidgetInterface *iface = 0; + widgetManager()->queryInterface( *it, &iface ); + if ( !iface ) + continue; + +#ifndef UIC + QIconSet icon = iface->iconSet( *it ); + if ( !icon.pixmap().isNull() ) + r->icon = new QIconSet( icon ); +#endif + QString grp = iface->group( *it ); + if ( grp.isEmpty() ) + grp = "3rd party widgets"; + r->group = widgetGroup( grp ); + r->toolTip = iface->toolTip( *it ); + r->whatsThis = iface->whatsThis( *it ); + r->includeFile = iface->includeFile( *it ); + r->isContainer = iface->isContainer( *it ); + r->name = *it; + r->isPlugin = TRUE; + append( r ); + iface->release(); + } +} + +/*! + Returns the number of elements in the widget database. +*/ + +int WidgetDatabase::count() +{ + setupDataBase( -1 ); + return dbcount; +} + +/*! + Returns the id at which the ids of custom widgets start. +*/ + +int WidgetDatabase::startCustom() +{ + setupDataBase( -1 ); + return dbcustom; +} + +/*! + Returns the iconset which represents the class registered as \a id. +*/ + +QIconSet WidgetDatabase::iconSet( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QIconSet(); +#if !defined(UIC) && !defined(RESOURCE) + if ( !r->icon ) { + if ( r->iconSet.isEmpty() ) + return QIconSet(); + QPixmap pix = QPixmap::fromMimeSource( r->iconSet ); + if ( pix.isNull() ) + pix = QPixmap( r->iconSet ); + r->icon = new QIconSet( pix ); + } + return *r->icon; +#else + return QIconSet(); +#endif +} + +/*! + Returns the classname of the widget which is registered as \a id. +*/ + +QString WidgetDatabase::className( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->name; +} + +/*! + Returns the group the widget registered as \a id belongs to. +*/ + +QString WidgetDatabase::group( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->group; +} + +/*! + Returns the tooltip text of the widget which is registered as \a id. +*/ + +QString WidgetDatabase::toolTip( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->toolTip; +} + +/*! + Returns the what's this? text of the widget which is registered as \a id. +*/ + +QString WidgetDatabase::whatsThis( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + return r->whatsThis; +} + +/*! + Returns the include file if the widget which is registered as \a id. +*/ + +QString WidgetDatabase::includeFile( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return QString::null; + if ( r->includeFile.isNull() ) + return r->name.lower() + ".h"; + return r->includeFile; +} + +/*! Returns whether the widget registered as \a id is a form. +*/ +bool WidgetDatabase::isForm( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return FALSE; + return r->isForm; +} + +/*! Returns whether the widget registered as \a id can have children. +*/ + +bool WidgetDatabase::isContainer( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return FALSE; + return r->isContainer || r->isForm; +} + +bool WidgetDatabase::isCommon( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return FALSE; + return r->isCommon; +} + +QString WidgetDatabase::createWidgetName( int id ) +{ + setupDataBase( id ); + QString n = className( id ); + if ( n == "QLayoutWidget" ) + n = "Layout"; + if ( n[ 0 ] == 'Q' && n[ 1 ].lower() != n[ 1 ] ) + n = n.mid( 1 ); + int colonColon = n.findRev( "::" ); + if ( colonColon != -1 ) + n = n.mid( colonColon + 2 ); + + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return n; + n += QString::number( ++r->nameCounter ); + n[0] = n[0].lower(); + return n; +} + +/*! Returns the id for \a name or -1 if \a name is unknown. + */ +int WidgetDatabase::idFromClassName( const QString &name ) +{ + setupDataBase( -1 ); + if ( name.isEmpty() ) + return 0; + int *i = className2Id->find( name ); + if ( i ) + return *i; + if ( name == "FormWindow" ) + return idFromClassName( "QLayoutWidget" ); +#ifdef UIC + setupDataBase( -2 ); + i = className2Id->find( name ); + if ( i ) + return *i; +#endif + return -1; +} + +bool WidgetDatabase::hasWidget( const QString &name ) +{ + return className2Id->find( name ) != 0; +} + +WidgetDatabaseRecord *WidgetDatabase::at( int index ) +{ + if ( index < 0 ) + return 0; + if ( index >= dbcustom && index < dbcustomcount ) + return db[ index ]; + if ( index < dbcount ) + return db[ index ]; + return 0; +} + +void WidgetDatabase::insert( int index, WidgetDatabaseRecord *r ) +{ + if ( index < 0 || index >= dbsize ) + return; + db[ index ] = r; + className2Id->insert( r->name, new int( index ) ); + if ( index < dbcustom ) + dbcount = QMAX( dbcount, index ); +} + +void WidgetDatabase::append( WidgetDatabaseRecord *r ) +{ + if ( !was_in_setup ) + setupDataBase( -1 ); + insert( dbcount++, r ); +} + +QString WidgetDatabase::widgetGroup( const QString &g ) +{ + if ( wGroups->find( g ) == -1 ) + wGroups->append( g ); + return g; +} + +bool WidgetDatabase::isGroupEmpty( const QString &grp ) +{ + WidgetDatabaseRecord *r = 0; + for ( int i = 0; i < dbcount; ++i ) { + if ( !( r = db[ i ] ) ) + continue; + if ( r->group == grp ) + return FALSE; + } + return TRUE; +} + +QString WidgetDatabase::widgetGroup( int i ) +{ + setupDataBase( -1 ); + if ( i >= 0 && i < (int)wGroups->count() ) + return wGroups->at( i ); + return QString::null; +} + +int WidgetDatabase::numWidgetGroups() +{ + setupDataBase( -1 ); + return wGroups->count(); +} + +bool WidgetDatabase::isGroupVisible( const QString &g ) +{ + setupDataBase( -1 ); + return invisibleGroups->find( g ) == -1; +} + +int WidgetDatabase::addCustomWidget( WidgetDatabaseRecord *r ) +{ + insert( dbcustomcount++, r ); + return dbcustomcount - 1; +} + +void WidgetDatabase::customWidgetClassNameChanged( const QString &oldName, + const QString &newName ) +{ + int id = idFromClassName( oldName ); + if ( id == -1 ) + return; + WidgetDatabaseRecord *r = db[ id ]; + r->name = newName; + className2Id->remove( oldName ); + className2Id->insert( newName, new int( id ) ); +} + +bool WidgetDatabase::isCustomWidget( int id ) +{ + if ( id >= dbcustom && id < dbcustomcount ) + return TRUE; + return FALSE; +} + +bool WidgetDatabase::isCustomPluginWidget( int id ) +{ + setupDataBase( id ); + WidgetDatabaseRecord *r = at( id ); + if ( !r ) + return FALSE; + return r->isPlugin; +} + +bool WidgetDatabase::isWhatsThisLoaded() +{ + return whatsThisLoaded; +} + +void WidgetDatabase::loadWhatsThis( const QString &docPath ) +{ + QString whatsthisFile = docPath + "/whatsthis"; + QFile f( whatsthisFile ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + while ( !ts.atEnd() ) { + QString s = ts.readLine(); + QStringList l = QStringList::split( " | ", s ); + int id = idFromClassName( l[ 1 ] ); + WidgetDatabaseRecord *r = at( id ); + if ( r ) + r->whatsThis = l[ 0 ]; + } + whatsThisLoaded = TRUE; +} + + +// ### Qt 3.1: make these publically accessible via QWidgetDatabase API +#if defined(UIC) +bool dbnounload = FALSE; +QStringList *dbpaths = 0; +#else +extern QString *qwf_plugin_dir; +#endif + + +QPluginManager *widgetManager() +{ + if ( !widgetPluginManager ) { + QString pluginDir = "/designer"; +#if !defined(UIC) + if ( qwf_plugin_dir ) + pluginDir = *qwf_plugin_dir; +#endif + widgetPluginManager = new QPluginManager( IID_Widget, QApplication::libraryPaths(), pluginDir ); + cleanup_manager.add( &widgetPluginManager ); +#if defined(UIC) + if ( dbnounload ) + widgetPluginManager->setAutoUnload( FALSE ); + if ( dbpaths ) { + QStringList::ConstIterator it = dbpaths->begin(); + for ( ; it != dbpaths->end(); ++it ) + widgetPluginManager->addLibraryPath( *it ); + } +#endif + } + return widgetPluginManager; +} diff --git a/tools/designer/shared/widgetdatabase.h b/tools/designer/shared/widgetdatabase.h new file mode 100644 index 0000000..5802444 --- /dev/null +++ b/tools/designer/shared/widgetdatabase.h @@ -0,0 +1,103 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef WIDGETDATABASE_H +#define WIDGETDATABASE_H + +#include +#include +#include "../interfaces/widgetinterface.h" // up here for GCC 2.7.* compatibility +#include + + +extern QPluginManager *widgetManager(); + +struct WidgetDatabaseRecord +{ + WidgetDatabaseRecord(); + ~WidgetDatabaseRecord(); + QString iconSet, name, group, toolTip, whatsThis, includeFile; + uint isContainer : 1; + uint isForm : 1; + uint isCommon : 1; + uint isPlugin : 1; + QIconSet *icon; + int nameCounter; +}; + +class WidgetDatabase : public Qt +{ +public: + WidgetDatabase(); + static void setupDataBase( int id ); + static void setupPlugins(); + + static int count(); + static int startCustom(); + + static QIconSet iconSet( int id ); + static QString className( int id ); + static QString group( int id ); + static QString toolTip( int id ); + static QString whatsThis( int id ); + static QString includeFile( int id ); + static bool isForm( int id ); + static bool isContainer( int id ); + static bool isCommon( int id ); + + static int idFromClassName( const QString &name ); + static QString createWidgetName( int id ); + + static WidgetDatabaseRecord *at( int index ); + static void insert( int index, WidgetDatabaseRecord *r ); + static void append( WidgetDatabaseRecord *r ); + + static QString widgetGroup( const QString &g ); + static QString widgetGroup( int i ); + static int numWidgetGroups(); + static bool isGroupVisible( const QString &g ); + static bool isGroupEmpty( const QString &grp ); + + static int addCustomWidget( WidgetDatabaseRecord *r ); + static bool isCustomWidget( int id ); + static bool isCustomPluginWidget( int id ); + + static bool isWhatsThisLoaded(); + static void loadWhatsThis( const QString &docPath ); + + static bool hasWidget( const QString &name ); + static void customWidgetClassNameChanged( const QString &oldName, const QString &newName ); + +}; + +#endif diff --git a/tools/designer/templates/Configuration_Dialog.ui b/tools/designer/templates/Configuration_Dialog.ui new file mode 100644 index 0000000..463ff84 --- /dev/null +++ b/tools/designer/templates/Configuration_Dialog.ui @@ -0,0 +1,162 @@ + +MyDialog2 + + + MyDialog2 + + + + 0 + 0 + 597 + 364 + + + + MyDialog2 + + + true + + + + unnamed + + + 11 + + + 6 + + + + + New Item + + + + listBox + + + + 0 + 7 + + + + + + tabWidget + + + + Widget2 + + + Tab + + + + + Widget3 + + + Tab + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + 4144 + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + 0 + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + 0 + + + true + + + + + + + + + buttonOk + clicked() + MyDialog2 + accept() + + + buttonCancel + clicked() + MyDialog2 + reject() + + + diff --git a/tools/designer/templates/Dialog_with_Buttons_(Bottom).ui b/tools/designer/templates/Dialog_with_Buttons_(Bottom).ui new file mode 100644 index 0000000..6e243ac --- /dev/null +++ b/tools/designer/templates/Dialog_with_Buttons_(Bottom).ui @@ -0,0 +1,122 @@ + +MyDialog + + + MyDialog + + + + 0 + 0 + 511 + 282 + + + + MyDialog + + + true + + + + Layout1 + + + + 20 + 240 + 476 + 33 + + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + 4144 + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + 0 + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + 0 + + + true + + + + + + + + buttonOk + clicked() + MyDialog + accept() + + + buttonCancel + clicked() + MyDialog + reject() + + + diff --git a/tools/designer/templates/Dialog_with_Buttons_(Right).ui b/tools/designer/templates/Dialog_with_Buttons_(Right).ui new file mode 100644 index 0000000..09d14e9 --- /dev/null +++ b/tools/designer/templates/Dialog_with_Buttons_(Right).ui @@ -0,0 +1,122 @@ + +MyDialog + + + MyDialog + + + + 0 + 0 + 592 + 470 + + + + MyDialog + + + true + + + + Layout5 + + + + 500 + 30 + 82 + 410 + + + + + unnamed + + + 0 + + + 6 + + + + buttonOk + + + &OK + + + 0 + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + 0 + + + true + + + + + buttonHelp + + + &Help + + + 4144 + + + true + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + buttonOk + clicked() + MyDialog + accept() + + + buttonCancel + clicked() + MyDialog + reject() + + + diff --git a/tools/designer/templates/Tab_Dialog.ui b/tools/designer/templates/Tab_Dialog.ui new file mode 100644 index 0000000..01d6f2c --- /dev/null +++ b/tools/designer/templates/Tab_Dialog.ui @@ -0,0 +1,146 @@ + +MyDialog1 + + + MyDialog1 + + + + 0 + 0 + 528 + 368 + + + + MyDialog1 + + + true + + + + unnamed + + + 11 + + + 6 + + + + tabWidget + + + + Widget8 + + + Tab + + + + + Widget9 + + + Tab + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + buttonHelp + + + &Help + + + 4144 + + + true + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + 0 + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + 0 + + + true + + + + + + + + + buttonOk + clicked() + MyDialog1 + accept() + + + buttonCancel + clicked() + MyDialog1 + reject() + + + diff --git a/tools/designer/tools/conv2ui/conv2ui.pro b/tools/designer/tools/conv2ui/conv2ui.pro new file mode 100644 index 0000000..015ad94 --- /dev/null +++ b/tools/designer/tools/conv2ui/conv2ui.pro @@ -0,0 +1,10 @@ +###################################################################### +# Automatically generated by qmake (1.04a) Tue Oct 1 18:34:56 2002 +###################################################################### +TEMPLATE = app +CONFIG -= moc + +# Input +INCLUDEPATH += ../../interfaces +SOURCES += main.cpp +DESTDIR = $$QT_BUILD_TREE/bin diff --git a/tools/designer/tools/conv2ui/main.cpp b/tools/designer/tools/conv2ui/main.cpp new file mode 100644 index 0000000..7ede6c7 --- /dev/null +++ b/tools/designer/tools/conv2ui/main.cpp @@ -0,0 +1,220 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt GUI Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#include +#include "filterinterface.h" +#include + +class Conv2ui { +public: + Conv2ui(); + ~Conv2ui(); + bool reinit(); + bool convert( const QString & filename, const QDir & dest ); + QStringList featureList(); +private: + QString getTag( const QString & filename ); + QString absName( const QString & filename ); + QPluginManager * importFiltersManager; +}; + +Conv2ui::Conv2ui() : importFiltersManager( 0 ) +{ + reinit(); +} + +Conv2ui::~Conv2ui() +{ + if ( importFiltersManager ) + delete importFiltersManager; +} + +bool Conv2ui::reinit() +{ + if ( importFiltersManager ) + delete importFiltersManager; + importFiltersManager = new QPluginManager( IID_ImportFilter, + QApplication::libraryPaths(), + "/designer"); + return !!importFiltersManager; +} + +bool Conv2ui::convert( const QString & filename, const QDir & dest ) +{ + if ( !importFiltersManager ) { + qWarning( "Conv2ui: no QPluginManager was found" ); + return FALSE; + } + + if ( !QFile::exists( absName( filename ) ) ) { + qWarning( "Conv2ui: can not find file %s", filename.latin1() ); + return FALSE; + } + + QString tag = getTag( filename ); + QStringList lst = importFiltersManager->featureList(); + + for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { + + ImportFilterInterface * interface = 0; + importFiltersManager->queryInterface( *it, &interface ); + + if ( !interface ) continue; + + if ( (*it).contains( tag, FALSE ) ) { + // Make sure we output the files in the destination dir + QString absfile = absName( filename ); + QString current = QDir::currentDirPath(); + QDir::setCurrent( dest.absPath() ); + interface->import( *it, absfile ); // resulting files go into the current dir + QDir::setCurrent( current ); + } + + interface->release(); + + } + + return TRUE; +} + +QStringList Conv2ui::featureList() +{ + if ( !importFiltersManager ) { + return 0; + } + return importFiltersManager->featureList(); +} + +QString Conv2ui::getTag( const QString & filename ) +{ + QFileInfo info( filename ); + return info.extension(); +} + +QString Conv2ui::absName( const QString & filename ) +{ + QString absFileName = QDir::isRelativePath( filename ) ? + QDir::currentDirPath() + + QDir::separator() + + filename : + filename; + return absFileName; +} + +void printHelpMessage( QStringList & formats ) +{ + printf( "Usage: conv2ui [options] \n\n" ); + printf( "Options:\n"); + printf( "\t-help\t\tDisplay this information\n" ); + printf( "\t-silent\t\tDon't write any messages\n"); + printf( "\t-version\tDisplay version of conv2ui\n"); + printf( "Supported file formats:\n" ); + for ( QStringList::Iterator it = formats.begin(); it != formats.end(); ++it ) + printf( "\t%s\n", (*it).latin1() ); +} + +void printVersion() +{ + printf( "Qt user interface file converter for Qt version %s\n", QT_VERSION_STR ); +} + +int main( int argc, char ** argv ) +{ + Conv2ui conv; + + bool help = TRUE; + bool silent = FALSE; + bool version = FALSE; + bool unrecognized = FALSE; + + // parse options + int argi = 1; + while ( argi < argc && argv[argi][0] == '-' ) { + int i = 1; + while ( argv[argi][i] != '\0' ) { + + if ( argv[argi][i] == 's' ) { + silent = TRUE; + break; + } else if ( argv[argi][i] == 'h' ) { + help = TRUE; + break; + } else if ( argv[argi][i] == 'v' ) { + version = TRUE; + silent = TRUE; + break; + } else { + unrecognized = TRUE; + } + i++; + } + argi++; + } + + // get source file + QString src; + if ( argv[argi] ) { + src = argv[argi++]; + } + + // get destination directory + QDir dst; + if ( argv[argi] ) { + dst.setPath( argv[argi++] ); + help = FALSE; + } + + if ( !silent ) { + printf( "Qt user interface file converter.\n" ); + if ( unrecognized ) { + printf( "conv2ui: Unrecognized option\n" ); + } + } + if ( version ) { + printVersion(); + return 0; + } else if ( help ) { + QStringList formats = conv.featureList(); + printHelpMessage( formats ); + return 0; + } + + // do the magic + if ( conv.convert( src, dst ) ) + return 0; + return -1; +} diff --git a/tools/designer/tools/createcw/README b/tools/designer/tools/createcw/README new file mode 100644 index 0000000..cc48234 --- /dev/null +++ b/tools/designer/tools/createcw/README @@ -0,0 +1,18 @@ +This small application makes it much easier to create custom widget +descriptions for Qt Designer. Using them you can use custom widgets +in Qt Designer including their signals, slots and properties. + +The usual way to do this is to enter all the information in the custom +widget dialog in Qt Designer for each widget. But this small tool can +create these description files for your custom widgets which you then +can simply import into Qt Designer. So you can use your custom widgets +without any additional work in your forms in Qt Designer. + +To do this you must modify the sourcecode (main.cpp) a bit and +recompile it afterwards. For further instructions how to use it see +the comments starting with STEP1 and STEP2 in main.cpp. + +Note that Qt Designer now supports widget plugins which are more +versatile and work just like built-in widgets, so you may prefer to +make your custom widgets into plugins. See the designer manual for +more information. diff --git a/tools/designer/tools/createcw/createcw.pro b/tools/designer/tools/createcw/createcw.pro new file mode 100644 index 0000000..415c0be --- /dev/null +++ b/tools/designer/tools/createcw/createcw.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +CONFIG += qt warn_on release +HEADERS = +SOURCES = main.cpp +TARGET = createcw + +target.path = $$bins.path +INSTALLS += target diff --git a/tools/designer/tools/createcw/main.cpp b/tools/designer/tools/createcw/main.cpp new file mode 100644 index 0000000..78f8562 --- /dev/null +++ b/tools/designer/tools/createcw/main.cpp @@ -0,0 +1,190 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt GUI Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#include +#include + +// STEP1: Include header files of the widgets for which a description +// should be created here. If you have a widget which is defined in +// the file mycustomwidget.h in /home/joedeveloper/src, write here +// +// #include "/home/joedeveloper/src/mycustomwidget.h" +// +// Now go on to STEP2! + +// ----------------------------- + +struct Widget +{ + QWidget *w; // the widget + QString include; // header file + QString location; // "global" for include <...> or "local" include "..." +}; + +static QString makeIndent( int indent ) +{ + QString s; + s.fill( ' ', indent * 4 ); + return s; +} + +static QString entitize( const QString &s ) +{ + QString s2 = s; + s2 = s2.replace( "\"", """ ); + s2 = s2.replace( "&", "&" ); + s2 = s2.replace( ">", ">" ); + s2 = s2.replace( "<", "<" ); + s2 = s2.replace( "'", "'" ); + return s2; +} + +static QString convert_type( const QString &s ) +{ + QString str( s ); + if ( str[ 0 ] == 'Q' ) + str.remove( 0, 1 ); + str[ 0 ] = str[ 0 ].upper(); + return str; +} + +static void createDescription( const QValueList &l, QTextStream &ts ) +{ + int indent = 0; + ts << "" << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + + for ( QValueList::ConstIterator it = l.begin(); it != l.end(); ++it ) { + Widget w = *it; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << w.w->className() << "" << endl; + ts << makeIndent( indent ) << "

    " << w.include << "
    " << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << w.w->sizeHint().width() << "" << endl; + ts << makeIndent( indent ) << "" << w.w->sizeHint().height() << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << makeIndent( indent ) << "" << ( w.w->inherits( "QGroupBox" ) || w.w->inherits( "QWidgetStack" ) ) << "" << endl; + ts << makeIndent( indent ) << "" << endl; + indent++; + ts << makeIndent( indent ) << "" << (int)w.w->sizePolicy().horData() << "" << endl; + ts << makeIndent( indent ) << "" << (int)w.w->sizePolicy().verData() << "" << endl; + indent--; + ts << makeIndent( indent ) << "" << endl; + + QStrList sigs = w.w->metaObject()->signalNames( TRUE ); + if ( !sigs.isEmpty() ) { + for ( int i = 0; i < (int)sigs.count(); ++i ) + ts << makeIndent( indent ) << "" << entitize( sigs.at( i ) ) << "" << endl; + } + QStrList slts = w.w->metaObject()->slotNames( TRUE ); + if ( !slts.isEmpty() ) { + for ( int i = 0; i < (int)slts.count(); ++i ) { + QMetaData::Access data = w.w->metaObject()->slot( i, TRUE )->access; + if ( data == QMetaData::Private ) + continue; + ts << makeIndent( indent ) << "" << entitize( slts.at( i ) ) << "" << endl; + } + } + QStrList props = w.w->metaObject()->propertyNames( TRUE ); + if ( !props.isEmpty() ) { + for ( int i = 0; i < (int)props.count(); ++i ) { + const QMetaProperty *p = w.w->metaObject()-> + property( w.w->metaObject()-> + findProperty( props.at( i ), TRUE ), TRUE ); + if ( !p ) + continue; + if ( !p->writable() || !p->designable( w.w ) ) + continue; + ts << makeIndent( indent ) << "type() ) << "\">" << entitize( p->name() ) << "" << endl; + } + } + indent--; + ts << makeIndent( indent ) << "" << endl; + } + + indent--; + ts << makeIndent( indent ) << "" << endl; + ts << "" << endl; +} + +int main( int argc, char **argv ) +{ + if ( argc < 2 ) + return -1; + QString fn = argv[1]; + QFile f( fn ); + if ( !f.open( IO_WriteOnly ) ) + return -1; + QTextStream ts( &f ); + QApplication a( argc, argv ); + + QValueList wl; + + // STEP2: Instantiate all widgets for which a description should + // be created here and add them to the list wl. If your custom widget + // is e.g. called MyCustomWidget you would write here + // + // Widget w; + // w.w = new MyCustomWidget( 0, 0 ); + // w.include = "mycustomwidget.h"; + // w.location = "global"; + // wl.append( w ); + // + // After that compile the program, link it with your custom widget + // (library or object file) and run it like this: + // (unix): ./createcw mywidgets.cw + // (win32): createcw mywidgets.cw + // + // After that you can import this description file into the Qt + // Designer using the Custom-Widget Dialog (See + // Tools->Custom->Edit Custom Widgets... in the Qt Designer) + // and use these custom widget there in your forms. + + + + // ---------------------------------------------- + + createDescription( wl, ts ); + f.close(); + return 0; +} diff --git a/tools/designer/uic/embed.cpp b/tools/designer/uic/embed.cpp new file mode 100644 index 0000000..f6f09c4 --- /dev/null +++ b/tools/designer/uic/embed.cpp @@ -0,0 +1,316 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "uic.h" +#include +#include +#include +#include +#include +#include +#include + +// on embedded, we do not compress image data. Rationale: by mapping +// the ready-only data directly into memory we are both faster and +// more memory efficient +#if defined(Q_WS_QWS) && !defined(QT_NO_IMAGE_COLLECTION_COMPRESSION) +#define QT_NO_IMAGE_COLLECTION_COMPRESSION +#endif + +struct EmbedImage +{ + ~EmbedImage() { delete[] colorTable; } + int width, height, depth; + int numColors; + QRgb* colorTable; + QString name; + QString cname; + bool alpha; +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + ulong compressed; +#endif +}; + +static QString convertToCIdentifier( const char *s ) +{ + QString r = s; + int len = r.length(); + if ( len > 0 && !isalpha( (char)r[0].latin1() ) ) + r[0] = '_'; + for ( int i=1; i> 4) & 15]; + s += hexdigits[v & 15]; + if ( i < (int)len-1 ) + s += ','; + } + if ( s.length() ) + out << (const char*)s; + return len; +} + +static void embedData( QTextStream& out, const QRgb* input, int n ) +{ + out << hex; + const QRgb *v = input; + for ( int i=0; i\n"; + out << "#include \n"; + out << "#include \n"; + out << "#include \n"; + out << "\n"; + + QPtrList list_image; + list_image.setAutoDelete( TRUE ); + int image_count = 0; + for ( it = images.begin(); it != images.end(); ++it ) { + QImage img; + if ( !img.load( *it ) ) { + fprintf( stderr, "uic: cannot load image file %s\n", (*it).latin1() ); + continue; + } + EmbedImage *e = new EmbedImage; + e->width = img.width(); + e->height = img.height(); + e->depth = img.depth(); + e->numColors = img.numColors(); + e->colorTable = new QRgb[e->numColors]; + e->alpha = img.hasAlphaBuffer(); + memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(QRgb)); + QFileInfo fi( *it ); + e->name = fi.fileName(); + e->cname = QString("image_%1").arg( image_count++); + list_image.append( e ); + out << "// " << *it << "\n"; + QString s; + if ( e->depth == 1 ) + img = img.convertBitOrder(QImage::BigEndian); + out << s.sprintf( "static const unsigned char %s_data[] = {", + (const char *)e->cname ); +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + e->compressed = +#endif + embedData( out, img.bits(), img.numBytes() ); + out << "\n};\n\n"; + if ( e->numColors ) { + out << s.sprintf( "static const QRgb %s_ctable[] = {", + (const char *)e->cname ); + embedData( out, e->colorTable, e->numColors ); + out << "\n};\n\n"; + } + } + + if ( !list_image.isEmpty() ) { + out << "static struct EmbedImage {\n" + " int width, height, depth;\n" + " const unsigned char *data;\n" +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + " ulong compressed;\n" +#endif + " int numColors;\n" + " const QRgb *colorTable;\n" + " bool alpha;\n" + " const char *name;\n" + "} embed_image_vec[] = {\n"; + EmbedImage *e = list_image.first(); + while ( e ) { + out << " { " + << e->width << ", " + << e->height << ", " + << e->depth << ", " + << "(const unsigned char*)" << e->cname << "_data, " +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + << e->compressed << ", " +#endif + << e->numColors << ", "; + if ( e->numColors ) + out << e->cname << "_ctable, "; + else + out << "0, "; + if ( e->alpha ) + out << "TRUE, "; + else + out << "FALSE, "; + out << "\"" << e->name << "\" },\n"; + e = list_image.next(); + } +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + out << " { 0, 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n"; +#else + out << " { 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n"; +#endif + + out << "\n" + "static QImage uic_findImage( const QString& name )\n" + "{\n" + " for ( int i=0; embed_image_vec[i].data; i++ ) {\n" + " if ( QString::fromUtf8(embed_image_vec[i].name) == name ) {\n" +#ifndef QT_NO_IMAGE_COLLECTION_COMPRESSION + " QByteArray baunzip;\n" + " baunzip = qUncompress( embed_image_vec[i].data, \n" + " embed_image_vec[i].compressed );\n" + " QImage img((uchar*)baunzip.data(),\n" + " embed_image_vec[i].width,\n" + " embed_image_vec[i].height,\n" + " embed_image_vec[i].depth,\n" + " (QRgb*)embed_image_vec[i].colorTable,\n" + " embed_image_vec[i].numColors,\n" + " QImage::BigEndian\n" + " );\n" + " img = img.copy();\n" +#else + " QImage img((uchar*)embed_image_vec[i].data,\n" + " embed_image_vec[i].width,\n" + " embed_image_vec[i].height,\n" + " embed_image_vec[i].depth,\n" + " (QRgb*)embed_image_vec[i].colorTable,\n" + " embed_image_vec[i].numColors,\n" + " QImage::BigEndian\n" + " );\n" +#endif + " if ( embed_image_vec[i].alpha )\n" + " img.setAlphaBuffer(TRUE);\n" + " return img;\n" + " }\n" + " }\n" + " return QImage();\n" + "}\n\n"; + + out << "class MimeSourceFactory_" << cProject << " : public QMimeSourceFactory\n"; + out << "{\n"; + out << "public:\n"; + out << " MimeSourceFactory_" << cProject << "() {}\n"; + out << " ~MimeSourceFactory_" << cProject << "() {}\n"; + out << " const QMimeSource* data( const QString& abs_name ) const {\n"; + out << "\tconst QMimeSource* d = QMimeSourceFactory::data( abs_name );\n"; + out << "\tif ( d || abs_name.isNull() ) return d;\n"; + out << "\tQImage img = uic_findImage( abs_name );\n"; + out << "\tif ( !img.isNull() )\n"; + out << "\t ((QMimeSourceFactory*)this)->setImage( abs_name, img );\n"; + out << "\treturn QMimeSourceFactory::data( abs_name );\n"; + out << " };\n"; + out << "};\n\n"; + + out << "static QMimeSourceFactory* factory = 0;\n"; + out << "\n"; + + out << "void qInitImages_" << cProject << "()\n"; + out << "{\n"; + out << " if ( !factory ) {\n"; + out << "\tfactory = new MimeSourceFactory_" << cProject << ";\n"; + out << "\tQMimeSourceFactory::defaultFactory()->addFactory( factory );\n"; + out << " }\n"; + out << "}\n\n"; + + out << "void qCleanupImages_" << cProject << "()\n"; + out << "{\n"; + out << " if ( factory ) {\n"; + out << "\tQMimeSourceFactory::defaultFactory()->removeFactory( factory );\n"; + out << "\tdelete factory;\n"; + out << "\tfactory = 0;\n"; + out << " }\n"; + out << "}\n\n"; + + out << "class StaticInitImages_" << cProject << "\n"; + out << "{\n"; + out << "public:\n"; + out << " StaticInitImages_" << cProject << "() { qInitImages_" << cProject << "(); }\n"; + out << "#if defined(Q_OS_SCO) || defined(Q_OS_UNIXWARE)\n"; + out << " ~StaticInitImages_" << cProject << "() { }\n"; + out << "#else\n"; + out << " ~StaticInitImages_" << cProject << "() { qCleanupImages_" << cProject << "(); }\n"; + out << "#endif\n"; + out << "};\n\n"; + + out << "static StaticInitImages_" << cProject << " staticImages;\n"; + } +} diff --git a/tools/designer/uic/form.cpp b/tools/designer/uic/form.cpp new file mode 100644 index 0000000..699e446 --- /dev/null +++ b/tools/designer/uic/form.cpp @@ -0,0 +1,1452 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include +#include +#include +#include +#include +#include +#define NO_STATIC_COLORS +#include + +static QByteArray unzipXPM( QString data, ulong& length ) +{ + const int lengthOffset = 4; + int baSize = data.length() / 2 + lengthOffset; + uchar *ba = new uchar[ baSize ]; + for ( int i = lengthOffset; i < baSize; ++i ) { + char h = data[ 2 * (i-lengthOffset) ].latin1(); + char l = data[ 2 * (i-lengthOffset) + 1 ].latin1(); + uchar r = 0; + if ( h <= '9' ) + r += h - '0'; + else + r += h - 'a' + 10; + r = r << 4; + if ( l <= '9' ) + r += l - '0'; + else + r += l - 'a' + 10; + ba[ i ] = r; + } + // qUncompress() expects the first 4 bytes to be the expected length of the + // uncompressed data + ba[0] = ( length & 0xff000000 ) >> 24; + ba[1] = ( length & 0x00ff0000 ) >> 16; + ba[2] = ( length & 0x0000ff00 ) >> 8; + ba[3] = ( length & 0x000000ff ); + QByteArray baunzip = qUncompress( ba, baSize ); + delete[] ba; + return baunzip; +} + +#if QT_VERSION >= 0x030900 +#error Add this functionality to QDir (relativePathTo() maybe?) and \ +remove it from here and from moc +#endif + +QCString combinePath( const char *infile, const char *outfile ) +{ + QFileInfo inFileInfo( QDir::current(), QFile::decodeName(infile) ); + QFileInfo outFileInfo( QDir::current(), QFile::decodeName(outfile) ); + int numCommonComponents = 0; + + QStringList inSplitted = + QStringList::split( '/', inFileInfo.dir().canonicalPath(), TRUE ); + QStringList outSplitted = + QStringList::split( '/', outFileInfo.dir().canonicalPath(), TRUE ); + + while ( !inSplitted.isEmpty() && !outSplitted.isEmpty() && + inSplitted.first() == outSplitted.first() ) { + inSplitted.remove( inSplitted.begin() ); + outSplitted.remove( outSplitted.begin() ); + numCommonComponents++; + } + + if ( numCommonComponents < 2 ) { + /* + The paths don't have the same drive, or they don't have the + same root directory. Use an absolute path. + */ + return QFile::encodeName( inFileInfo.absFilePath() ); + } else { + /* + The paths have something in common. Use a path relative to + the output file. + */ + while ( !outSplitted.isEmpty() ) { + outSplitted.remove( outSplitted.begin() ); + inSplitted.prepend( ".." ); + } + inSplitted.append( inFileInfo.fileName() ); + return QFile::encodeName( inSplitted.join("/") ); + } +} + +/*! + Creates a declaration (header file) for the form given in \a e + + \sa createFormImpl(), createObjectDecl() +*/ +void Uic::createFormDecl( const QDomElement &e ) +{ + QDomElement n; + QDomNodeList nl; + int i; + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + + QStringList typeDefs; + + QMap customWidgetIncludes; + + QString imageMembers; + + /* + We are generating a few QImage members that are not strictly + necessary in some cases. Ideally, we would use requiredImage, + which is computed elsewhere, to keep the generated .h and .cpp + files synchronized. + */ + + // at first the images + QMap customWidgets; + QStringList forwardDecl; + QStringList forwardDecl2; + QString exportMacro; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "images" ) { + nl = n.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QString img = registerObject( nl.item(i).toElement().attribute("name") ); + registerObject( img ); + imageMembers += QString( " QPixmap %1;\n" ).arg( img ); + } + } else if ( n.tagName() == "customwidgets" ) { + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "customwidget" ) { + QDomElement n3 = n2.firstChild().toElement(); + QString cl; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + while ( !n3.isNull() ) { + if ( n3.tagName() == "class" ) { + cl = n3.firstChild().toText().data(); + if ( !nofwd ) + forwardDecl << cl; + customWidgets.insert( cl, 0 ); + r->name = cl; + } else if ( n3.tagName() == "header" ) { + CustomInclude ci; + ci.header = n3.firstChild().toText().data(); + ci.location = n3.attribute( "location", "global" ); + r->includeFile = ci.header; + customWidgetIncludes.insert( cl, ci ); + } + WidgetDatabase::append( r ); + n3 = n3.nextSibling().toElement(); + } + } + n2 = n2.nextSibling().toElement(); + } + } + } + + // register the object and unify its name + objName = registerObject( objName ); + QString protector = objName.upper() + "_H"; + protector.replace( "::", "_" ); + out << "#ifndef " << protector << endl; + out << "#define " << protector << endl; + out << endl; + out << "#include " << endl; // for broken HP-UX compilers + + if ( !imageMembers.isEmpty() ) + out << "#include " << endl; + + QStringList globalIncludes, localIncludes; + int wid = WidgetDatabase::idFromClassName( objClass ); + { + QMap::Iterator it = customWidgetIncludes.find( objClass ); + if ( it != customWidgetIncludes.end() ) { + if ( ( *it ).location == "global" ) + globalIncludes += (*it).header; + else + localIncludes += (*it).header; + } else { + globalIncludes += WidgetDatabase::includeFile( wid ); + } + } + + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "impldecl", "in implementation" ) == "in declaration" && + n2.attribute( "location" ) != "local" ) { + if ( s.right( 5 ) == ".ui.h" ) + continue; + globalIncludes += s; + } + } + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "impldecl", "in implementation" ) == "in declaration" && + n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) { + if ( s.right( 5 ) == ".ui.h" ) + continue; + localIncludes += s; + } + } + + QStringList::Iterator it; + + globalIncludes = unique( globalIncludes ); + for ( it = globalIncludes.begin(); it != globalIncludes.end(); ++it ) { + if ( !(*it).isEmpty() ) + out << "#include <" << *it << ">" << endl; + } + localIncludes = unique( localIncludes ); + for ( it = localIncludes.begin(); it != localIncludes.end(); ++it ) { + if ( !(*it).isEmpty() ) + out << "#include \"" << *it << "\"" << endl; + } + out << endl; + + // forward declarations for child widgets and layouts + out << "class QVBoxLayout;" << endl; + out << "class QHBoxLayout;" << endl; + out << "class QGridLayout;" << endl; + out << "class QSpacerItem;" << endl; + if ( objClass == "QMainWindow" ) { + out << "class QAction;" << endl; + out << "class QActionGroup;" << endl; + out << "class QToolBar;" << endl; + out << "class QPopupMenu;" << endl; + } + + bool dbForm = FALSE; + registerDatabases( e ); + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + forwardDecl += "QSqlDatabase"; + if ( dbCursors.count() ) + forwardDecl += "QSqlCursor"; + if ( dbForms[ "(default)" ].count() ) + dbForm = TRUE; + bool subDbForms = FALSE; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)" ) { + if ( dbForms[ (*it) ].count() ) { + subDbForms = TRUE; + break; + } + } + } + if ( dbForm || subDbForms ) + forwardDecl += "QSqlForm"; + + for ( it = tags.begin(); it != tags.end(); ++it ) { + nl = e.parentNode().toElement().elementsByTagName( *it ); + for ( i = 1; i < (int) nl.length(); i++ ) { // begin at 1, 0 is the toplevel widget + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "QLayoutWidget" ) + continue; // hide qlayoutwidgets + if ( s == "Line" ) + s = "QFrame"; + if ( !(nofwd && customWidgets.contains(s)) ) + forwardDecl += s; + if ( s.mid( 1 ) == "ListBox" || s.mid( 1 ) == "ListView" || s.mid( 1 ) == "IconView" ) + forwardDecl += "Q" + s.mid( 1 ) + "Item"; + if ( s == "QDataTable" ) { // other convenience classes which are used in QDataTable signals, and thus should be forward-declared by uic for us + forwardDecl += "QSqlRecord"; + } + } + } + + // some typedefs, maybe + typeDefs = unique( typeDefs ); + for ( it = typeDefs.begin(); it != typeDefs.end(); ++it ) { + if ( !(*it).isEmpty() ) + out << "typedef " << *it << ";" << endl; + } + + nl = e.parentNode().toElement().elementsByTagName( "forward" ); + for ( i = 0; i < (int) nl.length(); i++ ) + forwardDecl2 << nl.item(i).toElement().firstChild().toText().data(); + + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "impldecl", "in implementation" ) == "in declaration" && + n2.attribute( "location" ) != "local" ) + globalIncludes += s; + } + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "impldecl", "in implementation" ) == "in declaration" && + n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) + localIncludes += s; + } + nl = e.parentNode().toElement().elementsByTagName( "exportmacro" ); + if ( nl.length() == 1 ) + exportMacro = nl.item( 0 ).firstChild().toText().data(); + + forwardDecl = unique( forwardDecl ); + for ( it = forwardDecl.begin(); it != forwardDecl.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != objClass ) { + QString forwardName = *it; + QStringList forwardNamespaces = QStringList::split( "::", + forwardName ); + forwardName = forwardNamespaces.last(); + forwardNamespaces.remove( forwardNamespaces.fromLast() ); + + QStringList::ConstIterator ns = forwardNamespaces.begin(); + while ( ns != forwardNamespaces.end() ) { + out << "namespace " << *ns << " {" << endl; + ++ns; + } + out << "class " << forwardName << ";" << endl; + for ( int i = 0; i < (int) forwardNamespaces.count(); i++ ) + out << "}" << endl; + } + } + + for ( it = forwardDecl2.begin(); it != forwardDecl2.end(); ++it ) { + QString fd = *it; + fd = fd.stripWhiteSpace(); + if ( !fd.endsWith( ";" ) ) + fd += ";"; + out << fd << endl; + } + + out << endl; + + QStringList::ConstIterator ns = namespaces.begin(); + while ( ns != namespaces.end() ) { + out << "namespace " << *ns << " {" << endl; + ++ns; + } + + out << "class "; + if ( !exportMacro.isEmpty() ) + out << exportMacro << " "; + out << bareNameOfClass << " : public " << objClass << endl << "{" << endl; + + /* qmake ignore Q_OBJECT */ + out << " Q_OBJECT" << endl; + out << endl; + out << "public:" << endl; + + // constructor + if ( objClass == "QDialog" || objClass == "QWizard" ) { + out << " " << bareNameOfClass << "( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );" << endl; + } else if ( objClass == "QWidget" ) { + out << " " << bareNameOfClass << "( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );" << endl; + } else if ( objClass == "QMainWindow" ) { + out << " " << bareNameOfClass << "( QWidget* parent = 0, const char* name = 0, WFlags fl = WType_TopLevel );" << endl; + isMainWindow = TRUE; + } else { + out << " " << bareNameOfClass << "( QWidget* parent = 0, const char* name = 0 );" << endl; + } + + // destructor + out << " ~" << bareNameOfClass << "();" << endl; + out << endl; + + // children + bool needPolish = FALSE; + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + n = nl.item(i).toElement(); + createObjectDecl( n ); + QString t = n.tagName(); + if ( t == "vbox" || t == "hbox" || t == "grid" ) + createSpacerDecl( n ); + QString s = getClassName( n ); + if ( s == "QDataTable" || s == "QDataBrowser" ) { + if ( isFrameworkCodeGenerated( n ) ) + needPolish = TRUE; + } + } + + // actions, toolbars, menus + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "actions" ) { + for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + createActionDecl( a ); + } else if ( n.tagName() == "toolbars" ) { + for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + createToolbarDecl( a ); + } else if ( n.tagName() == "menubar" ) { + out << " " << "QMenuBar *" << getObjectName( n ) << ";" << endl; + for ( QDomElement a = n.firstChild().toElement(); !a.isNull(); a = a.nextSibling().toElement() ) + createMenuBarDecl( a ); + } + } + out << endl; + + // database connections + dbConnections = unique( dbConnections ); + bool hadOutput = FALSE; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() ) { + // only need pointers to non-default connections + if ( (*it) != "(default)" && !(*it).isEmpty() ) { + out << indent << "QSqlDatabase* " << *it << "Connection;" << endl; + hadOutput = TRUE; + } + } + } + if ( hadOutput ) + out << endl; + + QStringList publicSlots, protectedSlots, privateSlots; + QStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + QStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedSlots += functionName; + protectedSlotTypes += returnType; + protectedSlotSpecifier += specifier; + } else if ( access == "private" ) { + privateSlots += functionName; + privateSlotTypes += returnType; + privateSlotSpecifier += specifier; + } else { + publicSlots += functionName; + publicSlotTypes += returnType; + publicSlotSpecifier += specifier; + } + } + + QStringList publicFuncts, protectedFuncts, privateFuncts; + QStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp; + QStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec; + + nl = e.parentNode().toElement().elementsByTagName( "function" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item( i ).toElement(); + if ( n.parentNode().toElement().tagName() != "functions" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedFuncts += functionName; + protectedFunctRetTyp += returnType; + protectedFunctSpec += specifier; + } else if ( access == "private" ) { + privateFuncts += functionName; + privateFunctRetTyp += returnType; + privateFunctSpec += specifier; + } else { + publicFuncts += functionName; + publicFunctRetTyp += returnType; + publicFunctSpec += specifier; + } + } + + QStringList publicVars, protectedVars, privateVars; + nl = e.parentNode().toElement().elementsByTagName( "variable" ); + for ( i = 0; i < (int)nl.length(); i++ ) { + n = nl.item( i ).toElement(); + // Because of compatibility the next lines have to be commented out. + // Someday it should be uncommented. + //if ( n.parentNode().toElement().tagName() != "variables" ) + // continue; + QString access = n.attribute( "access", "protected" ); + QString var = n.firstChild().toText().data().stripWhiteSpace(); + if (var.isEmpty()) + continue; + if ( !var.endsWith( ";" ) ) + var += ";"; + if ( access == "public" ) + publicVars += var; + else if ( access == "private" ) + privateVars += var; + else + protectedVars += var; + } + + if ( !publicVars.isEmpty() ) { + for ( it = publicVars.begin(); it != publicVars.end(); ++it ) + out << indent << *it << endl; + out << endl; + } + if ( !publicFuncts.isEmpty() ) + writeFunctionsDecl( publicFuncts, publicFunctRetTyp, publicFunctSpec ); + + if ( needPolish || !publicSlots.isEmpty() ) { + out << "public slots:" << endl; + if ( needPolish ) { + out << indent << "virtual void polish();" << endl; + out << endl; + } + if ( !publicSlots.isEmpty() ) + writeFunctionsDecl( publicSlots, publicSlotTypes, publicSlotSpecifier ); + } + + // find signals + QStringList extraSignals; + nl = e.parentNode().toElement().elementsByTagName( "signal" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item( i ).toElement(); + if ( n.parentNode().toElement().tagName() != "signals" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString sigName = n.firstChild().toText().data().stripWhiteSpace(); + if ( sigName.endsWith( ";" ) ) + sigName = sigName.left( sigName.length() - 1 ); + extraSignals += sigName; + } + + // create signals + if ( !extraSignals.isEmpty() ) { + out << "signals:" << endl; + for ( it = extraSignals.begin(); it != extraSignals.end(); ++it ) + out << " void " << (*it) << ";" << endl; + out << endl; + } + + out << "protected:" << endl; + if ( !protectedVars.isEmpty() ) { + for ( it = protectedVars.begin(); it != protectedVars.end(); ++it ) + out << indent << *it << endl; + out << endl; + } + if ( !protectedFuncts.isEmpty() ) + writeFunctionsDecl( protectedFuncts, protectedFunctRetTyp, protectedFunctSpec ); + + // child layouts + registerLayouts( e ); + out << endl; + +#if QT_VERSION >= 0x030900 +#error Make languageChange() a virtual protected non-slot member of QWidget +#endif + + out << "protected slots:" << endl; + out << " virtual void languageChange();" << endl; + if ( !protectedSlots.isEmpty() ) { + out << endl; + writeFunctionsDecl( protectedSlots, protectedSlotTypes, protectedSlotSpecifier ); + } + out << endl; + + // create all private stuff + if ( !privateFuncts.isEmpty() || !privateVars.isEmpty() || !imageMembers.isEmpty() ) { + out << "private:" << endl; + if ( !privateVars.isEmpty() ) { + for ( it = privateVars.begin(); it != privateVars.end(); ++it ) + out << indent << *it << endl; + out << endl; + } + if ( !imageMembers.isEmpty() ) { + out << imageMembers; + out << endl; + } + if ( !privateFuncts.isEmpty() ) + writeFunctionsDecl( privateFuncts, privateFunctRetTyp, privateFunctSpec ); + } + + if ( !privateSlots.isEmpty() ) { + out << "private slots:" << endl; + writeFunctionsDecl( privateSlots, privateSlotTypes, privateSlotSpecifier ); + } + + out << "};" << endl; + for ( i = 0; i < (int) namespaces.count(); i++ ) + out << "}" << endl; + + out << endl; + out << "#endif // " << protector << endl; +} + +void Uic::writeFunctionsDecl( const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst ) +{ + QValueListConstIterator it, it2, it3; + for ( it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin(); + it != fuLst.end(); ++it, ++it2, ++it3 ) { + QString signature = *it; + QString specifier; + QString pure; + QString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "static" ) { + specifier = "static "; + } else { + if ( *it3 != "non virtual" && *it3 != "nonVirtual" ) + specifier = "virtual "; + if ( *it3 == "pure virtual" || *it3 == "pureVirtual" ) + pure = " = 0"; + } + type.replace( ">>", "> >" ); + if ( !signature.contains("operator") ) + signature.replace( ">>", "> >" ); + out << " " << specifier << type << " " << signature << pure << ";" << endl; + } + out << endl; +} + +/*! + Creates an implementation (cpp-file) for the form given in \a e. + + \sa createFormDecl(), createObjectImpl() + */ +void Uic::createFormImpl( const QDomElement &e ) +{ + QDomElement n; + QDomNodeList nl; + int i; + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + + // generate local and local includes required + QStringList globalIncludes, localIncludes; + QStringList::Iterator it; + + QMap customWidgetIncludes; + + // find additional slots and functions + QStringList extraFuncts; + QStringList extraFunctTyp; + QStringList extraFunctSpecifier; + + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + extraFuncts += functionName; + extraFunctTyp += n.attribute( "returnType", "void" ); + extraFunctSpecifier += n.attribute( "specifier", "virtual" ); + } + + nl = e.parentNode().toElement().elementsByTagName( "function" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "functions" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + extraFuncts += functionName; + extraFunctTyp += n.attribute( "returnType", "void" ); + extraFunctSpecifier += n.attribute( "specifier", "virtual" ); + } + + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "customwidgets" ) { + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "customwidget" ) { + QDomElement n3 = n2.firstChild().toElement(); + QString cl; + WidgetDatabaseRecord *r = new WidgetDatabaseRecord; + while ( !n3.isNull() ) { + if ( n3.tagName() == "class" ) { + cl = n3.firstChild().toText().data(); + r->name = cl; + } else if ( n3.tagName() == "header" ) { + CustomInclude ci; + ci.header = n3.firstChild().toText().data(); + ci.location = n3.attribute( "location", "global" ); + r->includeFile = ci.header; + customWidgetIncludes.insert( cl, ci ); + } + WidgetDatabase::append( r ); + n3 = n3.nextSibling().toElement(); + } + } + n2 = n2.nextSibling().toElement(); + } + } + } + + // additional includes (local or global) and forward declaractions + nl = e.parentNode().toElement().elementsByTagName( "include" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) { + if ( s.right( 5 ) == ".ui.h" && !QFile::exists( s ) ) + continue; + if ( n2.attribute( "impldecl", "in implementation" ) != "in implementation" ) + continue; + globalIncludes += s; + } + } + + registerDatabases( e ); + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + globalIncludes += "qsqldatabase.h"; + if ( dbCursors.count() ) + globalIncludes += "qsqlcursor.h"; + bool dbForm = FALSE; + if ( dbForms[ "(default)" ].count() ) + dbForm = TRUE; + bool subDbForms = FALSE; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)" ) { + if ( dbForms[ (*it) ].count() ) { + subDbForms = TRUE; + break; + } + } + } + if ( dbForm || subDbForms ) { + globalIncludes += "qsqlform.h"; + globalIncludes += "qsqlrecord.h"; + } + + // do the local includes afterwards, since global includes have priority on clashes + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) == "local" &&!globalIncludes.contains( s ) ) { + if ( s.right( 5 ) == ".ui.h" && !QFile::exists( s ) ) + continue; + if ( n2.attribute( "impldecl", "in implementation" ) != "in implementation" ) + continue; + localIncludes += s; + } + } + + // additional custom widget headers + nl = e.parentNode().toElement().elementsByTagName( "header" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QDomElement n2 = nl.item(i).toElement(); + QString s = n2.firstChild().toText().data(); + if ( n2.attribute( "location" ) != "local" ) + globalIncludes += s; + else + localIncludes += s; + } + + // includes for child widgets + for ( it = tags.begin(); it != tags.end(); ++it ) { + nl = e.parentNode().toElement().elementsByTagName( *it ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + QString name = getClassName( nl.item(i).toElement() ); + if ( name == "Spacer" ) { + globalIncludes += "qlayout.h"; + globalIncludes += "qapplication.h"; + continue; + } + if ( name.mid( 1 ) == "ListView" ) + globalIncludes += "qheader.h"; + if ( name != objClass ) { + int wid = WidgetDatabase::idFromClassName( name ); + QMap::Iterator it = customWidgetIncludes.find( name ); + if ( it == customWidgetIncludes.end() ) + globalIncludes += WidgetDatabase::includeFile( wid ); + } + } + } + + out << "#include " << endl; // first for gcc 2.7.2 + + globalIncludes = unique( globalIncludes ); + for ( it = globalIncludes.begin(); it != globalIncludes.end(); ++it ) { + if ( !(*it).isEmpty() ) + out << "#include <" << *it << ">" << endl; + } + + out << "#include " << endl; + out << "#include " << endl; + out << "#include " << endl; + if ( objClass == "QMainWindow" ) { + out << "#include " << endl; + out << "#include " << endl; + out << "#include " << endl; + out << "#include " << endl; + } + + // find out what images are required + QStringList requiredImages; + static const char *imgTags[] = { "pixmap", "iconset", 0 }; + for ( i = 0; imgTags[i] != 0; i++ ) { + nl = e.parentNode().toElement().elementsByTagName( imgTags[i] ); + for ( int j = 0; j < (int) nl.length(); j++ ) { + QDomNode nn = nl.item(j); + while ( nn.parentNode() != e.parentNode() ) + nn = nn.parentNode(); + if ( nn.nodeName() != "customwidgets" ) + requiredImages += nl.item(j).firstChild().toText().data(); + } + } + + if ( !requiredImages.isEmpty() || externPixmaps ) { + out << "#include " << endl; + out << "#include " << endl << endl; + } + + /* + Put local includes after all global includes + */ + localIncludes = unique( localIncludes ); + for ( it = localIncludes.begin(); it != localIncludes.end(); ++it ) { + if ( !(*it).isEmpty() && *it != QFileInfo( fileName + ".h" ).fileName() ) + out << "#include \"" << *it << "\"" << endl; + } + + QString uiDotH = fileName + ".h"; + if ( QFile::exists( uiDotH ) ) { + if ( !outputFileName.isEmpty() ) + uiDotH = combinePath( uiDotH, outputFileName ); + out << "#include \"" << uiDotH << "\"" << endl; + writeFunctImpl = FALSE; + } + + // register the object and unify its name + objName = registerObject( objName ); + + QStringList images; + QStringList xpmImages; + if ( pixmapLoaderFunction.isEmpty() && !externPixmaps ) { + // create images + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "images" ) { + nl = n.elementsByTagName( "image" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QString img = registerObject( nl.item(i).toElement().attribute("name") ); + if ( !requiredImages.contains( img ) ) + continue; + QDomElement tmp = nl.item(i).firstChild().toElement(); + if ( tmp.tagName() != "data" ) + continue; + QString format = tmp.attribute("format", "PNG" ); + QString data = tmp.firstChild().toText().data(); + if ( format == "XPM.GZ" ) { + xpmImages += img; + ulong length = tmp.attribute("length").toULong(); + QByteArray baunzip = unzipXPM( data, length ); + length = baunzip.size(); + // shouldn't we test the initial 'length' against the + // resulting 'length' to catch corrupt UIC files? + int a = 0; + int column = 0; + bool inQuote = FALSE; + out << "static const char* const " << img << "_data[] = { " << endl; + while ( baunzip[a] != '\"' ) + a++; + for ( ; a < (int) length; a++ ) { + out << baunzip[a]; + if ( baunzip[a] == '\n' ) { + column = 0; + } else if ( baunzip[a] == '"' ) { + inQuote = !inQuote; + } + + if ( column++ >= 511 && inQuote ) { + out << "\"\n\""; // be nice with MSVC & Co. + column = 1; + } + } + out << endl; + } else { + images += img; + out << "static const unsigned char " << img << "_data[] = { " << endl; + out << " "; + int a ; + for ( a = 0; a < (int) (data.length()/2)-1; a++ ) { + out << "0x" << QString(data[2*a]) << QString(data[2*a+1]) << ","; + if ( a % 12 == 11 ) + out << endl << " "; + else + out << " "; + } + out << "0x" << QString(data[2*a]) << QString(data[2*a+1]) << endl; + out << "};" << endl << endl; + } + } + } + } + out << endl; + } else if ( externPixmaps ) { + pixmapLoaderFunction = "QPixmap::fromMimeSource"; + } + + // constructor + if ( objClass == "QDialog" || objClass == "QWizard" ) { + out << "/*" << endl; + out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl; + out << " * name 'name' and widget flags set to 'f'." << endl; + out << " *" << endl; + out << " * The " << objClass.mid(1).lower() << " will by default be modeless, unless you set 'modal' to" << endl; + out << " * TRUE to construct a modal " << objClass.mid(1).lower() << "." << endl; + out << " */" << endl; + out << nameOfClass << "::" << bareNameOfClass << "( QWidget* parent, const char* name, bool modal, WFlags fl )" << endl; + out << " : " << objClass << "( parent, name, modal, fl )"; + } else if ( objClass == "QWidget" ) { + out << "/*" << endl; + out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl; + out << " * name 'name' and widget flags set to 'f'." << endl; + out << " */" << endl; + out << nameOfClass << "::" << bareNameOfClass << "( QWidget* parent, const char* name, WFlags fl )" << endl; + out << " : " << objClass << "( parent, name, fl )"; + } else if ( objClass == "QMainWindow" ) { + out << "/*" << endl; + out << " * Constructs a " << nameOfClass << " as a child of 'parent', with the" << endl; + out << " * name 'name' and widget flags set to 'f'." << endl; + out << " *" << endl; + out << " */" << endl; + out << nameOfClass << "::" << bareNameOfClass << "( QWidget* parent, const char* name, WFlags fl )" << endl; + out << " : " << objClass << "( parent, name, fl )"; + isMainWindow = TRUE; + } else { + out << "/*" << endl; + out << " * Constructs a " << nameOfClass << " which is a child of 'parent', with the" << endl; + out << " * name 'name'.' " << endl; + out << " */" << endl; + out << nameOfClass << "::" << bareNameOfClass << "( QWidget* parent, const char* name )" << endl; + out << " : " << objClass << "( parent, name )"; + } + + // create pixmaps for all images + if ( !xpmImages.isEmpty() ) { + for ( it = xpmImages.begin(); it != xpmImages.end(); ++it ) { + out << "," << endl; + out << indent << " " << *it << "( (const char **) " << (*it) << "_data )"; + } + } + out << endl; + + out << "{" << endl; + if ( isMainWindow ) + out << indent << "(void)statusBar();" << endl; + + if ( !images.isEmpty() ) { + out << indent << "QImage img;" << endl; + for ( it = images.begin(); it != images.end(); ++it ) { + out << indent << "img.loadFromData( " << (*it) << "_data, sizeof( " << (*it) << "_data ), \"PNG\" );" << endl; + out << indent << (*it) << " = img;" << endl; + } + } + + // set the properties + QSize geometry( 0, 0 ); + + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + QString prop = n.attribute("name"); + QDomElement n2 = n.firstChild().toElement(); + QString value = setObjectProperty( objClass, QString::null, prop, n2, stdset ); + if ( value.isEmpty() ) + continue; + + if ( prop == "geometry" && n2.tagName() == "rect" ) { + QDomElement n3 = n2.firstChild().toElement(); + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + geometry.setWidth( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "height" ) + geometry.setHeight( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + } else { + QString call; + if ( stdset ) { + call = mkStdSet( prop ) + "( "; + } else { + call = "setProperty( \"" + prop + "\", "; + } + call += value + " );"; + + if ( n2.tagName() == "string" ) { + trout << indent << call << endl; + } else if ( prop == "name" ) { + out << indent << "if ( !name )" << endl; + out << "\t" << call << endl; + } else { + out << indent << call << endl; + } + } + } + } + + // create all children, some forms have special requirements + + if ( objClass == "QWizard" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, "this" ); + QString comment; + QString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << "addPage( " << page << ", QString(\"\") );" << endl; + trout << indent << "setTitle( " << page << ", " << trcall( label, comment ) << " );" << endl; + QVariant def( FALSE, 0 ); + if ( DomTool::hasAttribute( n, "backEnabled" ) ) + out << indent << "setBackEnabled( " << page << ", " << mkBool( DomTool::readAttribute( n, "backEnabled", def).toBool() ) << endl; + if ( DomTool::hasAttribute( n, "nextEnabled" ) ) + out << indent << "setNextEnabled( " << page << ", " << mkBool( DomTool::readAttribute( n, "nextEnabled", def).toBool() ) << endl; + if ( DomTool::hasAttribute( n, "finishEnabled" ) ) + out << indent << "setFinishEnabled( " << page << ", " << mkBool( DomTool::readAttribute( n, "finishEnabled", def).toBool() ) << " );" << endl; + if ( DomTool::hasAttribute( n, "helpEnabled" ) ) + out << indent << "setHelpEnabled( " << page << ", " << mkBool( DomTool::readAttribute( n, "helpEnabled", def).toBool() ) << endl; + if ( DomTool::hasAttribute( n, "finish" ) ) + out << indent << "setFinish( " << page << ", " << mkBool( DomTool::readAttribute( n, "finish", def).toBool() ) << endl; + } + } + } else { // standard widgets + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objName, "this" ); + } + } + + // database support + dbConnections = unique( dbConnections ); + if ( dbConnections.count() ) + out << endl; + for ( it = dbConnections.begin(); it != dbConnections.end(); ++it ) { + if ( !(*it).isEmpty() && (*it) != "(default)") { + out << indent << (*it) << "Connection = QSqlDatabase::database( \"" <<(*it) << "\" );" << endl; + } + } + + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 1; i < (int) nl.length(); i++ ) { // start at 1, 0 is the toplevel widget + n = nl.item(i).toElement(); + QString s = getClassName( n ); + if ( (dbForm || subDbForms) && (s == "QDataBrowser" || s == "QDataView") ) { + QString objName = getObjectName( n ); + QString tab = getDatabaseInfo( n, "table" ); + QString con = getDatabaseInfo( n, "connection" ); + out << indent << "QSqlForm* " << objName << "Form = new QSqlForm( this, \"" << objName << "Form\" );" << endl; + QDomElement n2; + for ( n2 = n.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) + createFormImpl( n2, objName, con, tab ); + out << indent << objName << "->setForm( " << objName << "Form );" << endl; + } + } + + // actions, toolbars, menubar + bool needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "actions" ) { + if ( !needEndl ) + out << endl << indent << "// actions" << endl; + createActionImpl( n.firstChild().toElement(), "this" ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "toolbars" ) { + if ( !needEndl ) + out << endl << indent << "// toolbars" << endl; + createToolbarImpl( n, objClass, objName ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + needEndl = FALSE; + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "menubar" ) { + if ( !needEndl ) + out << endl << indent << "// menubar" << endl; + createMenuBarImpl( n, objClass, objName ); + needEndl = TRUE; + } + } + if ( needEndl ) + out << endl; + + out << indent << "languageChange();" << endl; + + // take minimumSizeHint() into account, for height-for-width widgets + if ( !geometry.isNull() ) { + out << indent << "resize( QSize(" << geometry.width() << ", " + << geometry.height() << ").expandedTo(minimumSizeHint()) );" << endl; + out << indent << "clearWState( WState_Polished );" << endl; + } + + for ( n = e; !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "connections" ) { + // setup signals and slots connections + out << endl << indent << "// signals and slots connections" << endl; + nl = n.elementsByTagName( "connection" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QString sender, receiver, signal, slot; + for ( QDomElement n2 = nl.item(i).firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "sender" ) + sender = n2.firstChild().toText().data(); + else if ( n2.tagName() == "receiver" ) + receiver = n2.firstChild().toText().data(); + else if ( n2.tagName() == "signal" ) + signal = n2.firstChild().toText().data(); + else if ( n2.tagName() == "slot" ) + slot = n2.firstChild().toText().data(); + } + if ( sender.isEmpty() || + receiver.isEmpty() || + signal.isEmpty() || + slot.isEmpty() ) + continue; + if ( sender[0] == '<' || + receiver[0] == '<' || + signal[0] == '<' || + slot[0] == '<' ) + continue; + + sender = registeredName( sender ); + receiver = registeredName( receiver ); + + // translate formwindow name to "this" + if ( sender == objName ) + sender = "this"; + if ( receiver == objName ) + receiver = "this"; + + out << indent << "connect( " << sender << ", SIGNAL( " << signal << " ), " + << receiver << ", SLOT( " << slot << " ) );" << endl; + } + } else if ( n.tagName() == "tabstops" ) { + // setup tab order + out << endl << indent << "// tab order" << endl; + QString lastName; + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "tabstop" ) { + QString name = n2.firstChild().toText().data(); + name = registeredName( name ); + if ( !lastName.isEmpty() ) + out << indent << "setTabOrder( " << lastName << ", " << name << " );" << endl; + lastName = name; + } + n2 = n2.nextSibling().toElement(); + } + } + } + + // buddies + bool firstBuddy = TRUE; + for ( QValueList::Iterator buddy = buddies.begin(); buddy != buddies.end(); ++buddy ) { + if ( isObjectRegistered( (*buddy).buddy ) ) { + if ( firstBuddy ) { + out << endl << indent << "// buddies" << endl; + } + out << indent << (*buddy).key << "->setBuddy( " << registeredName( (*buddy).buddy ) << " );" << endl; + firstBuddy = FALSE; + } + } + + if ( extraFuncts.find( "init()" ) != extraFuncts.end() ) + out << indent << "init();" << endl; + + // end of constructor + out << "}" << endl; + out << endl; + + // destructor + out << "/*" << endl; + out << " * Destroys the object and frees any allocated resources" << endl; + out << " */" << endl; + out << nameOfClass << "::~" << bareNameOfClass << "()" << endl; + out << "{" << endl; + if ( extraFuncts.find( "destroy()" ) != extraFuncts.end() ) + out << indent << "destroy();" << endl; + out << indent << "// no need to delete child widgets, Qt does it all for us" << endl; + out << "}" << endl; + out << endl; + + // handle application events if required + bool needFontEventHandler = FALSE; + bool needSqlTableEventHandler = FALSE; + bool needSqlDataBrowserEventHandler = FALSE; + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + if ( !DomTool::propertiesOfType( nl.item(i).toElement() , "font" ).isEmpty() ) + needFontEventHandler = TRUE; + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "QDataTable" || s == "QDataBrowser" ) { + if ( !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) + continue; + if ( s == "QDataTable" ) + needSqlTableEventHandler = TRUE; + if ( s == "QDataBrowser" ) + needSqlDataBrowserEventHandler = TRUE; + } + if ( needFontEventHandler && needSqlTableEventHandler && needSqlDataBrowserEventHandler ) + break; + } + if ( needFontEventHandler && FALSE ) { + // indent = "\t"; // increase indentation for if-clause below + out << "/*" << endl; + out << " * Main event handler. Reimplemented to handle" << endl; + out << " * application font changes"; + out << " */" << endl; + out << "bool " << nameOfClass << "::event( QEvent* ev )" << endl; + out << "{" << endl; + out << " bool ret = " << objClass << "::event( ev ); " << endl; + if ( needFontEventHandler ) { + indent += "\t"; + out << " if ( ev->type() == QEvent::ApplicationFontChange ) {" << endl; + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + QStringList list = DomTool::propertiesOfType( n, "font" ); + for ( it = list.begin(); it != list.end(); ++it ) + createExclusiveProperty( n, *it ); + } + out << " }" << endl; + indent = " "; + } + out << "}" << endl; + out << endl; + } + + if ( needSqlTableEventHandler || needSqlDataBrowserEventHandler ) { + out << "/*" << endl; + out << " * Widget polish. Reimplemented to handle" << endl; + if ( needSqlTableEventHandler ) + out << " * default data table initialization" << endl; + if ( needSqlDataBrowserEventHandler ) + out << " * default data browser initialization" << endl; + out << " */" << endl; + out << "void " << nameOfClass << "::polish()" << endl; + out << "{" << endl; + if ( needSqlTableEventHandler ) { + for ( i = 0; i < (int) nl.length(); i++ ) { + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "QDataTable" ) { + n = nl.item(i).toElement(); + QString c = getObjectName( n ); + QString conn = getDatabaseInfo( n, "connection" ); + QString tab = getDatabaseInfo( n, "table" ); + if ( !( conn.isEmpty() || tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { + out << indent << "if ( " << c << " ) {" << endl; + out << indent << indent << "QSqlCursor* cursor = " << c << "->sqlCursor();" << endl; + out << indent << indent << "if ( !cursor ) {" << endl; + if ( conn == "(default)" ) + out << indent << indent << indent << "cursor = new QSqlCursor( \"" << tab << "\" );" << endl; + else + out << indent << indent << indent << "cursor = new QSqlCursor( \"" << tab << "\", TRUE, " << conn << "Connection );" << endl; + out << indent << indent << indent << "if ( " << c << "->isReadOnly() ) " << endl; + out << indent << indent << indent << indent << "cursor->setMode( QSqlCursor::ReadOnly );" << endl; + out << indent << indent << indent << c << "->setSqlCursor( cursor, FALSE, TRUE );" << endl; + out << indent << indent << "}" << endl; + out << indent << indent << "if ( !cursor->isActive() )" << endl; + out << indent << indent << indent << c << "->refresh( QDataTable::RefreshAll );" << endl; + out << indent << "}" << endl; + } + } + } + } + if ( needSqlDataBrowserEventHandler ) { + nl = e.elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + QString s = getClassName( nl.item(i).toElement() ); + if ( s == "QDataBrowser" ) { + QString obj = getObjectName( nl.item(i).toElement() ); + QString tab = getDatabaseInfo( nl.item(i).toElement(), + "table" ); + QString conn = getDatabaseInfo( nl.item(i).toElement(), + "connection" ); + if ( !(tab.isEmpty() || !isFrameworkCodeGenerated( nl.item(i).toElement() ) ) ) { + out << indent << "if ( " << obj << " ) {" << endl; + out << indent << indent << "if ( !" << obj << "->sqlCursor() ) {" << endl; + if ( conn == "(default)" ) + out << indent << indent << indent << "QSqlCursor* cursor = new QSqlCursor( \"" << tab << "\" );" << endl; + else + out << indent << indent << indent << "QSqlCursor* cursor = new QSqlCursor( \"" << tab << "\", TRUE, " << conn << "Connection );" << endl; + out << indent << indent << indent << obj << "->setSqlCursor( cursor, TRUE );" << endl; + out << indent << indent << indent << obj << "->refresh();" << endl; + out << indent << indent << indent << obj << "->first();" << endl; + out << indent << indent << "}" << endl; + out << indent << "}" << endl; + } + } + } + } + out << indent << objClass << "::polish();" << endl; + out << "}" << endl; + out << endl; + } + + out << "/*" << endl; + out << " * Sets the strings of the subwidgets using the current" << endl; + out << " * language." << endl; + out << " */" << endl; + out << "void " << nameOfClass << "::languageChange()" << endl; + out << "{" << endl; + out << languageChangeBody; + out << "}" << endl; + out << endl; + + // create stubs for additional slots if necessary + if ( !extraFuncts.isEmpty() && writeFunctImpl ) { + it = extraFuncts.begin(); + QStringList::Iterator it2 = extraFunctTyp.begin(); + QStringList::Iterator it3 = extraFunctSpecifier.begin(); + while ( it != extraFuncts.end() ) { + QString type = *it2; + if ( type.isEmpty() ) + type = "void"; + type = type.simplifyWhiteSpace(); + QString fname = Parser::cleanArgs( *it ); + if ( !(*it3).startsWith("pure") ) { // "pure virtual" or "pureVirtual" + out << type << " " << nameOfClass << "::" << fname << endl; + out << "{" << endl; + if ( *it != "init()" && *it != "destroy()" ) { + QRegExp numeric( "^(?:signed|unsigned|u?char|u?short|u?int" + "|u?long|Q_U?INT(?:8|16|32)|Q_U?LONG|float" + "|double)$" ); + QString retVal; + + /* + We return some kind of dummy value to shut the + compiler up. + + 1. If the type is 'void', we return nothing. + + 2. If the type is 'bool', we return 'FALSE'. + + 3. If the type is 'unsigned long' or + 'Q_UINT16' or 'double' or similar, we + return '0'. + + 4. If the type is 'Foo *', we return '0'. + + 5. If the type is 'Foo &', we create a static + variable of type 'Foo' and return it. + + 6. If the type is 'Foo', we assume there's a + default constructor and use it. + */ + if ( type != "void" ) { + QStringList toks = QStringList::split( " ", type ); + bool isBasicNumericType = + ( toks.grep(numeric).count() == toks.count() ); + + if ( type == "bool" ) { + retVal = "FALSE"; + } else if ( isBasicNumericType || type.endsWith("*") ) { + retVal = "0"; + } else if ( type.endsWith("&") ) { + do { + type.truncate( type.length() - 1 ); + } while ( type.endsWith(" ") ); + retVal = "uic_temp_var"; + out << indent << "static " << type << " " << retVal << ";" << endl; + } else { + retVal = type + "()"; + } + } + + out << indent << "qWarning( \"" << nameOfClass << "::" << fname << ": Not implemented yet\" );" << endl; + if ( !retVal.isEmpty() ) + out << indent << "return " << retVal << ";" << endl; + } + out << "}" << endl; + out << endl; + } + ++it; + ++it2; + ++it3; + } + } +} + + +/*! Creates form support implementation code for the widgets given + in \a e. + + Traverses recursively over all children. + */ + +void Uic::createFormImpl( const QDomElement& e, const QString& form, const QString& connection, const QString& table ) +{ + if ( e.tagName() == "widget" && + e.attribute( "class" ) != "QDataTable" ) { + QString field = getDatabaseInfo( e, "field" ); + if ( !field.isEmpty() ) { + if ( isWidgetInTable( e, connection, table ) ) + out << indent << form << "Form->insert( " << getObjectName( e ) << ", " << fixString( field ) << " );" << endl; + } + } + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + createFormImpl( n, form, connection, table ); + } +} diff --git a/tools/designer/uic/main.cpp b/tools/designer/uic/main.cpp new file mode 100644 index 0000000..ace2033 --- /dev/null +++ b/tools/designer/uic/main.cpp @@ -0,0 +1,358 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "uic.h" +#include "domtool.h" +#if defined(UIB) +#include "ui2uib.h" +#endif +#include +#include +#include +#include +#include +#define NO_STATIC_COLORS +#include +#include +#include + +// see ### in widgetdatabase.cpp +extern bool dbnounload; +extern QStringList *dbpaths; + +int main( int argc, char * argv[] ) +{ + bool impl = FALSE; + bool subcl = FALSE; + bool imagecollection = FALSE; + bool imagecollection_tmpfile = FALSE; +#if defined(UIB) + bool binary = FALSE; +#endif + QStringList images; + const char *error = 0; + const char* fileName = 0; + const char* className = 0; + const char* headerFile = 0; + QCString outputFile; + QCString image_tmpfile; + const char* projectName = 0; + const char* trmacro = 0; + bool nofwd = FALSE; + bool fix = FALSE; + QCString pchFile; + QApplication app(argc, argv, FALSE); + + QString keybase( "/Qt Designer/" + + QString::number( (QT_VERSION >> 16) & 0xff ) +"." + QString::number( (QT_VERSION >> 8) & 0xff ) + "/" ); + QSettings config; + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + QStringList pluginPaths = config.readListEntry( keybase + "PluginPaths" ); + if (pluginPaths.count()) + QApplication::setLibraryPaths(pluginPaths); + + for ( int n = 1; n < argc && error == 0; n++ ) { + QCString arg = argv[n]; + if ( arg[0] == '-' ) { // option + QCString opt = &arg[1]; + if ( opt[0] == 'o' ) { // output redirection + if ( opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing output-file name"; + break; + } + outputFile = argv[++n]; + } else + outputFile = &opt[1]; + } else if ( opt[0] == 'i' || opt == "impl" ) { + impl = TRUE; + if ( opt == "impl" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing name of header file"; + break; + } + headerFile = argv[++n]; + } else + headerFile = &opt[1]; + } else if ( opt[0] == 'e' || opt == "embed" ) { + imagecollection = TRUE; + if ( opt == "embed" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing name of project"; + break; + } + projectName = argv[++n]; + } else { + projectName = &opt[1]; + } + if ( argc > n+1 && qstrcmp( argv[n+1], "-f" ) == 0 ) { + imagecollection_tmpfile = TRUE; + image_tmpfile = argv[n+2]; + n += 2; + } +#if defined(UIB) + + } else if ( opt == "binary" ) { + binary = TRUE; +#endif + } else if ( opt == "nofwd" ) { + nofwd = TRUE; + } else if ( opt == "nounload" ) { + dbnounload = TRUE; + } else if ( opt == "subdecl" ) { + subcl = TRUE; + if ( !(n < argc-2) ) { + error = "Missing arguments"; + break; + } + className = argv[++n]; + headerFile = argv[++n]; + } else if ( opt == "subimpl" ) { + subcl = TRUE; + impl = TRUE; + if ( !(n < argc-2) ) { + error = "Missing arguments"; + break; + } + className = argv[++n]; + headerFile = argv[++n]; + } else if ( opt == "tr" ) { + if ( opt == "tr" || opt[1] == '\0' ) { + if ( !(n < argc-1) ) { + error = "Missing tr macro."; + break; + } + trmacro = argv[++n]; + } else { + trmacro = &opt[1]; + } + } else if ( opt == "L" ) { + if ( !(n < argc-1) ) { + error = "Missing plugin path."; + break; + } + if ( !dbpaths ) + dbpaths = new QStringList(); + QString fn = QFile::decodeName( argv[++n] ); + dbpaths->append( fn ); + QApplication::addLibraryPath( fn ); + } else if ( opt == "version" ) { + fprintf( stderr, + "User Interface Compiler for Qt version %s\n", + QT_VERSION_STR ); + return 1; + } else if ( opt == "help" ) { + break; + } else if ( opt == "fix" ) { + fix = TRUE; + } else if ( opt == "pch") { + if ( !(n < argc-1) ) { + error = "Missing name of PCH file"; + break; + } + pchFile = argv[++n]; + } else { + error = "Unrecognized option"; + } + } else { + if ( imagecollection && !imagecollection_tmpfile ) + images << argv[n]; + else if ( fileName ) // can handle only one file + error = "Too many input files specified"; + else + fileName = argv[n]; + } + } + + if ( argc < 2 || error || (!fileName && !imagecollection ) ) { + fprintf( stderr, "Qt user interface compiler.\n" ); + if ( error ) + fprintf( stderr, "uic: %s\n", error ); + + fprintf( stderr, "Usage: %s [options] [mode] \n\n" + "Generate declaration:\n" + " %s [options] \n" + "Generate implementation:\n" + " %s [options] -impl \n" + "\t name of the declaration file\n" + "Generate image collection:\n" + " %s [options] -embed ...\n" + "or\n" + " %s [options] -embed -f \n" + "\t project name\n" + "\t image files\n" +#if defined(UIB) + "Generate binary UI file:\n" + " %s [options] -binary \n" +#endif + "Generate subclass declaration:\n" + " %s [options] -subdecl \n" + "\t name of the subclass to generate\n" + "\t declaration file of the baseclass\n" + "Generate subclass implementation:\n" + " %s [options] -subimpl \n" + "\t name of the subclass to generate\n" + "\t declaration file of the subclass\n" + "Options:\n" + "\t-o file Write output to file rather than stdout\n" + "\t-pch file Add #include \"file\" as the first statement in implementation\n" + "\t-nofwd Omit forward declarations of custom classes\n" + "\t-nounload Don't unload plugins after processing\n" + "\t-tr func Use func() instead of tr() for i18n\n" + "\t-L path Additional plugin search path\n" + "\t-version Display version of uic\n" + "\t-help Display this information\n" + , argv[0], argv[0], argv[0], argv[0], argv[0], argv[0], argv[0] +#if defined(UIB) + , argv[0] +#endif + ); + return 1; + } + + if ( imagecollection_tmpfile ) { + QFile ifile( image_tmpfile ); + if ( ifile.open( IO_ReadOnly ) ) { + QTextStream ts( &ifile ); + QString s = ts.read(); + s = s.simplifyWhiteSpace(); + images = QStringList::split( ' ', s ); + for ( QStringList::Iterator it = images.begin(); it != images.end(); ++it ) + *it = (*it).simplifyWhiteSpace(); + } + } + +#if defined(UIB) + if ( binary && outputFile.isEmpty() ) { + outputFile = fileName; + if ( outputFile.mid(outputFile.length() - 3).lower() == ".ui" ) + outputFile.truncate( outputFile.length() - 3 ); + outputFile += ".uib"; + } +#endif + + QFile fileOut; + if ( !outputFile.isEmpty() ) { + fileOut.setName( outputFile ); + if (!fileOut.open( IO_WriteOnly ) ) { + qWarning( "uic: Could not open output file '%s'", outputFile.data() ); + return 1; + } + } else { + fileOut.open( IO_WriteOnly, stdout ); + } + QTextStream out( &fileOut ); + + if ( imagecollection ) { + out.setEncoding( QTextStream::Latin1 ); + Uic::embed( out, projectName, images ); + return 0; + } + + out.setEncoding( QTextStream::UnicodeUTF8 ); + + QFile file( fileName ); + if ( !file.open( IO_ReadOnly ) ) { + qWarning( "uic: Could not open file '%s'", fileName ); + return 1; + } + + QDomDocument doc; + QString errMsg; + int errLine; + if ( !doc.setContent( &file, &errMsg, &errLine ) ) { + qWarning( QString("uic: Failed to parse %s: ") + errMsg + QString (" in line %d"), fileName, errLine ); + return 1; + } + + QDomElement e = doc.firstChild().toElement(); + if ( e.hasAttribute("version") && e.attribute("version").toDouble() > 3.3 ) { + qWarning( QString("uic: File generated with too recent version of Qt Designer (%s vs. %s)"), + e.attribute("version").latin1(), QT_VERSION_STR ); + return 1; + } + + DomTool::fixDocument( doc ); + + if ( fix ) { + out << doc.toString(); + return 0; +#if defined(UIB) + } else if ( binary ) { + out.unsetDevice(); + QDataStream binaryOut( &fileOut ); + convertUiToUib( doc, binaryOut ); + return 0; +#endif + } + + if ( !subcl ) { + out << "/****************************************************************************" << endl; + out << "** Form "<< (impl? "implementation" : "interface") << " generated from reading ui file '" << fileName << "'" << endl; + out << "**" << endl; + out << "** Created: " << QDateTime::currentDateTime().toString() << endl; + out << "**" << endl; + out << "** WARNING! All changes made in this file will be lost!" << endl; + out << "****************************************************************************/" << endl << endl; + } + + QString protector; + if ( subcl && className && !impl ) + protector = QString::fromLocal8Bit( className ).upper() + "_H"; + + if ( !protector.isEmpty() ) { + out << "#ifndef " << protector << endl; + out << "#define " << protector << endl; + } + + if ( !pchFile.isEmpty() && impl ) { + out << "#include \"" << pchFile << "\" // PCH include" << endl; + } + + if ( headerFile ) { + out << "#include \"" << headerFile << "\"" << endl << endl; + } + + Uic( fileName, outputFile, out, doc, !impl, subcl, trmacro, className, nofwd ); + + if ( !protector.isEmpty() ) { + out << endl; + out << "#endif // " << protector << endl; + } + if ( fileOut.status() != IO_Ok ) { + qWarning( "uic: Error writing to file" ); + if ( !outputFile.isEmpty() ) + remove( outputFile ); + } + return 0; +} diff --git a/tools/designer/uic/object.cpp b/tools/designer/uic/object.cpp new file mode 100644 index 0000000..00eaa55 --- /dev/null +++ b/tools/designer/uic/object.cpp @@ -0,0 +1,745 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "domtool.h" +#include +#include +#include +#define NO_STATIC_COLORS +#include +#include "../interfaces/widgetinterface.h" +#include "../shared/widgetdatabase.h" + +/*! + Creates a declaration for the object given in \a e. + + Children are not traversed recursively. + + \sa createObjectImpl() + */ +void Uic::createObjectDecl( const QDomElement& e ) +{ + if ( e.tagName() == "vbox" ) { + out << " QVBoxLayout* " << registerObject(getLayoutName(e) ) << ";" << endl; + } else if ( e.tagName() == "hbox" ) { + out << " QHBoxLayout* " << registerObject(getLayoutName(e) ) << ";" << endl; + } else if ( e.tagName() == "grid" ) { + out << " QGridLayout* " << registerObject(getLayoutName(e) ) << ";" << endl; + } else { + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + // ignore QLayoutWidgets + if ( objClass == "QLayoutWidget" ) + return; + // register the object and unify its name + objName = registerObject( objName ); + if ( objClass == "Line" ) + objClass = "QFrame"; + else if (objClass == "Spacer") + objClass = "QSpacerItem"; + out << " " << objClass << "* " << objName << ";" << endl; + } +} + + +/*! + Creates an implementation for the object given in \a e. + + Traverses recursively over all children. + + Returns the name of the generated child object. + + \sa createObjectDecl() + */ + +static bool createdCentralWidget = FALSE; + +QString Uic::createObjectImpl( const QDomElement &e, const QString& parentClass, const QString& par, const QString& layout ) +{ + QString parent( par ); + if ( parent == "this" && isMainWindow ) { + if ( !createdCentralWidget ) + out << indent << "setCentralWidget( new QWidget( this, \"qt_central_widget\" ) );" << endl; + createdCentralWidget = TRUE; + parent = "centralWidget()"; + } + QDomElement n; + QString objClass, objName; + int numItems = 0; + int numColumns = 0; + int numRows = 0; + + if ( layouts.contains( e.tagName() ) ) + return createLayoutImpl( e, parentClass, parent, layout ); + + objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return objName; + objName = getObjectName( e ); + + QString definedName = objName; + bool isTmpObject = objName.isEmpty() || objClass == "QLayoutWidget"; + if ( isTmpObject ) { + if ( objClass[0] == 'Q' ) + objName = objClass.mid(1); + else + objName = objClass.lower(); + objName.prepend( "private" ); + } + + bool isLine = objClass == "Line"; + if ( isLine ) + objClass = "QFrame"; + + out << endl; + if ( objClass == "QLayoutWidget" ) { + if ( layout.isEmpty() ) { + // register the object and unify its name + objName = registerObject( objName ); + out << " QWidget* " << objName << " = new QWidget( " << parent << ", \"" << definedName << "\" );" << endl; + } else { + // the layout widget is not necessary, hide it by creating its child in the parent + QString result; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if (tags.contains( n.tagName() ) ) + result = createObjectImpl( n, parentClass, parent, layout ); + } + return result; + } + } else if ( objClass != "QToolBar" && objClass != "QMenuBar" ) { + // register the object and unify its name + objName = registerObject( objName ); + out << " "; + if ( isTmpObject ) + out << objClass << "* "; + out << objName << " = new " << createObjectInstance( objClass, parent, objName ) << ";" << endl; + } + + if ( objClass == "QAxWidget" ) { + QString controlId; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.attribute( "name" ) == "control" ) { + controlId = n.firstChild().toElement().text(); + } + } + out << " "; + out << objName << "->setControl(\"" << controlId << "\");" << endl; + } + + lastItem = "0"; + // set the properties and insert items + bool hadFrameShadow = FALSE; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + QString prop = n.attribute( "name" ); + if ( prop == "database" ) + continue; + QString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + if ( prop == "name" ) + continue; + if ( isLine && prop == "frameShadow" ) + hadFrameShadow = TRUE; + if ( prop == "buddy" && value.startsWith("\"") && value.endsWith("\"") ) { + buddies << Buddy( objName, value.mid(1, value.length() - 2 ) ); + continue; + } + if ( isLine && prop == "orientation" ) { + prop = "frameShape"; + if ( value.right(10) == "Horizontal" ) + value = "QFrame::HLine"; + else + value = "QFrame::VLine"; + if ( !hadFrameShadow ) { + prop = "frameStyle"; + value += " | QFrame::Sunken"; + } + } + if ( prop == "buttonGroupId" ) { + if ( parentClass == "QButtonGroup" ) + out << indent << parent << "->insert( " << objName << ", " << value << " );" << endl; + continue; + } + if ( prop == "frameworkCode" ) + continue; + if ( objClass == "QMultiLineEdit" && + QRegExp("echoMode|hMargin|maxLength|maxLines|undoEnabled").exactMatch(prop) ) + continue; + + QString call = objName + "->"; + if ( stdset ) { + call += mkStdSet( prop ) + "( "; + } else { + call += "setProperty( \"" + prop + "\", "; + } + if ( prop == "accel" ) + call += "QKeySequence( " + value + " ) );"; + else + call += value + " );"; + + if ( n.firstChild().toElement().tagName() == "string" || + prop == "currentItem" ) { + trout << indent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( n.tagName() == "item" ) { + QString call; + QString value; + + if ( objClass.contains( "ListBox" ) ) { + call = createListBoxItemImpl( n, objName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.contains( "ComboBox" ) ) { + call = createListBoxItemImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.contains( "IconView" ) ) { + call = createIconViewItemImpl( n, objName ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << indent << call << endl; + } + } else if ( objClass.contains( "ListView" ) ) { + call = createListViewItemImpl( n, objName, QString::null ); + if ( !call.isEmpty() ) { + if ( numItems == 0 ) + trout << indent << objName << "->clear();" << endl; + trout << call << endl; + } + } + if ( !call.isEmpty() ) + numItems++; + } else if ( n.tagName() == "column" || n.tagName() == "row" ) { + QString call; + QString value; + + if ( objClass.contains( "ListView" ) ) { + call = createListViewColumnImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << indent << objName << "->header()->setLabel( " + << numColumns++ << ", " << value << " );\n"; + } + } else if ( objClass == "QTable" || objClass == "QDataTable" ) { + bool isCols = ( n.tagName() == "column" ); + call = createTableRowColumnImpl( n, objName, &value ); + if ( !call.isEmpty() ) { + out << call; + trout << indent << objName << "->" + << ( isCols ? "horizontalHeader" : "verticalHeader" ) + << "()->setLabel( " + << ( isCols ? numColumns++ : numRows++ ) + << ", " << value << " );\n"; + } + } + } + } + + // create all children, some widgets have special requirements + + if ( objClass == "QTabWidget" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, objName ); + QString comment; + QString label = DomTool::readAttribute( n, "title", "", comment ).toString(); + out << indent << objName << "->insertTab( " << page << ", QString::fromLatin1(\"\") );" << endl; + trout << indent << objName << "->changeTab( " << page << ", " + << trcall( label, comment ) << " );" << endl; + } + } + } else if ( objClass == "QWidgetStack" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, objName ); + int id = DomTool::readAttribute( n, "id", "" ).toInt(); + out << indent << objName << "->addWidget( " << page << ", " << id << " );" << endl; + } + } + } else if ( objClass == "QToolBox" ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + QString page = createObjectImpl( n, objClass, objName ); + QString comment; + QString label = DomTool::readAttribute( n, "label", "", comment ).toString(); + out << indent << objName << "->addItem( " << page << ", QString::fromLatin1(\"\") );" << endl; + trout << indent << objName << "->setItemLabel( " << objName + << "->indexOf(" << page << "), " << trcall( label, comment ) + << " );" << endl; + } + } + } else if ( objClass != "QToolBar" && objClass != "QMenuBar" ) { // standard widgets + WidgetInterface *iface = 0; + widgetManager()->queryInterface( objClass, &iface ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + int id = WidgetDatabase::idFromClassName( objClass ); + if ( WidgetDatabase::isContainer( id ) && WidgetDatabase::isCustomPluginWidget( id ) && iface ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + bool supportsPages = iface2->supportsPages( objClass ); + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) { + if ( supportsPages ) { + QString page = createObjectImpl( n, objClass, objName ); + QString comment; + QString label = DomTool::readAttribute( n, "label", "", comment ).toString(); + out << indent << iface2->createCode( objClass, objName, page, label ) << endl; + } else { + createObjectImpl( n, objClass, objName ); + } + } + } + iface2->release(); + } + iface->release(); + } else { +#endif + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( tags.contains( n.tagName() ) ) + createObjectImpl( n, objClass, objName ); + } +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } +#endif + } + + return objName; +} + +/*! + Creates declarations for spacer items that are children of \a e. + + \sa createObjectDecl() +*/ + +void Uic::createSpacerDecl( const QDomElement &e ) +{ + for ( QDomElement n = e.firstChild().toElement(); + !n.isNull(); n = n.nextSibling().toElement() ) + if ( n.tagName() == "spacer" ) + out << " QSpacerItem* " << registerObject(getObjectName(n)) << ";" << endl; +} + +/*! + Creates a set-call for property \a exclusiveProp of the object + given in \a e. + + If the object does not have this property, the function does nothing. + + Exclusive properties are used to generate the implementation of + application font or palette change handlers in createFormImpl(). + + */ +void Uic::createExclusiveProperty( const QDomElement & e, const QString& exclusiveProp ) +{ + QDomElement n; + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + QString objName = getObjectName( e ); +#if 0 // it's not clear whether this check should be here or not + if ( objName.isEmpty() ) + return; +#endif + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n.hasAttribute( "stdset" ) ) + stdset = toBool( n.attribute( "stdset" ) ); + QString prop = n.attribute( "name" ); + if ( prop != exclusiveProp ) + continue; + QString value = setObjectProperty( objClass, objName, prop, n.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + // we assume the property isn't of type 'string' + out << '\t' << objName << "->setProperty( \"" << prop << "\", " << value << " );" << endl; + } + } +} + + +/*! Attention: this function has to be in sync with + Resource::saveProperty() and DomTool::elementToVariant. If you + change one, change all. + */ +QString Uic::setObjectProperty( const QString& objClass, const QString& obj, const QString &prop, const QDomElement &e, bool stdset ) +{ + QString v; + if ( e.tagName() == "rect" ) { + QDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0, w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "QRect( %1, %2, %3, %4 )"; + v = v.arg(x).arg(y).arg(w).arg(h); + + } else if ( e.tagName() == "point" ) { + QDomElement n3 = e.firstChild().toElement(); + int x = 0, y = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "x" ) + x = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "y" ) + y = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "QPoint( %1, %2 )"; + v = v.arg(x).arg(y); + } else if ( e.tagName() == "size" ) { + QDomElement n3 = e.firstChild().toElement(); + int w = 0, h = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "width" ) + w = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "height" ) + h = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "QSize( %1, %2 )"; + v = v.arg(w).arg(h); + } else if ( e.tagName() == "color" ) { + QDomElement n3 = e.firstChild().toElement(); + int r = 0, g = 0, b = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "red" ) + r = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "green" ) + g = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "blue" ) + b = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "QColor( %1, %2, %3 )"; + v = v.arg(r).arg(g).arg(b); + } else if ( e.tagName() == "font" ) { + QDomElement n3 = e.firstChild().toElement(); + QString attrname = e.parentNode().toElement().attribute( "name", "font" ); + QString fontname; + if ( !obj.isEmpty() ) { + fontname = registerObject( obj + "_" + attrname ); + out << indent << "QFont " << fontname << "( " << obj << "->font() );" << endl; + } else { + fontname = registerObject( "f" ); + out << indent << "QFont " << fontname << "( font() );" << endl; + } + while ( !n3.isNull() ) { + if ( n3.tagName() == "family" ) + out << indent << fontname << ".setFamily( \"" << n3.firstChild().toText().data() << "\" );" << endl; + else if ( n3.tagName() == "pointsize" ) + out << indent << fontname << ".setPointSize( " << n3.firstChild().toText().data() << " );" << endl; + else if ( n3.tagName() == "bold" ) + out << indent << fontname << ".setBold( " << mkBool( n3.firstChild().toText().data() ) << " );" << endl; + else if ( n3.tagName() == "italic" ) + out << indent << fontname << ".setItalic( " << mkBool( n3.firstChild().toText().data() ) << " );" << endl; + else if ( n3.tagName() == "underline" ) + out << indent << fontname << ".setUnderline( " << mkBool( n3.firstChild().toText().data() ) << " );" << endl; + else if ( n3.tagName() == "strikeout" ) + out << indent << fontname << ".setStrikeOut( " << mkBool( n3.firstChild().toText().data() ) << " );" << endl; + n3 = n3.nextSibling().toElement(); + } + + if ( prop == "font" ) { + if ( !obj.isEmpty() ) + out << indent << obj << "->setFont( " << fontname << " ); " << endl; + else + out << indent << "setFont( " << fontname << " ); " << endl; + } else { + v = fontname; + } + } else if ( e.tagName() == "string" ) { + QString txt = e.firstChild().toText().data(); + QString com = getComment( e.parentNode() ); + + if ( prop == "toolTip" && objClass != "QAction" && objClass != "QActionGroup" ) { + if ( !obj.isEmpty() ) + trout << indent << "QToolTip::add( " << obj << ", " + << trcall( txt, com ) << " );" << endl; + else + trout << indent << "QToolTip::add( this, " + << trcall( txt, com ) << " );" << endl; + } else if ( prop == "whatsThis" && objClass != "QAction" && objClass != "QActionGroup" ) { + if ( !obj.isEmpty() ) + trout << indent << "QWhatsThis::add( " << obj << ", " + << trcall( txt, com ) << " );" << endl; + else + trout << indent << "QWhatsThis::add( this, " + << trcall( txt, com ) << " );" << endl; + } else { + v = trcall( txt, com ); + } + } else if ( e.tagName() == "cstring" ) { + v = "\"%1\""; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "number" ) { + v = "%1"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "bool" ) { + if ( stdset ) + v = "%1"; + else + v = "QVariant( %1, 0 )"; + v = v.arg( mkBool( e.firstChild().toText().data() ) ); + } else if ( e.tagName() == "pixmap" ) { + v = e.firstChild().toText().data(); + if ( !pixmapLoaderFunction.isEmpty() ) { + v.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) ); + v.append( QString( externPixmaps ? "\"" : "" ) + " )" ); + } + } else if ( e.tagName() == "iconset" ) { + v = "QIconSet( %1 )"; + QString s = e.firstChild().toText().data(); + if ( !pixmapLoaderFunction.isEmpty() ) { + s.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) ); + s.append( QString( externPixmaps ? "\"" : "" ) + " )" ); + } + v = v.arg( s ); + } else if ( e.tagName() == "image" ) { + v = e.firstChild().toText().data() + ".convertToImage()"; + } else if ( e.tagName() == "enum" ) { + if ( stdset ) + v = "%1::%2"; + else + v = "\"%1\""; + QString oc = objClass; + QString ev = e.firstChild().toText().data(); + if ( oc == "QListView" && ev == "Manual" ) // #### workaround, rename QListView::Manual in 4.0 + oc = "QScrollView"; + if ( stdset ) + v = v.arg( oc ).arg( ev ); + else + v = v.arg( ev ); + } else if ( e.tagName() == "set" ) { + QString keys( e.firstChild().toText().data() ); + QStringList lst = QStringList::split( '|', keys ); + v = "int( "; + QStringList::Iterator it = lst.begin(); + while ( it != lst.end() ) { + v += objClass + "::" + *it; + if ( it != lst.fromLast() ) + v += " | "; + ++it; + } + v += " )"; + } else if ( e.tagName() == "sizepolicy" ) { + QDomElement n3 = e.firstChild().toElement(); + QSizePolicy sp; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hsizetype" ) + sp.setHorData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "vsizetype" ) + sp.setVerData( (QSizePolicy::SizeType)n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "horstretch" ) + sp.setHorStretch( n3.firstChild().toText().data().toInt() ); + else if ( n3.tagName() == "verstretch" ) + sp.setVerStretch( n3.firstChild().toText().data().toInt() ); + n3 = n3.nextSibling().toElement(); + } + QString tmp; + if ( !obj.isEmpty() ) + tmp = obj + "->"; + v = "QSizePolicy( (QSizePolicy::SizeType)%1, (QSizePolicy::SizeType)%2, %3, %4, " + tmp + "sizePolicy().hasHeightForWidth() )"; + v = v.arg( (int)sp.horData() ).arg( (int)sp.verData() ).arg( sp.horStretch() ).arg( sp.verStretch() ); + } else if ( e.tagName() == "palette" ) { + QPalette pal; + bool no_pixmaps = e.elementsByTagName( "pixmap" ).count() == 0; + QDomElement n; + if ( no_pixmaps ) { + n = e.firstChild().toElement(); + while ( !n.isNull() ) { + QColorGroup cg; + if ( n.tagName() == "active" ) { + cg = loadColorGroup( n ); + pal.setActive( cg ); + } else if ( n.tagName() == "inactive" ) { + cg = loadColorGroup( n ); + pal.setInactive( cg ); + } else if ( n.tagName() == "disabled" ) { + cg = loadColorGroup( n ); + pal.setDisabled( cg ); + } + n = n.nextSibling().toElement(); + } + } + if ( no_pixmaps && pal == QPalette( pal.active().button(), pal.active().background() ) ) { + v = "QPalette( QColor( %1, %2, %3 ), QColor( %1, %2, %3 ) )"; + v = v.arg( pal.active().button().red() ).arg( pal.active().button().green() ).arg( pal.active().button().blue() ); + v = v.arg( pal.active().background().red() ).arg( pal.active().background().green() ).arg( pal.active().background().blue() ); + } else { + QString palette = "pal"; + if ( !pal_used ) { + out << indent << "QPalette " << palette << ";" << endl; + pal_used = TRUE; + } + QString cg = "cg"; + if ( !cg_used ) { + out << indent << "QColorGroup " << cg << ";" << endl; + cg_used = TRUE; + } + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "active" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setActive( " << cg << " );" << endl; + + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "inactive" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setInactive( " << cg << " );" << endl; + + n = e.firstChild().toElement(); + while ( !n.isNull() && n.tagName() != "disabled" ) + n = n.nextSibling().toElement(); + createColorGroupImpl( cg, n ); + out << indent << palette << ".setDisabled( " << cg << " );" << endl; + v = palette; + } + } else if ( e.tagName() == "cursor" ) { + v = "QCursor( %1 )"; + v = v.arg( e.firstChild().toText().data() ); + } else if ( e.tagName() == "date" ) { + QDomElement n3 = e.firstChild().toElement(); + int y, m, d; + y = m = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "QDate( %1, %2, %3 )"; + v = v.arg(y).arg(m).arg(d); + } else if ( e.tagName() == "time" ) { + QDomElement n3 = e.firstChild().toElement(); + int h, m, s; + h = m = s = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + m = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "QTime( %1, %2, %3 )"; + v = v.arg(h).arg(m).arg(s); + } else if ( e.tagName() == "datetime" ) { + QDomElement n3 = e.firstChild().toElement(); + int h, mi, s, y, mo, d; + h = mi = s = y = mo = d = 0; + while ( !n3.isNull() ) { + if ( n3.tagName() == "hour" ) + h = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "minute" ) + mi = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "second" ) + s = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "year" ) + y = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "month" ) + mo = n3.firstChild().toText().data().toInt(); + else if ( n3.tagName() == "day" ) + d = n3.firstChild().toText().data().toInt(); + n3 = n3.nextSibling().toElement(); + } + v = "QDateTime( QDate( %1, %2, %3 ), QTime( %4, %5, %6 ) )"; + v = v.arg(y).arg(mo).arg(d).arg(h).arg(mi).arg(s); + } else if ( e.tagName() == "stringlist" ) { + QStringList l; + QDomElement n3 = e.firstChild().toElement(); + QString listname = "l"; + if ( !obj.isEmpty() ) { + listname = obj + "_stringlist"; + listname = registerObject( listname ); + out << indent << "QStringList " << listname << ";" << endl; + } else { + listname = registerObject( listname ); + out << indent << "QStringList " << listname << ";" << endl; + } + while ( !n3.isNull() ) { + if ( n3.tagName() == "string" ) + out << indent << listname << " << \"" << n3.firstChild().toText().data().simplifyWhiteSpace() << "\";" << endl; + n3 = n3.nextSibling().toElement(); + } + v = listname; + } + return v; +} + +/*! Extracts a named object property from \a e. + */ +QDomElement Uic::getObjectProperty( const QDomElement& e, const QString& name ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); + !n.isNull(); + n = n.nextSibling().toElement() ) { + if ( n.tagName() == "property" && n.toElement().attribute("name") == name ) + return n; + } + return n; +} diff --git a/tools/designer/uic/subclassing.cpp b/tools/designer/uic/subclassing.cpp new file mode 100644 index 0000000..a7be6df --- /dev/null +++ b/tools/designer/uic/subclassing.cpp @@ -0,0 +1,352 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include +#include +#include +#define NO_STATIC_COLORS +#include +#include +#include +#include + +/*! + Creates a declaration ( headerfile ) for a subclass \a subClass + of the form given in \a e + + \sa createSubImpl() + */ +void Uic::createSubDecl( const QDomElement &e, const QString& subClass ) +{ + QDomElement n; + QDomNodeList nl; + int i; + + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + + out << "class " << subClass << " : public " << nameOfClass << endl; + out << "{" << endl; + +/* tmake ignore Q_OBJECT */ + out << " Q_OBJECT" << endl; + out << endl; + out << "public:" << endl; + + // constructor + if ( objClass == "QDialog" || objClass == "QWizard" ) { + out << " " << subClass << "( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );" << endl; + } else { // standard QWidget + out << " " << subClass << "( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );" << endl; + } + + // destructor + out << " ~" << subClass << "();" << endl; + out << endl; + + // find additional functions + QStringList publicSlots, protectedSlots, privateSlots; + QStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + QStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + QStringList publicFuncts, protectedFuncts, privateFuncts; + QStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp; + QStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec; + + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedSlots += functionName; + protectedSlotTypes += returnType; + protectedSlotSpecifier += specifier; + } else if ( access == "private" ) { + privateSlots += functionName; + privateSlotTypes += returnType; + privateSlotSpecifier += specifier; + } else { + publicSlots += functionName; + publicSlotTypes += returnType; + publicSlotSpecifier += specifier; + } + } + + nl = e.parentNode().toElement().elementsByTagName( "function" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "functions" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedFuncts += functionName; + protectedFunctRetTyp += returnType; + protectedFunctSpec += specifier; + } else if ( access == "private" ) { + privateFuncts += functionName; + privateFunctRetTyp += returnType; + privateFunctSpec += specifier; + } else { + publicFuncts += functionName; + publicFunctRetTyp += returnType; + publicFunctSpec += specifier; + } + } + + if ( !publicFuncts.isEmpty() ) + writeFunctionsSubDecl( publicFuncts, publicFunctRetTyp, publicFunctSpec ); + + // create public additional slots + if ( !publicSlots.isEmpty() ) { + out << "public slots:" << endl; + writeFunctionsSubDecl( publicSlots, publicSlotTypes, publicSlotSpecifier ); + } + + if ( !protectedFuncts.isEmpty() ) { + out << "protected:" << endl; + writeFunctionsSubDecl( protectedFuncts, protectedFunctRetTyp, protectedFunctSpec ); + } + + // create protected additional slots + if ( !protectedSlots.isEmpty() ) { + out << "protected slots:" << endl; + writeFunctionsSubDecl( protectedSlots, protectedSlotTypes, protectedSlotSpecifier ); + } + + if ( !privateFuncts.isEmpty() ) { + out << "private:" << endl; + writeFunctionsSubDecl( privateFuncts, privateFunctRetTyp, privateFunctSpec ); + } + + // create private additional slots + if ( !privateSlots.isEmpty() ) { + out << "private slots:" << endl; + writeFunctionsSubDecl( privateSlots, privateSlotTypes, privateSlotSpecifier ); + } + out << "};" << endl; +} + +void Uic::writeFunctionsSubDecl( const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst ) +{ + QValueListConstIterator it, it2, it3; + for ( it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin(); + it != fuLst.end(); ++it, ++it2, ++it3 ) { + QString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + out << " " << type << " " << (*it) << ";" << endl; + } + out << endl; +} + +/*! + Creates an implementation for a subclass \a subClass of the form + given in \a e + + \sa createSubDecl() + */ +void Uic::createSubImpl( const QDomElement &e, const QString& subClass ) +{ + QDomElement n; + QDomNodeList nl; + int i; + + QString objClass = getClassName( e ); + if ( objClass.isEmpty() ) + return; + + // constructor + if ( objClass == "QDialog" || objClass == "QWizard" ) { + out << "/* " << endl; + out << " * Constructs a " << subClass << " which is a child of 'parent', with the " << endl; + out << " * name 'name' and widget flags set to 'f' " << endl; + out << " *" << endl; + out << " * The " << objClass.mid(1).lower() << " will by default be modeless, unless you set 'modal' to" << endl; + out << " * TRUE to construct a modal " << objClass.mid(1).lower() << "." << endl; + out << " */" << endl; + out << subClass << "::" << subClass << "( QWidget* parent, const char* name, bool modal, WFlags fl )" << endl; + out << " : " << nameOfClass << "( parent, name, modal, fl )" << endl; + } else { // standard QWidget + out << "/* " << endl; + out << " * Constructs a " << subClass << " which is a child of 'parent', with the " << endl; + out << " * name 'name' and widget flags set to 'f' " << endl; + out << " */" << endl; + out << subClass << "::" << subClass << "( QWidget* parent, const char* name, WFlags fl )" << endl; + out << " : " << nameOfClass << "( parent, name, fl )" << endl; + } + out << "{" << endl; + out << "}" << endl; + out << endl; + + // destructor + out << "/* " << endl; + out << " * Destroys the object and frees any allocated resources" << endl; + out << " */" << endl; + out << subClass << "::~" << subClass << "()" << endl; + out << "{" << endl; + out << " // no need to delete child widgets, Qt does it all for us" << endl; + out << "}" << endl; + out << endl; + + + // find additional functions + QStringList publicSlots, protectedSlots, privateSlots; + QStringList publicSlotTypes, protectedSlotTypes, privateSlotTypes; + QStringList publicSlotSpecifier, protectedSlotSpecifier, privateSlotSpecifier; + QStringList publicFuncts, protectedFuncts, privateFuncts; + QStringList publicFunctRetTyp, protectedFunctRetTyp, privateFunctRetTyp; + QStringList publicFunctSpec, protectedFunctSpec, privateFunctSpec; + + nl = e.parentNode().toElement().elementsByTagName( "slot" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "slots" + && n.parentNode().toElement().tagName() != "connections" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedSlots += functionName; + protectedSlotTypes += returnType; + protectedSlotSpecifier += specifier; + } else if ( access == "private" ) { + privateSlots += functionName; + privateSlotTypes += returnType; + privateSlotSpecifier += specifier; + } else { + publicSlots += functionName; + publicSlotTypes += returnType; + publicSlotSpecifier += specifier; + } + } + + nl = e.parentNode().toElement().elementsByTagName( "function" ); + for ( i = 0; i < (int) nl.length(); i++ ) { + n = nl.item(i).toElement(); + if ( n.parentNode().toElement().tagName() != "functions" ) + continue; + if ( n.attribute( "language", "C++" ) != "C++" ) + continue; + QString returnType = n.attribute( "returnType", "void" ); + QString functionName = n.firstChild().toText().data().stripWhiteSpace(); + if ( functionName.endsWith( ";" ) ) + functionName = functionName.left( functionName.length() - 1 ); + QString specifier = n.attribute( "specifier" ); + QString access = n.attribute( "access" ); + if ( access == "protected" ) { + protectedFuncts += functionName; + protectedFunctRetTyp += returnType; + protectedFunctSpec += specifier; + } else if ( access == "private" ) { + privateFuncts += functionName; + privateFunctRetTyp += returnType; + privateFunctSpec += specifier; + } else { + publicFuncts += functionName; + publicFunctRetTyp += returnType; + publicFunctSpec += specifier; + } + } + + if ( !publicFuncts.isEmpty() ) + writeFunctionsSubImpl( publicFuncts, publicFunctRetTyp, publicFunctSpec, subClass, "public function" ); + + // create stubs for public additional slots + if ( !publicSlots.isEmpty() ) + writeFunctionsSubImpl( publicSlots, publicSlotTypes, publicSlotSpecifier, subClass, "public slot" ); + + if ( !protectedFuncts.isEmpty() ) + writeFunctionsSubImpl( protectedFuncts, protectedFunctRetTyp, protectedFunctSpec, subClass, "protected function" ); + + // create stubs for protected additional slots + if ( !protectedSlots.isEmpty() ) + writeFunctionsSubImpl( protectedSlots, protectedSlotTypes, protectedSlotSpecifier, subClass, "protected slot" ); + + if ( !privateFuncts.isEmpty() ) + writeFunctionsSubImpl( privateFuncts, privateFunctRetTyp, privateFunctSpec, subClass, "private function" ); + + // create stubs for private additional slots + if ( !privateSlots.isEmpty() ) + writeFunctionsSubImpl( privateSlots, privateSlotTypes, privateSlotSpecifier, subClass, "private slot" ); +} + +void Uic::writeFunctionsSubImpl( const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst, + const QString &subClass, const QString &descr ) +{ + QValueListConstIterator it, it2, it3; + for ( it = fuLst.begin(), it2 = typLst.begin(), it3 = specLst.begin(); + it != fuLst.end(); ++it, ++it2, ++it3 ) { + QString type = *it2; + if ( type.isEmpty() ) + type = "void"; + if ( *it3 == "non virtual" ) + continue; + out << "/*" << endl; + out << " * " << descr << endl; + out << " */" << endl; + out << type << " " << subClass << "::" << (*it) << endl; + out << "{" << endl; + out << " qWarning( \"" << subClass << "::" << (*it) << " not yet implemented!\" );" << endl; + out << "}" << endl << endl; + } + out << endl; +} diff --git a/tools/designer/uic/uic.cpp b/tools/designer/uic/uic.cpp new file mode 100644 index 0000000..b0a61d6 --- /dev/null +++ b/tools/designer/uic/uic.cpp @@ -0,0 +1,1129 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "uic.h" +#include "parser.h" +#include "widgetdatabase.h" +#include "domtool.h" +#include +#include +#include +#define NO_STATIC_COLORS +#include +#include +#include +#include + +bool Uic::isMainWindow = FALSE; + +QString Uic::getComment( const QDomNode& n ) +{ + QDomNode child = n.firstChild(); + while ( !child.isNull() ) { + if ( child.toElement().tagName() == "comment" ) + return child.toElement().firstChild().toText().data(); + child = child.nextSibling(); + } + return QString::null; +} + +QString Uic::mkBool( bool b ) +{ + return b? "TRUE" : "FALSE"; +} + +QString Uic::mkBool( const QString& s ) +{ + return mkBool( s == "true" || s == "1" ); +} + +bool Uic::toBool( const QString& s ) +{ + return s == "true" || s.toInt() != 0; +} + +QString Uic::fixString( const QString &str, bool encode ) +{ + QString s; + if ( !encode ) { + s = str; + s.replace( "\\", "\\\\" ); + s.replace( "\"", "\\\"" ); + s.replace( "\r", "" ); + s.replace( "\n", "\\n\"\n\"" ); + } else { + QCString utf8 = str.utf8(); + const int l = utf8.length(); + + for ( int i = 0; i < l; ++i ) { + uchar c = (uchar)utf8[i]; + if (c != 0x0d) // skip \r + s += "\\x" + QString::number(c, 16); + + if (i && (i % 20) == 0) + s += "\"\n \""; + } + } + + return "\"" + s + "\""; +} + +QString Uic::trcall( const QString& sourceText, const QString& comment ) +{ + if ( sourceText.isEmpty() && comment.isEmpty() ) + return "QString::null"; + + QString t = trmacro; + bool encode = FALSE; + if ( t.isNull() ) { + t = "tr"; + for ( int i = 0; i < (int) sourceText.length(); i++ ) { + if ( sourceText[i].unicode() >= 0x80 ) { + t = "trUtf8"; + encode = TRUE; + break; + } + } + } + + if ( comment.isEmpty() ) { + return t + "( " + fixString( sourceText, encode ) + " )"; + } else { + return t + "( " + fixString( sourceText, encode ) + ", " + + fixString( comment, encode ) + " )"; + } +} + +QString Uic::mkStdSet( const QString& prop ) +{ + return QString( "set" ) + prop[0].upper() + prop.mid(1); +} + + + +/*! + \class Uic uic.h + \brief User Interface Compiler + + The class Uic encapsulates the user interface compiler (uic). + */ +Uic::Uic( const QString &fn, const char *outputFn, QTextStream &outStream, + QDomDocument doc, bool decl, bool subcl, const QString &trm, + const QString& subClass, bool omitForwardDecls ) + : out( outStream ), trout( &languageChangeBody ), + outputFileName( outputFn ), trmacro( trm ), nofwd( omitForwardDecls ) +{ + fileName = fn; + writeFunctImpl = TRUE; + defMargin = BOXLAYOUT_DEFAULT_MARGIN; + defSpacing = BOXLAYOUT_DEFAULT_SPACING; + externPixmaps = FALSE; + indent = " "; // default indent + + item_used = cg_used = pal_used = 0; + + layouts << "hbox" << "vbox" << "grid"; + tags = layouts; + tags << "widget"; + + pixmapLoaderFunction = getPixmapLoaderFunction( doc.firstChild().toElement() ); + nameOfClass = getFormClassName( doc.firstChild().toElement() ); + + uiFileVersion = doc.firstChild().toElement().attribute("version"); + stdsetdef = toBool( doc.firstChild().toElement().attribute("stdsetdef") ); + + if ( doc.firstChild().isNull() || doc.firstChild().firstChild().isNull() ) + return; + QDomElement e = doc.firstChild().firstChild().toElement(); + QDomElement widget; + while ( !e.isNull() ) { + if ( e.tagName() == "widget" ) { + widget = e; + } else if ( e.tagName() == "pixmapinproject" ) { + externPixmaps = TRUE; + } else if ( e.tagName() == "layoutdefaults" ) { + defSpacing = e.attribute( "spacing", defSpacing.toString() ); + defMargin = e.attribute( "margin", defMargin.toString() ); + } else if ( e.tagName() == "layoutfunctions" ) { + defSpacing = e.attribute( "spacing", defSpacing.toString() ); + bool ok; + defSpacing.toInt( &ok ); + if ( !ok ) { + QString buf = defSpacing.toString(); + defSpacing = buf.append( "()" ); + } + defMargin = e.attribute( "margin", defMargin.toString() ); + defMargin.toInt( &ok ); + if ( !ok ) { + QString buf = defMargin.toString(); + defMargin = buf.append( "()" ); + } + } + e = e.nextSibling().toElement(); + } + e = widget; + + if ( nameOfClass.isEmpty() ) + nameOfClass = getObjectName( e ); + namespaces = QStringList::split( "::", nameOfClass ); + bareNameOfClass = namespaces.last(); + namespaces.remove( namespaces.fromLast() ); + + if ( subcl ) { + if ( decl ) + createSubDecl( e, subClass ); + else + createSubImpl( e, subClass ); + } else { + if ( decl ) + createFormDecl( e ); + else + createFormImpl( e ); + } + +} + +/*! Extracts a pixmap loader function from \a e + */ +QString Uic::getPixmapLoaderFunction( const QDomElement& e ) +{ + QDomElement n; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "pixmapfunction" ) + return n.firstChild().toText().data(); + } + return QString::null; +} + + +/*! Extracts the forms class name from \a e + */ +QString Uic::getFormClassName( const QDomElement& e ) +{ + QDomElement n; + QString cn; + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "class" ) { + QString s = n.firstChild().toText().data(); + int i; + while ( ( i = s.find(' ' )) != -1 ) + s[i] = '_'; + cn = s; + } + } + return cn; +} + +/*! Extracts a class name from \a e. + */ +QString Uic::getClassName( const QDomElement& e ) +{ + QString s = e.attribute( "class" ); + if ( s.isEmpty() && e.tagName() == "toolbar" ) + s = "QToolBar"; + else if ( s.isEmpty() && e.tagName() == "menubar" ) + s = "QMenuBar"; + return s; +} + +/*! Returns TRUE if database framework code is generated, else FALSE. +*/ + +bool Uic::isFrameworkCodeGenerated( const QDomElement& e ) +{ + QDomElement n = getObjectProperty( e, "frameworkCode" ); + if ( n.attribute("name") == "frameworkCode" && + !DomTool::elementToVariant( n.firstChild().toElement(), QVariant( TRUE, 0 ) ).toBool() ) + return FALSE; + return TRUE; +} + +/*! Extracts an object name from \a e. It's stored in the 'name' + property. + */ +QString Uic::getObjectName( const QDomElement& e ) +{ + QDomElement n = getObjectProperty( e, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) + return n.firstChild().toElement().firstChild().toText().data(); + return QString::null; +} + +/*! Extracts an layout name from \a e. It's stored in the 'name' + property of the preceeding sibling (the first child of a QLayoutWidget). + */ +QString Uic::getLayoutName( const QDomElement& e ) +{ + QDomElement p = e.parentNode().toElement(); + QString name; + + if ( getClassName(p) != "QLayoutWidget" ) + name = "Layout"; + + QDomElement n = getObjectProperty( p, "name" ); + if ( n.firstChild().toElement().tagName() == "cstring" ) { + name.prepend( n.firstChild().toElement().firstChild().toText().data() ); + return QStringList::split( "::", name ).last(); + } + return e.tagName(); +} + + +QString Uic::getDatabaseInfo( const QDomElement& e, const QString& tag ) +{ + QDomElement n; + QDomElement n1; + int child = 0; + // database info is a stringlist stored in this order + if ( tag == "connection" ) + child = 0; + else if ( tag == "table" ) + child = 1; + else if ( tag == "field" ) + child = 2; + else + return QString::null; + n = getObjectProperty( e, "database" ); + if ( n.firstChild().toElement().tagName() == "stringlist" ) { + // find correct stringlist entry + QDomElement n1 = n.firstChild().firstChild().toElement(); + for ( int i = 0; i < child && !n1.isNull(); ++i ) + n1 = n1.nextSibling().toElement(); + if ( n1.isNull() ) + return QString::null; + return n1.firstChild().toText().data(); + } + return QString::null; +} + + +void Uic::registerLayouts( const QDomElement &e ) +{ + if ( layouts.contains(e.tagName())) { + createObjectDecl(e); + QString t = e.tagName(); + if ( t == "vbox" || t == "hbox" || t == "grid" ) + createSpacerDecl( e ); + } + + QDomNodeList nl = e.childNodes(); + for ( int i = 0; i < (int) nl.length(); ++i ) + registerLayouts( nl.item(i).toElement() ); +} + + +/*! + Returns include file for class \a className or a null string. + */ +QString Uic::getInclude( const QString& className ) +{ + int wid = WidgetDatabase::idFromClassName( className ); + if ( wid != -1 ) + return WidgetDatabase::includeFile( wid ); + return QString::null; +} + + +void Uic::createActionDecl( const QDomElement& e ) +{ + QString objClass = e.tagName() == "action" ? "QAction" : "QActionGroup"; + QString objName = getObjectName( e ); + if ( objName.isEmpty() ) + return; + out << " " << objClass << "* " << objName << ";" << endl; + if ( e.tagName() == "actiongroup" ) { + for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) + createActionDecl( n ); + } + } +} + +void Uic::createToolbarDecl( const QDomElement &e ) +{ + if ( e.tagName() == "toolbar" ) + out << " " << "QToolBar *" << getObjectName( e ) << ";" << endl; +} + +void Uic::createMenuBarDecl( const QDomElement &e ) +{ + if ( e.tagName() == "item" ) { + out << " " << "QPopupMenu *" << e.attribute( "name" ) << ";" << endl; + createPopupMenuDecl( e ); + } +} + +void Uic::createPopupMenuDecl( const QDomElement &e ) +{ + for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) { + QDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item" ) { // the action has a sub menu + out << " " << "QPopupMenu *" << n2.attribute( "name" ) << ";" << endl; + createPopupMenuDecl( n2 ); + n = n2; + } + } + } +} + +void Uic::createActionImpl( const QDomElement &n, const QString &parent ) +{ + for ( QDomElement ae = n; !ae.isNull(); ae = ae.nextSibling().toElement() ) { + QString objName = registerObject( getObjectName( ae ) ); + if ( ae.tagName() == "action" ) + out << indent << objName << " = new QAction( " << parent << ", \"" << objName << "\" );" << endl; + else if ( ae.tagName() == "actiongroup" ) + out << indent << objName << " = new QActionGroup( " << parent << ", \"" << objName << "\" );" << endl; + else + continue; + bool subActionsDone = FALSE; + bool hasMenuText = FALSE; + QString actionText; + for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "property" ) { + bool stdset = stdsetdef; + if ( n2.hasAttribute( "stdset" ) ) + stdset = toBool( n2.attribute( "stdset" ) ); + QString prop = n2.attribute("name"); + if ( prop == "name" ) + continue; + QString value = setObjectProperty( "QAction", objName, prop, n2.firstChild().toElement(), stdset ); + if ( value.isEmpty() ) + continue; + + QString call = objName + "->"; + if ( stdset ) { + call += mkStdSet( prop ) + "( "; + } else { + call += "setProperty( \"" + prop + "\", "; + } + call += value + " );"; + + if (prop == "menuText") + hasMenuText = TRUE; + else if (prop == "text") + actionText = value; + + if ( n2.firstChild().toElement().tagName() == "string" ) { + trout << indent << call << endl; + } else { + out << indent << call << endl; + } + } else if ( !subActionsDone && ( n2.tagName() == "actiongroup" || n2.tagName() == "action" ) ) { + createActionImpl( n2, objName ); + subActionsDone = TRUE; + } + } + // workaround for loading pre-3.3 files expecting bogus QAction behavior + if (!hasMenuText && !actionText.isEmpty() && uiFileVersion < "3.3") + trout << indent << objName << "->setMenuText(" << actionText << ");" << endl; + } +} + +QString get_dock( const QString &d ) +{ + if ( d == "0" ) + return "DockUnmanaged"; + if ( d == "1" ) + return "DockTornOff"; + if ( d == "2" ) + return "DockTop"; + if ( d == "3" ) + return "DockBottom"; + if ( d == "4" ) + return "DockRight"; + if ( d == "5" ) + return "DockLeft"; + if ( d == "6" ) + return "DockMinimized"; + return ""; +} + +void Uic::createToolbarImpl( const QDomElement &n, const QString &parentClass, const QString &parent ) +{ + QDomNodeList nl = n.elementsByTagName( "toolbar" ); + for ( int i = 0; i < (int) nl.length(); i++ ) { + QDomElement ae = nl.item( i ).toElement(); + QString dock = get_dock( ae.attribute( "dock" ) ); + QString objName = getObjectName( ae ); + out << indent << objName << " = new QToolBar( QString(\"\"), this, " << dock << " ); " << endl; + createObjectImpl( ae, parentClass, parent ); + for ( QDomElement n2 = ae.firstChild().toElement(); !n2.isNull(); n2 = n2.nextSibling().toElement() ) { + if ( n2.tagName() == "action" ) { + out << indent << n2.attribute( "name" ) << "->addTo( " << objName << " );" << endl; + } else if ( n2.tagName() == "separator" ) { + out << indent << objName << "->addSeparator();" << endl; + } else if ( n2.tagName() == "widget" ) { + if ( n2.attribute( "class" ) != "Spacer" ) { + createObjectImpl( n2, "QToolBar", objName ); + } else { + QString child = createSpacerImpl( n2, parentClass, parent, objName ); + out << indent << "QApplication::sendPostedEvents( " << objName + << ", QEvent::ChildInserted );" << endl; + out << indent << objName << "->boxLayout()->addItem( " << child << " );" << endl; + } + } + } + } +} + +void Uic::createMenuBarImpl( const QDomElement &n, const QString &parentClass, const QString &parent ) +{ + QString objName = getObjectName( n ); + out << indent << objName << " = new QMenuBar( this, \"" << objName << "\" );" << endl; + createObjectImpl( n, parentClass, parent ); + int i = 0; + QDomElement c = n.firstChild().toElement(); + while ( !c.isNull() ) { + if ( c.tagName() == "item" ) { + QString itemName = c.attribute( "name" ); + out << endl; + out << indent << itemName << " = new QPopupMenu( this );" << endl; + createPopupMenuImpl( c, parentClass, itemName ); + out << indent << objName << "->insertItem( QString(\"\"), " << itemName << ", " << i << " );" << endl; + QString findItem(objName + "->findItem(%1)"); + findItem = findItem.arg(i); + trout << indent << "if (" << findItem << ")" << endl; + trout << indent << indent << findItem << "->setText( " << trcall( c.attribute( "text" ) ) << " );" << endl; + } else if ( c.tagName() == "separator" ) { + out << endl; + out << indent << objName << "->insertSeparator( " << i << " );" << endl; + } + c = c.nextSibling().toElement(); + i++; + } +} + +void Uic::createPopupMenuImpl( const QDomElement &e, const QString &parentClass, const QString &parent ) +{ + int i = 0; + for ( QDomElement n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) { + QDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item" ) { // the action has a sub menu + QString itemName = n2.attribute( "name" ); + QString itemText = n2.attribute( "text" ); + out << indent << itemName << " = new QPopupMenu( this );" << endl; + out << indent << parent << "->insertItem( " << n.attribute( "name" ) << "->iconSet(), "; + out << trcall( itemText ) << ", " << itemName << " );" << endl; + trout << indent << parent << "->changeItem( " << parent << "->idAt( " << i << " ), "; + trout << trcall( itemText ) << " );" << endl; + createPopupMenuImpl( n2, parentClass, itemName ); + n = n2; + } else { + out << indent << n.attribute( "name" ) << "->addTo( " << parent << " );" << endl; + } + } else if ( n.tagName() == "separator" ) { + out << indent << parent << "->insertSeparator();" << endl; + } + ++i; + } +} + +/*! + Creates implementation of an listbox item tag. +*/ + +QString Uic::createListBoxItemImpl( const QDomElement &e, const QString &parent, + QString *value ) +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + " )" ); + } + } + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + if ( pix.isEmpty() ) { + return parent + "->insertItem( " + trcall( txt, com ) + " );"; + } else { + return parent + "->insertItem( " + pix + ", " + trcall( txt, com ) + " );"; + } +} + +/*! + Creates implementation of an iconview item tag. +*/ + +QString Uic::createIconViewItemImpl( const QDomElement &e, const QString &parent ) +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + " )" ); + } + } + } + n = n.nextSibling().toElement(); + } + + if ( pix.isEmpty() ) + return "(void) new QIconViewItem( " + parent + ", " + trcall( txt, com ) + " );"; + else + return "(void) new QIconViewItem( " + parent + ", " + trcall( txt, com ) + ", " + pix + " );"; +} + +/*! + Creates implementation of an listview item tag. +*/ + +QString Uic::createListViewItemImpl( const QDomElement &e, const QString &parent, + const QString &parentItem ) +{ + QString s; + + QDomElement n = e.firstChild().toElement(); + + bool hasChildren = e.elementsByTagName( "item" ).count() > 0; + QString item; + + if ( hasChildren ) { + item = registerObject( "item" ); + s = indent + "QListViewItem * " + item + " = "; + } else { + item = "item"; + if ( item_used ) + s = indent + item + " = "; + else + s = indent + "QListViewItem * " + item + " = "; + item_used = TRUE; + } + + if ( !parentItem.isEmpty() ) + s += "new QListViewItem( " + parentItem + ", " + lastItem + " );\n"; + else + s += "new QListViewItem( " + parent + ", " + lastItem + " );\n"; + + QStringList texts; + QStringList pixmaps; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + texts << v.toString(); + else if ( attrib == "pixmap" ) { + QString pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + " )" ); + } + pixmaps << pix; + } + } else if ( n.tagName() == "item" ) { + s += indent + item + "->setOpen( TRUE );\n"; + s += createListViewItemImpl( n, parent, item ); + } + n = n.nextSibling().toElement(); + } + + for ( int i = 0; i < (int)texts.count(); ++i ) { + if ( !texts[ i ].isEmpty() ) + s += indent + item + "->setText( " + QString::number( i ) + ", " + trcall( texts[ i ] ) + " );\n"; + if ( !pixmaps[ i ].isEmpty() ) + s += indent + item + "->setPixmap( " + QString::number( i ) + ", " + pixmaps[ i ] + " );\n"; + } + + lastItem = item; + return s; +} + +/*! + Creates implementation of an listview column tag. +*/ + +QString Uic::createListViewColumnImpl( const QDomElement &e, const QString &parent, + QString *value ) +{ + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + bool clickable = FALSE, resizable = FALSE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + " )" ); + } + } else if ( attrib == "clickable" ) + clickable = v.toBool(); + else if ( attrib == "resizable" || attrib == "resizeable" ) + resizable = v.toBool(); + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + QString s; + s = indent + parent + "->addColumn( " + trcall( txt, com ) + " );\n"; + if ( !pix.isEmpty() ) + s += indent + parent + "->header()->setLabel( " + parent + "->header()->count() - 1, " + pix + ", " + trcall( txt, com ) + " );\n"; + if ( !clickable ) + s += indent + parent + "->header()->setClickEnabled( FALSE, " + parent + "->header()->count() - 1 );\n"; + if ( !resizable ) + s += indent + parent + "->header()->setResizeEnabled( FALSE, " + parent + "->header()->count() - 1 );\n"; + return s; +} + +QString Uic::createTableRowColumnImpl( const QDomElement &e, const QString &parent, + QString *value ) +{ + QString objClass = getClassName( e.parentNode().toElement() ); + QDomElement n = e.firstChild().toElement(); + QString txt; + QString com; + QString pix; + QString field; + bool isRow = e.tagName() == "row"; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute("name"); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) { + txt = v.toString(); + com = getComment( n ); + } else if ( attrib == "pixmap" ) { + pix = v.toString(); + if ( !pix.isEmpty() && !pixmapLoaderFunction.isEmpty() ) { + pix.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) ); + pix.append( QString( externPixmaps ? "\"" : "" ) + " )" ); + } + } else if ( attrib == "field" ) + field = v.toString(); + } + n = n.nextSibling().toElement(); + } + + if ( value ) + *value = trcall( txt, com ); + + // ### This generated code sucks! We have to set the number of + // rows/cols before and then only do setLabel/() + // ### careful, though, since QDataTable has an API which makes this code pretty good + + QString s; + if ( isRow ) { + s = indent + parent + "->setNumRows( " + parent + "->numRows() + 1 );\n"; + if ( pix.isEmpty() ) + s += indent + parent + "->verticalHeader()->setLabel( " + parent + "->numRows() - 1, " + + trcall( txt, com ) + " );\n"; + else + s += indent + parent + "->verticalHeader()->setLabel( " + parent + "->numRows() - 1, " + + pix + ", " + trcall( txt, com ) + " );\n"; + } else { + if ( objClass == "QTable" ) { + s = indent + parent + "->setNumCols( " + parent + "->numCols() + 1 );\n"; + if ( pix.isEmpty() ) + s += indent + parent + "->horizontalHeader()->setLabel( " + parent + "->numCols() - 1, " + + trcall( txt, com ) + " );\n"; + else + s += indent + parent + "->horizontalHeader()->setLabel( " + parent + "->numCols() - 1, " + + pix + ", " + trcall( txt, com ) + " );\n"; + } else if ( objClass == "QDataTable" ) { + if ( !txt.isEmpty() && !field.isEmpty() ) { + if ( pix.isEmpty() ) + out << indent << parent << "->addColumn( " << fixString( field ) << ", " << trcall( txt, com ) << " );" << endl; + else + out << indent << parent << "->addColumn( " << fixString( field ) << ", " << trcall( txt, com ) << ", " << pix << " );" << endl; + } + } + } + return s; +} + +/*! + Creates the implementation of a layout tag. Called from createObjectImpl(). + */ +QString Uic::createLayoutImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout ) +{ + QDomElement n; + QString objClass, objName; + objClass = e.tagName(); + + QString qlayout = "QVBoxLayout"; + if ( objClass == "hbox" ) + qlayout = "QHBoxLayout"; + else if ( objClass == "grid" ) + qlayout = "QGridLayout"; + + bool isGrid = e.tagName() == "grid" ; + objName = registerObject( getLayoutName( e ) ); + layoutObjects += objName; + + QString margin = DomTool::readProperty( e, "margin", defMargin ).toString(); + QString spacing = DomTool::readProperty( e, "spacing", defSpacing ).toString(); + QString resizeMode = DomTool::readProperty( e, "resizeMode", QString::null ).toString(); + + QString optcells; + if ( isGrid ) + optcells = "1, 1, "; + if ( (parentClass == "QGroupBox" || parentClass == "QButtonGroup") && layout.isEmpty() ) { + // special case for group box + out << indent << parent << "->setColumnLayout(0, Qt::Vertical );" << endl; + out << indent << parent << "->layout()->setSpacing( " << spacing << " );" << endl; + out << indent << parent << "->layout()->setMargin( " << margin << " );" << endl; + out << indent << objName << " = new " << qlayout << "( " << parent << "->layout() );" << endl; + out << indent << objName << "->setAlignment( Qt::AlignTop );" << endl; + } else { + out << indent << objName << " = new " << qlayout << "( "; + if ( layout.isEmpty() ) + out << parent; + else { + out << "0"; + if ( !DomTool::hasProperty( e, "margin" ) ) + margin = "0"; + } + out << ", " << optcells << margin << ", " << spacing << ", \"" << objName << "\"); " << endl; + } + if ( !resizeMode.isEmpty() ) + out << indent << objName << "->setResizeMode( QLayout::" << resizeMode << " );" << endl; + + if ( !isGrid ) { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + if ( n.tagName() == "spacer" ) { + QString child = createSpacerImpl( n, parentClass, parent, objName ); + out << indent << objName << "->addItem( " << child << " );" << endl; + } else if ( tags.contains( n.tagName() ) ) { + QString child = createObjectImpl( n, parentClass, parent, objName ); + if ( isLayout( child ) ) + out << indent << objName << "->addLayout( " << child << " );" << endl; + else + out << indent << objName << "->addWidget( " << child << " );" << endl; + } + } + } else { + for ( n = e.firstChild().toElement(); !n.isNull(); n = n.nextSibling().toElement() ) { + QDomElement ae = n; + int row = ae.attribute( "row" ).toInt(); + int col = ae.attribute( "column" ).toInt(); + int rowspan = ae.attribute( "rowspan" ).toInt(); + int colspan = ae.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + if ( n.tagName() == "spacer" ) { + QString child = createSpacerImpl( n, parentClass, parent, objName ); + if ( rowspan * colspan != 1 ) + out << indent << objName << "->addMultiCell( " << child << ", " + << row << ", " << ( row + rowspan - 1 ) << ", " << col << ", " << ( col + colspan - 1 ) << " );" << endl; + else + out << indent << objName << "->addItem( " << child << ", " + << row << ", " << col << " );" << endl; + } else if ( tags.contains( n.tagName() ) ) { + QString child = createObjectImpl( n, parentClass, parent, objName ); + out << endl; + QString o = "Widget"; + if ( isLayout( child ) ) + o = "Layout"; + if ( rowspan * colspan != 1 ) + out << indent << objName << "->addMultiCell" << o << "( " << child << ", " + << row << ", " << ( row + rowspan - 1 ) << ", " << col << ", " << ( col + colspan - 1 ) << " );" << endl; + else + out << indent << objName << "->add" << o << "( " << child << ", " + << row << ", " << col << " );" << endl; + } + } + } + + return objName; +} + + + +QString Uic::createSpacerImpl( const QDomElement &e, const QString& /*parentClass*/, const QString& /*parent*/, const QString& /*layout*/) +{ + QDomElement n; + QString objClass, objName; + objClass = e.tagName(); + objName = registerObject( getObjectName( e ) ); + + QSize size = DomTool::readProperty( e, "sizeHint", QSize( 0, 0 ) ).toSize(); + QString sizeType = DomTool::readProperty( e, "sizeType", "Expanding" ).toString(); + bool isVspacer = DomTool::readProperty( e, "orientation", "Horizontal" ) == "Vertical"; + + if ( sizeType != "Expanding" && sizeType != "MinimumExpanding" && + DomTool::hasProperty( e, "geometry" ) ) { // compatibility Qt 2.2 + QRect geom = DomTool::readProperty( e, "geometry", QRect(0,0,0,0) ).toRect(); + size = geom.size(); + } + + if ( isVspacer ) + out << " " << objName << " = new QSpacerItem( " + << size.width() << ", " << size.height() + << ", QSizePolicy::Minimum, QSizePolicy::" << sizeType << " );" << endl; + else + out << " " << objName << " = new QSpacerItem( " + << size.width() << ", " << size.height() + << ", QSizePolicy::" << sizeType << ", QSizePolicy::Minimum );" << endl; + + return objName; +} + +static const char* const ColorRole[] = { + "Foreground", "Button", "Light", "Midlight", "Dark", "Mid", + "Text", "BrightText", "ButtonText", "Base", "Background", "Shadow", + "Highlight", "HighlightedText", "Link", "LinkVisited", 0 +}; + + +/*! + Creates a colorgroup with name \a name from the color group \a cg + */ +void Uic::createColorGroupImpl( const QString& name, const QDomElement& e ) +{ + QColorGroup cg; + int r = -1; + QDomElement n = e.firstChild().toElement(); + QString color; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + QColor col = DomTool::readColor( n ); + color = "QColor( %1, %2, %3)"; + color = color.arg( col.red() ).arg( col.green() ).arg( col.blue() ); + if ( col == white ) + color = "white"; + else if ( col == black ) + color = "black"; + if ( n.nextSibling().toElement().tagName() != "pixmap" ) { + out << indent << name << ".setColor( QColorGroup::" << ColorRole[r] << ", " << color << " );" << endl; + } + } else if ( n.tagName() == "pixmap" ) { + QString pixmap = n.firstChild().toText().data(); + if ( !pixmapLoaderFunction.isEmpty() ) { + pixmap.prepend( pixmapLoaderFunction + "( " + QString( externPixmaps ? "\"" : "" ) ); + pixmap.append( QString( externPixmaps ? "\"" : "" ) + " )" ); + } + out << indent << name << ".setBrush( QColorGroup::" + << ColorRole[r] << ", QBrush( " << color << ", " << pixmap << " ) );" << endl; + } + n = n.nextSibling().toElement(); + } +} + +/*! + Auxiliary function to load a color group. The colorgroup must not + contain pixmaps. + */ +QColorGroup Uic::loadColorGroup( const QDomElement &e ) +{ + QColorGroup cg; + int r = -1; + QDomElement n = e.firstChild().toElement(); + QColor col; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + cg.setColor( (QColorGroup::ColorRole)r, (col = DomTool::readColor( n ) ) ); + } + n = n.nextSibling().toElement(); + } + return cg; +} + +/*! Returns TRUE if the widget properties specify that it belongs to + the database \a connection and \a table. +*/ + +bool Uic::isWidgetInTable( const QDomElement& e, const QString& connection, const QString& table ) +{ + QString conn = getDatabaseInfo( e, "connection" ); + QString tab = getDatabaseInfo( e, "table" ); + if ( conn == connection && tab == table ) + return TRUE; + return FALSE; +} + +/*! + Registers all database connections, cursors and forms. +*/ + +void Uic::registerDatabases( const QDomElement& e ) +{ + QDomElement n; + QDomNodeList nl; + int i; + nl = e.parentNode().toElement().elementsByTagName( "widget" ); + for ( i = 0; i < (int) nl.length(); ++i ) { + n = nl.item(i).toElement(); + QString conn = getDatabaseInfo( n, "connection" ); + QString tab = getDatabaseInfo( n, "table" ); + QString fld = getDatabaseInfo( n, "field" ); + if ( !conn.isNull() ) { + dbConnections += conn; + if ( !tab.isNull() ) { + dbCursors[conn] += tab; + if ( !fld.isNull() ) + dbForms[conn] += tab; + } + } + } +} + +/*! + Registers an object with name \a name. + + The returned name is a valid variable identifier, as similar to \a + name as possible and guaranteed to be unique within the form. + + \sa registeredName(), isObjectRegistered() + */ +QString Uic::registerObject( const QString& name ) +{ + if ( objectNames.isEmpty() ) { + // some temporary variables we need + objectNames += "img"; + objectNames += "item"; + objectNames += "cg"; + objectNames += "pal"; + } + + QString result = name; + int i; + while ( ( i = result.find(' ' )) != -1 ) { + result[i] = '_'; + } + + if ( objectNames.contains( result ) ) { + int i = 2; + while ( objectNames.contains( result + "_" + QString::number(i) ) ) + i++; + result += "_"; + result += QString::number(i); + } + objectNames += result; + objectMapper.insert( name, result ); + return result; +} + +/*! + Returns the registered name for the original name \a name + or \a name if \a name wasn't registered. + + \sa registerObject(), isObjectRegistered() + */ +QString Uic::registeredName( const QString& name ) +{ + if ( !objectMapper.contains( name ) ) + return name; + return objectMapper[name]; +} + +/*! + Returns whether the object \a name was registered yet or not. + */ +bool Uic::isObjectRegistered( const QString& name ) +{ + return objectMapper.contains( name ); +} + + +/*! + Unifies the entries in stringlist \a list. Should really be a QStringList feature. + */ +QStringList Uic::unique( const QStringList& list ) +{ + if ( list.isEmpty() ) + return list; + + QStringList result; + for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) { + if ( !result.contains(*it) ) + result += *it; + } + return result; +} + + + +/*! + Creates an instance of class \a objClass, with parent \a parent and name \a objName + */ +QString Uic::createObjectInstance( const QString& objClass, const QString& parent, const QString& objName ) +{ + + if ( objClass.mid( 1 ) == "ComboBox" ) { + return objClass + "( FALSE, " + parent + ", \"" + objName + "\" )"; + } + return objClass + "( " + parent + ", \"" + objName + "\" )"; +} + +bool Uic::isLayout( const QString& name ) const +{ + return layoutObjects.contains( name ); +} + + + diff --git a/tools/designer/uic/uic.h b/tools/designer/uic/uic.h new file mode 100644 index 0000000..f6e41a5 --- /dev/null +++ b/tools/designer/uic/uic.h @@ -0,0 +1,176 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef UIC_H +#define UIC_H +#include +#include +#include +#include +#include +#include +#include + +class Uic : public Qt +{ +public: + Uic( const QString &fn, const char *outputFn, QTextStream& out, + QDomDocument doc, bool decl, bool subcl, const QString &trm, + const QString& subclname, bool omitForwardDecls ); + + void createFormDecl( const QDomElement &e ); + void createFormImpl( const QDomElement &e ); + + void createSubDecl( const QDomElement &e, const QString& subclname ); + void createSubImpl( const QDomElement &e, const QString& subclname ); + + void createObjectDecl( const QDomElement &e ); + void createSpacerDecl( const QDomElement &e ); + void createActionDecl( const QDomElement &e ); + void createToolbarDecl( const QDomElement &e ); + void createMenuBarDecl( const QDomElement &e ); + void createPopupMenuDecl( const QDomElement &e ); + void createActionImpl( const QDomElement &e, const QString &parent ); + void createToolbarImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + void createMenuBarImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + void createPopupMenuImpl( const QDomElement &e, const QString &parentClass, const QString &parent ); + QString createObjectImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + QString createLayoutImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + QString createObjectInstance( const QString& objClass, const QString& parent, const QString& objName ); + QString createSpacerImpl( const QDomElement &e, const QString& parentClass, const QString& parent, const QString& layout = QString::null ); + void createExclusiveProperty( const QDomElement & e, const QString& exclusiveProp ); + QString createListBoxItemImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createIconViewItemImpl( const QDomElement &e, const QString &parent ); + QString createListViewColumnImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createTableRowColumnImpl( const QDomElement &e, const QString &parent, QString *value = 0 ); + QString createListViewItemImpl( const QDomElement &e, const QString &parent, + const QString &parentItem ); + void createColorGroupImpl( const QString& cg, const QDomElement& e ); + QColorGroup loadColorGroup( const QDomElement &e ); + + QDomElement getObjectProperty( const QDomElement& e, const QString& name ); + QString getPixmapLoaderFunction( const QDomElement& e ); + QString getFormClassName( const QDomElement& e ); + QString getClassName( const QDomElement& e ); + QString getObjectName( const QDomElement& e ); + QString getLayoutName( const QDomElement& e ); + QString getInclude( const QString& className ); + + QString setObjectProperty( const QString& objClass, const QString& obj, const QString &prop, const QDomElement &e, bool stdset ); + + QString registerObject( const QString& name ); + QString registeredName( const QString& name ); + bool isObjectRegistered( const QString& name ); + QStringList unique( const QStringList& ); + + QString trcall( const QString& sourceText, const QString& comment = "" ); + + static void embed( QTextStream& out, const char* project, const QStringList& images ); + +private: + void registerLayouts ( const QDomElement& e ); + + QTextStream& out; + QTextOStream trout; + QString languageChangeBody; + QCString outputFileName; + QStringList objectNames; + QMap objectMapper; + QString indent; + QStringList tags; + QStringList layouts; + QString formName; + QString lastItem; + QString trmacro; + bool nofwd; + + struct Buddy + { + Buddy( const QString& k, const QString& b ) + : key( k ), buddy( b ) {} + Buddy(){} // for valuelist + QString key; + QString buddy; + bool operator==( const Buddy& other ) const + { return (key == other.key); } + }; + struct CustomInclude + { + QString header; + QString location; + Q_DUMMY_COMPARISON_OPERATOR(CustomInclude) + }; + QValueList buddies; + + QStringList layoutObjects; + bool isLayout( const QString& name ) const; + + uint item_used : 1; + uint cg_used : 1; + uint pal_used : 1; + uint stdsetdef : 1; + uint externPixmaps : 1; + + QString uiFileVersion; + QString nameOfClass; + QStringList namespaces; + QString bareNameOfClass; + QString pixmapLoaderFunction; + + void registerDatabases( const QDomElement& e ); + bool isWidgetInTable( const QDomElement& e, const QString& connection, const QString& table ); + bool isFrameworkCodeGenerated( const QDomElement& e ); + QString getDatabaseInfo( const QDomElement& e, const QString& tag ); + void createFormImpl( const QDomElement& e, const QString& form, const QString& connection, const QString& table ); + void writeFunctionsDecl( const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst ); + void writeFunctionsSubDecl( const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst ); + void writeFunctionsSubImpl( const QStringList &fuLst, const QStringList &typLst, const QStringList &specLst, + const QString &subClass, const QString &descr ); + QStringList dbConnections; + QMap< QString, QStringList > dbCursors; + QMap< QString, QStringList > dbForms; + + static bool isMainWindow; + static QString mkBool( bool b ); + static QString mkBool( const QString& s ); + bool toBool( const QString& s ); + static QString fixString( const QString &str, bool encode = FALSE ); + static bool onlyAscii; + static QString mkStdSet( const QString& prop ); + static QString getComment( const QDomNode& n ); + QVariant defSpacing, defMargin; + QString fileName; + bool writeFunctImpl; +}; + +#endif diff --git a/tools/designer/uic/uic.pro b/tools/designer/uic/uic.pro new file mode 100644 index 0000000..ef5bde0 --- /dev/null +++ b/tools/designer/uic/uic.pro @@ -0,0 +1,42 @@ +TEMPLATE = app +CONFIG += qt console warn_on release professional +HEADERS = uic.h \ + ../shared/widgetdatabase.h \ + ../shared/domtool.h \ + ../shared/parser.h \ + ../interfaces/widgetinterface.h + +#HEADERS += ../shared/ui2uib.h \ +# ../shared/uib.h + +SOURCES = main.cpp uic.cpp form.cpp object.cpp \ + subclassing.cpp embed.cpp\ + ../shared/widgetdatabase.cpp \ + ../shared/domtool.cpp \ + ../shared/parser.cpp + +#SOURCES += ../shared/ui2uib.cpp \ +# ../shared/uib.cpp + +DEFINES += QT_INTERNAL_XML +include( ../../../src/qt_professional.pri ) + +TARGET = uic +INCLUDEPATH += ../shared +DEFINES += UIC +DESTDIR = ../../../bin + +target.path=$$bins.path +INSTALLS += target + +*-mwerks { + TEMPLATE = lib + TARGET = McUic + CONFIG -= static + CONFIG += shared plugin + DEFINES += UIC_MWERKS_PLUGIN + MWERKSDIR = $(QT_SOURCE_TREE)/util/mwerks_plugin + INCLUDEPATH += $$MWERKSDIR/Headers + LIBS += $$MWERKSDIR/Libraries/PluginLib4.shlb + SOURCES += mwerks_mac.cpp +} diff --git a/tools/designer/uilib/qwidgetfactory.cpp b/tools/designer/uilib/qwidgetfactory.cpp new file mode 100644 index 0000000..a1ff1c2 --- /dev/null +++ b/tools/designer/uilib/qwidgetfactory.cpp @@ -0,0 +1,2623 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qwidgetfactory.h" + +#include "../interfaces/languageinterface.h" +#include "../interfaces/widgetinterface.h" + +#include +#include "../designer/database2.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_SQL +#include +#include +#include +#endif + +// include all Qt widgets we support +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef QT_NO_TABLE +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class QWidgetFactoryPrivate +{ +public: + QCString translationContext; + QListViewItem *lastItem; + QDict customWidgets; +}; + +static QPtrList widgetFactories; +static QPluginManager *languageInterfaceManager = 0; +static QPluginManager *widgetInterfaceManager = 0; + +static QMap *availableWidgetMap = 0; +static QStringList *availableWidgetList = 0; + +QMap *qwf_forms = 0; +QString *qwf_language = 0; +bool qwf_execute_code = TRUE; +bool qwf_stays_on_top = FALSE; +QString qwf_currFileName = ""; +QObject *qwf_form_object = 0; +QString *qwf_plugin_dir = 0; + +static void setupPluginDir() +{ + if ( !qwf_plugin_dir ) + qwf_plugin_dir = new QString( "/designer" ); +} + +static void setupWidgetListAndMap() +{ + if ( availableWidgetMap ) + return; + setupPluginDir(); + availableWidgetList = new QStringList; + (*availableWidgetList) << "QPushButton" << "QToolButton" << "QCheckBox" << "QRadioButton" + << "QGroupBox" << "QButtonGroup" << "QIconView" << "QTable" + << "QListBox" << "QListView" << "QLineEdit" << "QSpinBox" + << "QMultiLineEdit" << "QLabel" << "TextLabel" << "PixmapLabel" + << "QLayoutWidget" << "QTabWidget" << "QComboBox" + << "QWidget" << "QDialog" << "QWizard" << "QLCDNumber"; + // put less stress on the compiler by limiting the template nesting depth + (*availableWidgetList) << "QProgressBar" << "QTextView" << "QTextBrowser" + << "QDial" << "QSlider" << "QFrame" << "Line" << "QTextEdit" + << "QDateEdit" << "QTimeEdit" << "QDateTimeEdit" << "QScrollBar" + << "QPopupMenu" << "QWidgetStack" << "QMainWindow" + << "QDataTable" << "QDataBrowser" << "QDataView" + << "QVBox" << "QHBox" << "QGrid" << "QToolBox" << "QSplitter"; + + if ( !widgetInterfaceManager ) + widgetInterfaceManager = + new QPluginManager( IID_Widget, QApplication::libraryPaths(), *qwf_plugin_dir ); + + QStringList l = widgetInterfaceManager->featureList(); + QStringList::Iterator it; + for ( it = l.begin(); it != l.end(); ++it ) + (*availableWidgetList) << *it; + + availableWidgetMap = new QMap; + for ( it = availableWidgetList->begin(); it != availableWidgetList->end(); ++it ) + availableWidgetMap->insert( *it, TRUE ); +} + +static QImage loadImageData( const QString& format, ulong len, QByteArray data ) +{ + QImage img; + if ( format == "XPM.GZ" || format == "XBM.GZ" ) { + if ( len < data.size() * 10 ) + len = data.size() * 10; + // qUncompress() expects the first 4 bytes to be the expected length of + // the uncompressed data + QByteArray dataTmp( data.size() + 4 ); + memcpy( dataTmp.data()+4, data.data(), data.size() ); + dataTmp[0] = ( len & 0xff000000 ) >> 24; + dataTmp[1] = ( len & 0x00ff0000 ) >> 16; + dataTmp[2] = ( len & 0x0000ff00 ) >> 8; + dataTmp[3] = ( len & 0x000000ff ); + QByteArray baunzip = qUncompress( dataTmp ); + len = baunzip.size(); + img.loadFromData( (const uchar*)baunzip.data(), len, format.left(format.find('.')) ); + } else { + img.loadFromData( (const uchar*)data.data(), data.size(), format ); + } + return img; +} + +static QSizePolicy::SizeType stringToSizeType( const QString& str ) +{ + if ( str == "Fixed" ) { + return QSizePolicy::Fixed; + } else if ( str == "Minimum" ) { + return QSizePolicy::Minimum; + } else if ( str == "Maximum" ) { + return QSizePolicy::Maximum; + } else if ( str == "Preferred" ) { + return QSizePolicy::Preferred; + } else if ( str == "MinimumExpanding" ) { + return QSizePolicy::MinimumExpanding; + } else if ( str == "Expanding" ) { + return QSizePolicy::Expanding; + } else { + return QSizePolicy::Ignored; + } +} + + +/*! + \class QWidgetFactory + + \brief The QWidgetFactory class provides for the dynamic creation of widgets + from Qt Designer .ui files. + + This class basically offers two things: + + \list + + \i Dynamically creating widgets from \link designer-manual.book Qt + Designer\endlink user interface description files. + You can do this using the static function QWidgetFactory::create(). + This function also performs signal and slot connections, tab + ordering, etc., as defined in the .ui file, and returns the + top-level widget in the .ui file. After creating the widget you can + use QObject::child() and QObject::queryList() to access child + widgets of this returned widget. + + \i Adding additional widget factories to be able to create custom + widgets. See createWidget() for details. + + \endlist + + This class is not included in the Qt library itself. To use it you + must link against \c libqui.so (Unix) or \c qui.lib (Windows), which is + built into \c INSTALL/lib if you built \e{Qt Designer} (\c INSTALL is + the directory where Qt is installed ). + + If you create a QMainWindow using a QWidgetFactory, be aware that + it already has a central widget. Therefore, you need to delete this + one before setting another one. + + See the "Creating Dynamic Dialogs from .ui Files" section of the \link + designer-manual.book Qt Designer manual\endlink for an example. See + also the \l{QWidgetPlugin} class and the \link plugins-howto.html + Plugins documentation\endlink. +*/ + +/*! Constructs a QWidgetFactory. */ + +QWidgetFactory::QWidgetFactory() + : d( new QWidgetFactoryPrivate() ), dbControls( 0 ), + usePixmapCollection( FALSE ), defMargin( 11 ), defSpacing( 6 ) +{ + widgetFactories.setAutoDelete( TRUE ); + d->customWidgets.setAutoDelete( TRUE ); +} + +/*! \fn QWidgetFactory::~QWidgetFactory() + Destructor. +*/ +QWidgetFactory::~QWidgetFactory() +{ + delete d; +} + +/*! + + Loads the \e{Qt Designer} user interface description file \a uiFile + and returns the top-level widget in that description. \a parent and + \a name are passed to the constructor of the top-level widget. + + This function also performs signal and slot connections, tab + ordering, etc., as described in the .ui file. In \e{Qt Designer} it + is possible to add custom slots to a form and connect to them. If + you want these connections to be made, you must create a class + derived from QObject, which implements all these slots. Then pass an + instance of the object as \a connector to this function. If you do + this, the connections to the custom slots will be done using the \a + connector as slot. + + If something fails, 0 is returned. + + The ownership of the returned widget is passed to the caller. +*/ + +QWidget *QWidgetFactory::create( const QString &uiFile, QObject *connector, + QWidget *parent, const char *name ) +{ + setupPluginDir(); + QFile f( uiFile ); + bool failed = FALSE; + if ( !f.open( IO_ReadOnly ) ) + failed = TRUE; + if ( failed && qApp->type() == QApplication::Tty ) { + // for QSA: If we have no GUI, we have no form definition + // files, but just the code. So try if only the code exists. + f.setName( uiFile + ".qs" ); + failed = !f.open( IO_ReadOnly ); + } + if ( failed ) + return 0; + + qwf_currFileName = uiFile; + QWidget *w = QWidgetFactory::create( &f, connector, parent, name ); + if ( !qwf_forms ) + qwf_forms = new QMap; + qwf_forms->insert( w, uiFile ); + return w; +} + +#undef slots + +/*! \overload + Loads the user interface description from device \a dev. + */ + +QWidget *QWidgetFactory::create( QIODevice *dev, QObject *connector, QWidget *parent, const char *name ) +{ + setupPluginDir(); + QWidget *w = 0; + QDomDocument doc; + QString errMsg; + int errLine; + + QWidgetFactory *widgetFactory = new QWidgetFactory; + widgetFactory->toplevel = 0; + + // If we have no GUI, we only want to load the code + if ( qApp->type() != QApplication::Tty ) { + QIODevice::Offset start = dev->at(); + Q_UINT32 magic; + QDataStream in( dev ); + in >> magic; + if ( magic == UibMagic ) { + w = widgetFactory->createFromUibFile( in, connector, parent, name ); + } else { + in.unsetDevice(); + dev->at( start ); + if ( doc.setContent( dev, &errMsg, &errLine ) ) { + w = widgetFactory->createFromUiFile( doc, connector, parent, name ); + } else { + // qDebug( QString("Parse error: ") + errMsg + QString(" in line %d"), errLine ); + } + } + if ( !w ) { + delete widgetFactory; + return 0; + } + } + + if ( !languageInterfaceManager ) + languageInterfaceManager = + new QPluginManager( IID_Language, QApplication::libraryPaths(), *qwf_plugin_dir ); + widgetFactory->loadExtraSource(); + + if ( widgetFactory->toplevel ) { +#ifndef QT_NO_SQL + QMap::Iterator cit = widgetFactory->sqlWidgetConnections.begin(); + for( ; cit != widgetFactory->sqlWidgetConnections.end(); ++cit ) { + if ( widgetFactory->noDatabaseWidgets.find( cit.key()->name() ) != + widgetFactory->noDatabaseWidgets.end() ) + continue; + if ( cit.key()->inherits( "QDesignerDataBrowser2" ) ) + ( (QDesignerDataBrowser2*)cit.key() )->initPreview( (*cit).conn, (*cit).table, + cit.key(), *(*cit).dbControls ); + else if ( cit.key()->inherits( "QDesignerDataView2" ) ) + ( (QDesignerDataView2*)cit.key() )->initPreview( (*cit).conn, (*cit).table, + cit.key(), *(*cit).dbControls ); + } + + for ( QMap::Iterator it = widgetFactory->dbTables.begin(); + it != widgetFactory->dbTables.end(); ++it ) { + QDataTable *table = (QDataTable*)widgetFactory->toplevel->child( it.key(), "QDataTable" ); + if ( !table ) + continue; + if ( widgetFactory->noDatabaseWidgets.find( table->name() ) != + widgetFactory->noDatabaseWidgets.end() ) + continue; + QValueList fieldMap = *widgetFactory->fieldMaps.find( table ); + QString conn = (*it)[ 0 ]; + QSqlCursor* c = 0; + QSqlDatabase *db = 0; + if ( conn.isEmpty() || conn == "(default)" ) { + db = QSqlDatabase::database(); + c = new QSqlCursor( (*it)[ 1 ] ); + } else { + db = QSqlDatabase::database( conn ); + c = new QSqlCursor( (*it)[ 1 ], TRUE, db ); + } + if ( db ) { + table->setSqlCursor( c, fieldMap.isEmpty(), TRUE ); + table->refresh( QDataTable::RefreshAll ); + } + } +#endif + } + + for ( QMap::Iterator it = widgetFactory->buddies.begin(); + it != widgetFactory->buddies.end(); ++it ) { + QLabel *label = (QLabel*)widgetFactory->toplevel->child( it.key(), "QLabel" ); + QWidget *buddy = (QWidget*)widgetFactory->toplevel->child( *it, "QWidget" ); + if ( label && buddy ) + label->setBuddy( buddy ); + } + + delete widgetFactory; + + QApplication::sendPostedEvents(); + + return w; +} + +QWidget *QWidgetFactory::createFromUiFile( QDomDocument doc, QObject *connector, + QWidget *parent, const char *name ) +{ + DomTool::fixDocument( doc ); + + uiFileVersion = doc.firstChild().toElement().attribute("version"); + QDomElement e = doc.firstChild().toElement().firstChild().toElement(); + + QDomElement variables = e; + while ( variables.tagName() != "variables" && !variables.isNull() ) + variables = variables.nextSibling().toElement(); + + QDomElement slots = e; + while ( slots.tagName() != "slots" && !slots.isNull() ) + slots = slots.nextSibling().toElement(); + + QDomElement connections = e; + while ( connections.tagName() != "connections" && !connections.isNull() ) + connections = connections.nextSibling().toElement(); + + QDomElement imageCollection = e; + while ( imageCollection.tagName() != "images" && !imageCollection.isNull() ) + imageCollection = imageCollection.nextSibling().toElement(); + + QDomElement tabOrder = e; + while ( tabOrder.tagName() != "tabstops" && !tabOrder.isNull() ) + tabOrder = tabOrder.nextSibling().toElement(); + + QDomElement actions = e; + while ( actions.tagName() != "actions" && !actions.isNull() ) + actions = actions.nextSibling().toElement(); + + QDomElement toolbars = e; + while ( toolbars.tagName() != "toolbars" && !toolbars.isNull() ) + toolbars = toolbars.nextSibling().toElement(); + + QDomElement menubar = e; + while ( menubar.tagName() != "menubar" && !menubar.isNull() ) + menubar = menubar.nextSibling().toElement(); + + QDomElement functions = e; + while ( functions.tagName() != "functions" && !functions.isNull() ) + functions = functions.nextSibling().toElement(); + + QDomElement widget; + while ( !e.isNull() ) { + if ( e.tagName() == "class" ) { + d->translationContext = e.firstChild().toText().data(); + } else if ( e.tagName() == "widget" ) { + widget = e; + } else if ( e.tagName() == "pixmapinproject" ) { + usePixmapCollection = TRUE; + } else if ( e.tagName() == "layoutdefaults" ) { + defSpacing = e.attribute( "spacing", QString::number( defSpacing ) ).toInt(); + defMargin = e.attribute( "margin", QString::number( defMargin ) ).toInt(); + } + e = e.nextSibling().toElement(); + } + + if ( !imageCollection.isNull() ) + loadImageCollection( imageCollection ); + + createWidgetInternal( widget, parent, 0, widget.attribute("class", "QWidget") ); + QWidget *w = toplevel; + if ( !w ) + return 0; + + if ( !actions.isNull() ) + loadActions( actions ); + if ( !toolbars.isNull() ) + loadToolBars( toolbars ); + if ( !menubar.isNull() ) + loadMenuBar( menubar ); + + if ( !connections.isNull() ) + loadConnections( connections, connector ); + if ( w && name && qstrlen( name ) > 0 ) + w->setName( name ); + + if ( !tabOrder.isNull() ) + loadTabOrder( tabOrder ); + +#if 0 + if ( !functions.isNull() ) // compatibiliy with early 3.0 betas + loadFunctions( functions ); +#endif + + return w; +} + +void QWidgetFactory::unpackUInt16( QDataStream& in, Q_UINT16& n ) +{ + Q_UINT8 half; + in >> half; + if ( half == 255 ) { + in >> n; + } else { + n = half; + } +} + +void QWidgetFactory::unpackUInt32( QDataStream& in, Q_UINT32& n ) +{ + Q_UINT16 half; + in >> half; + if ( half == 65535 ) { + in >> n; + } else { + n = half; + } +} + +void QWidgetFactory::unpackByteArray( QDataStream& in, QByteArray& array ) +{ + Q_UINT32 size; + unpackUInt32( in, size ); + array.resize( size ); + in.readRawBytes( array.data(), size ); +} + +void QWidgetFactory::unpackCString( const UibStrTable& strings, QDataStream& in, + QCString& cstr ) +{ + Q_UINT32 n; + unpackUInt32( in, n ); + cstr = strings.asCString( n ); +} + +void QWidgetFactory::unpackString( const UibStrTable& strings, QDataStream& in, + QString& str ) +{ + Q_UINT32 n; + unpackUInt32( in, n ); + str = strings.asString( n ); +} + +void QWidgetFactory::unpackStringSplit( const UibStrTable& strings, + QDataStream& in, QString& str ) +{ + QString remainder; + unpackString( strings, in, str ); + unpackString( strings, in, remainder ); + str += remainder; +} + +void QWidgetFactory::unpackVariant( const UibStrTable& strings, QDataStream& in, + QVariant& value ) +{ + QString imageName; + Q_UINT32 number; + Q_UINT16 count; + Q_UINT16 x; + Q_UINT16 y; + Q_UINT16 width; + Q_UINT16 height; + Q_UINT8 bit; + Q_UINT8 type; + + in >> type; + + switch ( type ) { + case QVariant::String: + unpackString( strings, in, value.asString() ); + break; + case QVariant::Pixmap: + unpackString( strings, in, imageName ); + if ( imageName.isEmpty() ) { + value.asPixmap() = QPixmap(); + } else { + value.asPixmap() = loadPixmap( imageName ); + } + break; + case QVariant::Image: + unpackString( strings, in, imageName ); + if ( imageName.isEmpty() ) { + value.asImage() = QImage(); + } else { + value.asImage() = loadFromCollection( imageName ); + } + break; + case QVariant::IconSet: + unpackString( strings, in, imageName ); + if ( imageName.isEmpty() ) { + value.asIconSet() = QIconSet(); + } else { + value.asIconSet() = QIconSet( loadPixmap(imageName) ); + } + break; + case QVariant::StringList: + unpackUInt16( in, count ); + while ( count-- ) { + QString str; + unpackString( strings, in, str ); + value.asStringList().append( str ); + } + break; + case QVariant::Rect: + unpackUInt16( in, x ); + unpackUInt16( in, y ); + unpackUInt16( in, width ); + unpackUInt16( in, height ); + value = QRect( x, y, width, height ); + break; + case QVariant::Size: + unpackUInt16( in, width ); + unpackUInt16( in, height ); + value = QSize( width, height ); + break; + case QVariant::Color: + in >> value.asColor(); + break; + case QVariant::Point: + unpackUInt16( in, x ); + unpackUInt16( in, y ); + value = QPoint( x, y ); + break; + case QVariant::Int: + unpackUInt32( in, number ); + value = (int) number; + break; + case QVariant::Bool: + in >> bit; + value = QVariant( bit != 0, 0 ); + break; + case QVariant::Double: + in >> value.asDouble(); + break; + case QVariant::CString: + unpackCString( strings, in, value.asCString() ); + break; + case QVariant::Cursor: + in >> value.asCursor(); + break; + case QVariant::Date: + in >> value.asDate(); + break; + case QVariant::Time: + in >> value.asTime(); + break; + case QVariant::DateTime: + in >> value.asDateTime(); + break; + default: + in >> value; + } +} + +void QWidgetFactory::inputSpacer( const UibStrTable& strings, QDataStream& in, + QLayout *parent ) +{ + QCString name; + QVariant value; + QCString comment; + QSizePolicy::SizeType sizeType = QSizePolicy::Preferred; + bool vertical = FALSE; + int w = 0; + int h = 0; + Q_UINT16 column = 0; + Q_UINT16 row = 0; + Q_UINT16 colspan = 1; + Q_UINT16 rowspan = 1; + Q_UINT8 objectTag; + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_GridCell: + unpackUInt16( in, column ); + unpackUInt16( in, row ); + unpackUInt16( in, colspan ); + unpackUInt16( in, rowspan ); + break; + case Object_VariantProperty: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + + if ( name == "orientation" ) { + vertical = ( value == "Vertical" ); + } else if ( name == "sizeHint" ) { + w = value.toSize().width(); + h = value.toSize().height(); + } else if ( name == "sizeType" ) { + sizeType = stringToSizeType( value.toString() ); + } + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + } + + if ( parent != 0 ) { + QSpacerItem *spacer; + if ( vertical ) { + spacer = new QSpacerItem( w, h, QSizePolicy::Minimum, sizeType ); + } else { + spacer = new QSpacerItem( w, h, sizeType, QSizePolicy::Minimum ); + } + + if ( parent->inherits("QGridLayout") ) { + ((QGridLayout *) parent)->addMultiCell( spacer, row, + row + rowspan - 1, column, column + colspan - 1, + vertical ? Qt::AlignHCenter : Qt::AlignVCenter ); + } else { + parent->addItem( spacer ); + } + } +} + +void QWidgetFactory::inputColumnOrRow( const UibStrTable& strings, + QDataStream& in, QObject *parent, + bool isRow ) +{ + QString text; + QPixmap pixmap; + QString field; + bool clickable = TRUE; + bool resizable = TRUE; + + QCString name; + QVariant value; + QCString comment; + QString str; + Q_UINT8 objectTag; + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_TextProperty: + unpackCString( strings, in, name ); + unpackCString( strings, in, value.asCString() ); + unpackCString( strings, in, comment ); + str = translate( value.asCString().data(), comment.data() ); + + if ( name == "field" ) { + field = str; + } else if ( name == "text" ) { + text = str; + } + break; + case Object_VariantProperty: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + + if ( name == "clickable" ) { + clickable = value.toBool(); + } else if ( name == "pixmap" ) { + pixmap = value.asPixmap(); + } else if ( name == "resizable" ) { + resizable = value.toBool(); + } + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + } + + if ( parent != 0 ) { + if ( parent->inherits("QListView") ) { + createListViewColumn( (QListView *) parent, text, pixmap, clickable, + resizable ); +#ifndef QT_NO_TABLE + } else if ( parent->inherits("QTable") ) { + createTableColumnOrRow( (QTable *) parent, text, pixmap, field, + isRow ); +#endif + } + } +} + +void QWidgetFactory::inputItem( const UibStrTable& strings, QDataStream& in, + QObject *parent, QListViewItem *parentItem ) +{ + QStringList texts; + QValueList pixmaps; + QCString name; + QVariant value; + QCString comment; + Q_UINT8 objectTag; + + QListView *listView = 0; + if ( parent != 0 && parent->inherits("QListView") ) + parent = (QListView *) parent; + QListViewItem *item = 0; + if ( listView != 0 ) { + if ( parentItem == 0 ) { + item = new QListViewItem( listView, d->lastItem ); + } else { + item = new QListViewItem( parentItem, d->lastItem ); + } + d->lastItem = item; + } + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_Item: + if ( listView != 0 ) + d->lastItem->setOpen( TRUE ); + inputItem( strings, in, parent, item ); + break; + case Object_TextProperty: + unpackCString( strings, in, name ); + unpackCString( strings, in, value.asCString() ); + unpackCString( strings, in, comment ); + + if ( name == "text" ) + texts << translate( value.asCString().data(), comment.data() ); + break; + case Object_VariantProperty: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + + if ( name == "pixmap" ) + pixmaps << value.asPixmap(); + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + } + + if ( listView != 0 ) { + int i = 0; + QStringList::ConstIterator t = texts.begin(); + while ( t != texts.end() ) { + item->setText( i, *t ); + ++i; + ++t; + } + + int j = 0; + QValueList::ConstIterator p = pixmaps.begin(); + while ( p != pixmaps.end() ) { + item->setPixmap( j, *p ); + ++j; + ++p; + } + } else { + QString text = texts.last(); + QPixmap pixmap = pixmaps.last(); + + if ( parent != 0 ) { + if ( parent->inherits("QComboBox") || + parent->inherits("QListBox") ) { + QListBox *listBox = (QListBox *) parent->qt_cast( "QListBox" ); + if ( listBox == 0 ) + listBox = ((QComboBox *) parent)->listBox(); + + if ( pixmap.isNull() ) { + (void) new QListBoxText( listBox, text ); + } else { + (void) new QListBoxPixmap( listBox, pixmap, text ); + } + #ifndef QT_NO_ICONVIEW + } else if ( parent->inherits("QIconView") ) { + (void) new QIconViewItem( (QIconView *) parent, text, pixmap ); + #endif + } + } + } +} + +void QWidgetFactory::inputMenuItem( QObject **objects, + const UibStrTable& strings, QDataStream& in, + QMenuBar *menuBar ) +{ + QCString name; + QCString text; + Q_UINT16 actionNo; + Q_UINT8 objectTag; + + unpackCString( strings, in, name ); + unpackCString( strings, in, text ); + + QPopupMenu *popupMenu = new QPopupMenu( menuBar->parentWidget(), name ); + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_ActionRef: + unpackUInt16( in, actionNo ); + ((QAction *) objects[actionNo])->addTo( popupMenu ); + break; + case Object_Separator: + popupMenu->insertSeparator(); + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + } + menuBar->insertItem( translate(text.data()), popupMenu ); +} + +QObject *QWidgetFactory::inputObject( QObject **objects, int& numObjects, + const UibStrTable& strings, + QDataStream& in, QWidget *ancestorWidget, + QObject *parent, QCString className ) +{ + QObject *obj = 0; + QWidget *widget = 0; + QLayout *layout = 0; + QWidget *parentWidget = 0; + QLayout *parentLayout = 0; + + bool isQObject = !className.isEmpty(); + if ( isQObject ) { + if ( parent != 0 ) { + if ( parent->isWidgetType() ) { + if ( parent->inherits("QMainWindow") ) { + parentWidget = ((QMainWindow *) parent)->centralWidget(); + } else { + parentWidget = (QWidget *) parent; + } + } else if ( parent->inherits("QLayout") ) { + parentLayout = (QLayout *) parent; + parentWidget = ancestorWidget; + } + } + + if ( className == "QAction" ) { + unpackCString( strings, in, className ); + if ( className == "QActionGroup" ) { + obj = new QActionGroup( parent ); + } else { + obj = new QAction( parent ); + } + } else if ( className == "QLayout" ) { + unpackCString( strings, in, className ); + LayoutType type = Grid; + if ( className == "QHBoxLayout" ) { + type = HBox; + } else if ( className == "QVBoxLayout" ) { + type = VBox; + } + if ( parentLayout != 0 && parentLayout->inherits("QGridLayout") ) { + layout = createLayout( 0, 0, type ); + } else { + layout = createLayout( parentWidget, parentLayout, type ); + } + obj = layout; + } else if ( className == "QMenuBar" ) { + unpackCString( strings, in, className ); + widget = ((QMainWindow *) parent)->menuBar(); + obj = widget; + } else if ( className == "QToolBar" ) { + Q_UINT8 dock; + in >> dock; + unpackCString( strings, in, className ); + widget = new QToolBar( QString::null, (QMainWindow *) parent, + (Qt::Dock) dock ); + obj = widget; + } else if ( className == "QWidget" ) { + unpackCString( strings, in, className ); + widget = createWidget( className, parentWidget, 0 ); + obj = widget; + } + + if ( widget != 0 ) + ancestorWidget = widget; + d->lastItem = 0; + objects[numObjects++] = obj; + } + + QCString name; + QVariant value; + QCString comment; + QString str; + Q_UINT16 actionNo; + int metAttribute = 0; + Q_UINT16 column = 0; + Q_UINT16 row = 0; + Q_UINT16 colspan = 1; + Q_UINT16 rowspan = 1; + Q_UINT8 paletteTag; + Q_UINT8 objectTag; + + in >> objectTag; + while ( !in.atEnd() && objectTag != Object_End ) { + switch ( objectTag ) { + case Object_ActionRef: + unpackUInt16( in, actionNo ); + ((QAction *) objects[actionNo])->addTo( (QToolBar *) widget ); + break; + case Object_Attribute: + metAttribute = 2; + break; + case Object_Column: + inputColumnOrRow( strings, in, obj, FALSE ); + break; + case Object_Event: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + // ### do something with value.asStringList() + break; + case Object_FontProperty: + { + QFont font; + QString family; + Q_UINT16 pointSize; + Q_UINT8 fontFlags; + + unpackCString( strings, in, name ); + in >> fontFlags; + + if ( fontFlags & Font_Family ) { + unpackString( strings, in, family ); + font.setFamily( family ); + } + if ( fontFlags & Font_PointSize ) { + unpackUInt16( in, pointSize ); + font.setPointSize( pointSize ); + } + if ( fontFlags & Font_Bold ) + font.setBold( TRUE ); + if ( fontFlags & Font_Italic ) + font.setItalic( TRUE ); + if ( fontFlags & Font_Underline ) + font.setUnderline( TRUE ); + if ( fontFlags & Font_StrikeOut ) + font.setStrikeOut( TRUE ); + + if ( obj != 0 ) + setProperty( obj, name, font ); + } + break; + case Object_GridCell: + unpackUInt16( in, column ); + unpackUInt16( in, row ); + unpackUInt16( in, colspan ); + unpackUInt16( in, rowspan ); + break; + case Object_Item: + inputItem( strings, in, obj ); + break; + case Object_MenuItem: + inputMenuItem( objects, strings, in, (QMenuBar *) widget ); + break; + case Object_PaletteProperty: + { + QPalette palette; + QColorGroup colorGroup; + QColor color; + int role = -1; + + unpackCString( strings, in, name ); + + in >> paletteTag; + while ( !in.atEnd() && paletteTag != Palette_End ) { + switch ( paletteTag ) { + case Palette_Active: + palette.setActive( colorGroup ); + role = -1; + break; + case Palette_Inactive: + palette.setInactive( colorGroup ); + role = -1; + break; + case Palette_Disabled: + palette.setDisabled( colorGroup ); + role = -1; + break; + case Palette_Color: + role++; + in >> color; + colorGroup.setColor( (QColorGroup::ColorRole) role, + color ); + break; + case Palette_Pixmap: + unpackVariant( strings, in, value ); + colorGroup.setBrush( (QColorGroup::ColorRole) role, + QBrush(color, value.asPixmap()) ); + break; + default: + qFatal( "Corrupt" ); + } + in >> paletteTag; + } + if ( obj != 0 ) + setProperty( obj, name, palette ); + } + break; + case Object_Row: + inputColumnOrRow( strings, in, obj, TRUE ); + break; + case Object_Spacer: + inputSpacer( strings, in, layout ); + break; + case Object_Separator: + ((QToolBar *) widget)->addSeparator(); + break; + case Object_SubAction: + inputObject( objects, numObjects, strings, in, parentWidget, + obj != 0 ? obj : parent, "QAction" ); + break; + case Object_SubLayout: + inputObject( objects, numObjects, strings, in, parentWidget, obj, + "QLayout" ); + break; + case Object_SubWidget: + inputObject( objects, numObjects, strings, in, parentWidget, obj, + "QWidget" ); + break; + case Object_TextProperty: + unpackCString( strings, in, name ); + unpackCString( strings, in, value.asCString() ); + unpackCString( strings, in, comment ); + str = translate( value.asCString().data(), comment.data() ); + + if ( metAttribute > 0 ) { + if ( name == "title" ) { + if ( parent != 0 ) { + if ( parent->inherits("QTabWidget") ) { + ((QTabWidget *) parent)->insertTab( widget, str ); + } else if ( parent->inherits("QWizard") ) { + ((QWizard *) parent)->addPage( widget, str ); + } + } + } + } else { + if ( obj != 0 ) + setProperty( obj, name, str ); + } + break; + case Object_VariantProperty: + unpackCString( strings, in, name ); + unpackVariant( strings, in, value ); + + if ( metAttribute > 0 ) { + if ( name == "id" ) { + if ( parent != 0 && parent->inherits("QWidgetStack") ) + ((QWidgetStack *) parent)->addWidget( widget, value.toInt() ); + } + } else { + if ( obj != 0 ) + setProperty( obj, name, value ); + } + break; + default: + qFatal( "Corrupt" ); + } + in >> objectTag; + metAttribute--; + } + + if ( parentLayout != 0 ) { + if ( widget != 0 ) { + if ( parentLayout->inherits("QGridLayout") ) { + ((QGridLayout *) parentLayout)->addMultiCellWidget( + widget, row, row + rowspan - 1, column, + column + colspan - 1 ); + } else { + ((QBoxLayout *) parentLayout)->addWidget( widget ); + } + } else if ( layout != 0 ) { + if ( parentLayout->inherits("QGridLayout") ) { + ((QGridLayout *) parentLayout)->addMultiCellLayout( + layout, row, row + rowspan - 1, column, + column + colspan - 1 ); + } + } + } + return obj; +} + +QWidget *QWidgetFactory::createFromUibFile( QDataStream& in, + QObject * /* connector */ , QWidget *parent, const char *name ) +{ +#define END_OF_BLOCK() \ + ( in.atEnd() || in.device()->at() >= nextBlock ) + + Q_UINT8 lf; + Q_UINT8 cr; + in >> lf; + in >> cr; + if ( lf != '\n' || cr != '\r' ) { + qWarning( "File corrupted" ); + return 0; + } + + Q_UINT8 qdatastreamVersion; + in >> qdatastreamVersion; + if ( (int) qdatastreamVersion > in.version() ) { + qWarning( "Incompatible version of Qt" ); + return 0; + } + in.setVersion( qdatastreamVersion ); + + UibStrTable strings; + QObject **objects = 0; + int numObjects = 0; + + Q_UINT8 blockType; + Q_UINT32 blockSize; + + in >> blockType; + while ( !in.atEnd() && blockType != Block_End ) { + unpackUInt32( in, blockSize ); + QIODevice::Offset nextBlock = in.device()->at() + blockSize; + + switch ( blockType ) { + case Block_Actions: + inputObject( objects, numObjects, strings, in, toplevel, toplevel ); + break; + case Block_Buddies: + { + Q_UINT16 labelNo; + Q_UINT16 buddyNo; + + do { + unpackUInt16( in, labelNo ); + unpackUInt16( in, buddyNo ); + QLabel *label = + (QLabel *) objects[labelNo]->qt_cast( "QLabel" ); + if ( label != 0 ) + label->setBuddy( (QWidget *) objects[buddyNo] ); + } while ( !END_OF_BLOCK() ); + } + break; + case Block_Connections: + { + QString language = "C++"; + Q_UINT16 senderNo = 0; + QString signal = "clicked()"; + Q_UINT16 receiverNo = 0; + QString slot = "accept()"; + Q_UINT8 connectionFlags; + + do { + in >> connectionFlags; + if ( connectionFlags & Connection_Language ) + unpackString( strings, in, language ); + if ( connectionFlags & Connection_Sender ) + unpackUInt16( in, senderNo ); + if ( connectionFlags & Connection_Signal ) + unpackStringSplit( strings, in, signal ); + if ( connectionFlags & Connection_Receiver ) + unpackUInt16( in, receiverNo ); + if ( connectionFlags & Connection_Slot ) + unpackStringSplit( strings, in, slot ); + // ### +#if 0 + qWarning( "connect( %p, %s, %p, %s )", objects[senderNo], + signal.latin1(), objects[receiverNo], + slot.latin1() ); +#endif + } while ( !END_OF_BLOCK() ); + } + break; + case Block_Functions: + // ### + qWarning( "Block_Functions not supported" ); + in.device()->at( nextBlock ); + break; + case Block_Images: + { + QString format; + Q_UINT32 length; + QByteArray data; + Image image; + + do { + unpackString( strings, in, image.name ); + unpackString( strings, in, format ); + unpackUInt32( in, length ); + unpackByteArray( in, data ); + image.img = loadImageData( format, length, data ); + images += image; + } while ( !END_OF_BLOCK() ); + } + break; + case Block_Intro: + { + Q_INT16 defaultMargin; + Q_INT16 defaultSpacing; + Q_UINT16 maxObjects; + Q_UINT8 introFlags; + + in >> introFlags; + in >> defaultMargin; + in >> defaultSpacing; + unpackUInt16( in, maxObjects ); + unpackCString( strings, in, d->translationContext ); + + if ( introFlags & Intro_Pixmapinproject ) + usePixmapCollection = TRUE; + if ( defaultMargin != -32768 ) + defMargin = defaultMargin; + if ( defaultSpacing != -32768 ) + defSpacing = defaultSpacing; + objects = new QObject *[maxObjects]; + } + break; + case Block_Menubar: + inputObject( objects, numObjects, strings, in, toplevel, toplevel, + "QMenuBar" ); + break; + case Block_Slots: + { + QString language; + QString slot; + + do { + unpackString( strings, in, language ); + unpackStringSplit( strings, in, slot ); + } while ( !END_OF_BLOCK() ); + } + break; + case Block_Strings: + strings.readBlock( in, blockSize ); + break; + case Block_Tabstops: + { + Q_UINT16 beforeNo; + Q_UINT16 afterNo; + + unpackUInt16( in, beforeNo ); + while ( !END_OF_BLOCK() ) { + unpackUInt16( in, afterNo ); + toplevel->setTabOrder( (QWidget *) objects[beforeNo], + (QWidget *) objects[afterNo] ); + beforeNo = afterNo; + } + } + break; + case Block_Toolbars: + do { + inputObject( objects, numObjects, strings, in, toplevel, + toplevel, "QToolBar" ); + } while ( !END_OF_BLOCK() ); + break; + case Block_Variables: + // ### + qWarning( "Block_Variables not supported" ); + in.device()->at( nextBlock ); + break; + case Block_Widget: + toplevel = (QWidget *) + inputObject( objects, numObjects, strings, in, toplevel, parent, + "QWidget" ); + if ( toplevel != 0 ) + toplevel->setName( name ); + break; + default: + qWarning( "Version error" ); + return 0; + } + in >> blockType; + } + delete[] objects; + return toplevel; +} + +/*! Installs a widget factory \a factory, which normally contains + additional widgets that can then be created using a QWidgetFactory. + See createWidget() for further details. +*/ + +void QWidgetFactory::addWidgetFactory( QWidgetFactory *factory ) +{ + widgetFactories.append( factory ); +} + +/*! + Creates a widget of the type \a className passing \a parent and \a + name to its constructor. + + If \a className is a widget in the Qt library, it is directly + created by this function. If the widget isn't in the Qt library, + each of the installed widget plugins is asked, in turn, to create + the widget. As soon as a plugin says it can create the widget it + is asked to do so. It may occur that none of the plugins can + create the widget, in which case each installed widget factory is + asked to create the widget (see addWidgetFactory()). If the widget + cannot be created by any of these means, 0 is returned. + + If you have a custom widget, and want it to be created using the + widget factory, there are two approaches you can use: + + \list 1 + + \i Write a widget plugin. This allows you to use the widget in + \e{Qt Designer} and in this QWidgetFactory. See the widget plugin + documentation for further details. (See the "Creating Custom + Widgets with Plugins" section of the \link designer-manual.book Qt + Designer manual\endlink for an example. + + \i Subclass QWidgetFactory. Then reimplement this function to + create and return an instance of your custom widget if \a + className equals the name of your widget, otherwise return 0. Then + at the beginning of your program where you want to use the widget + factory to create widgets do a: + \code + QWidgetFactory::addWidgetFactory( new MyWidgetFactory ); + \endcode + where MyWidgetFactory is your QWidgetFactory subclass. + + \endlist +*/ + +QWidget *QWidgetFactory::createWidget( const QString &className, QWidget *parent, + const char *name ) const +{ + // create widgets we know + if ( className == "QPushButton" ) { + return new QPushButton( parent, name ); + } else if ( className == "QToolButton" ) { + return new QToolButton( parent, name ); + } else if ( className == "QCheckBox" ) { + return new QCheckBox( parent, name ); + } else if ( className == "QRadioButton" ) { + return new QRadioButton( parent, name ); + } else if ( className == "QGroupBox" ) { + return new QGroupBox( parent, name ); + } else if ( className == "QButtonGroup" ) { + return new QButtonGroup( parent, name ); + } else if ( className == "QIconView" ) { +#if !defined(QT_NO_ICONVIEW) + return new QIconView( parent, name ); +#endif + } else if ( className == "QTable" ) { +#if !defined(QT_NO_TABLE) + return new QTable( parent, name ); +#endif + } else if ( className == "QListBox" ) { + return new QListBox( parent, name ); + } else if ( className == "QListView" ) { + return new QListView( parent, name ); + } else if ( className == "QLineEdit" ) { + return new QLineEdit( parent, name ); + } else if ( className == "QSpinBox" ) { + return new QSpinBox( parent, name ); + } else if ( className == "QMultiLineEdit" ) { + return new QMultiLineEdit( parent, name ); + } else if ( className == "QLabel" || className == "TextLabel" || className == "PixmapLabel" ) { + return new QLabel( parent, name ); + } else if ( className == "QLayoutWidget" ) { + return new QWidget( parent, name ); + } else if ( className == "QTabWidget" ) { + return new QTabWidget( parent, name ); + } else if ( className == "QComboBox" ) { + return new QComboBox( FALSE, parent, name ); + } else if ( className == "QWidget" ) { + if ( !qwf_stays_on_top ) + return new QWidget( parent, name ); + return new QWidget( parent, name, Qt::WStyle_StaysOnTop ); + } else if ( className == "QDialog" ) { + if ( !qwf_stays_on_top ) + return new QDialog( parent, name ); + return new QDialog( parent, name, FALSE, Qt::WStyle_StaysOnTop ); + } else if ( className == "QWizard" ) { + return new QWizard( parent, name ); + } else if ( className == "QLCDNumber" ) { + return new QLCDNumber( parent, name ); + } else if ( className == "QProgressBar" ) { + return new QProgressBar( parent, name ); + } else if ( className == "QTextView" ) { + return new QTextView( parent, name ); + } else if ( className == "QTextBrowser" ) { + return new QTextBrowser( parent, name ); + } else if ( className == "QDial" ) { + return new QDial( parent, name ); + } else if ( className == "QSlider" ) { + return new QSlider( parent, name ); + } else if ( className == "QFrame" ) { + return new QFrame( parent, name ); + } else if ( className == "QSplitter" ) { + return new QSplitter( parent, name ); + } else if ( className == "Line" ) { + QFrame *f = new QFrame( parent, name ); + f->setFrameStyle( QFrame::HLine | QFrame::Sunken ); + return f; + } else if ( className == "QTextEdit" ) { + return new QTextEdit( parent, name ); + } else if ( className == "QDateEdit" ) { + return new QDateEdit( parent, name ); + } else if ( className == "QTimeEdit" ) { + return new QTimeEdit( parent, name ); + } else if ( className == "QDateTimeEdit" ) { + return new QDateTimeEdit( parent, name ); + } else if ( className == "QScrollBar" ) { + return new QScrollBar( parent, name ); + } else if ( className == "QPopupMenu" ) { + return new QPopupMenu( parent, name ); + } else if ( className == "QWidgetStack" ) { + return new QWidgetStack( parent, name ); + } else if ( className == "QToolBox" ) { + return new QToolBox( parent, name ); + } else if ( className == "QVBox" ) { + return new QVBox( parent, name ); + } else if ( className == "QHBox" ) { + return new QHBox( parent, name ); + } else if ( className == "QGrid" ) { + return new QGrid( 4, parent, name ); + } else if ( className == "QMainWindow" ) { + QMainWindow *mw = 0; + if ( !qwf_stays_on_top ) + mw = new QMainWindow( parent, name ); + else + mw = new QMainWindow( parent, name, Qt::WType_TopLevel | Qt::WStyle_StaysOnTop ); + mw->setCentralWidget( new QWidget( mw, "qt_central_widget" ) ); + mw->centralWidget()->show(); + (void)mw->statusBar(); + return mw; + + } +#if !defined(QT_NO_SQL) + else if ( className == "QDataTable" ) { + return new QDataTable( parent, name ); + } else if ( className == "QDataBrowser" ) { + return new QDesignerDataBrowser2( parent, name ); + } else if ( className == "QDataView" ) { + return new QDesignerDataView2( parent, name ); + } +#endif + + setupPluginDir(); + // try to create it using the loaded widget plugins + if ( !widgetInterfaceManager ) + widgetInterfaceManager = + new QPluginManager( IID_Widget, QApplication::libraryPaths(), + *qwf_plugin_dir ); + + QInterfacePtr iface = 0; + widgetInterfaceManager->queryInterface( className, &iface ); + if ( iface ) { + QWidget *w = iface->create( className, parent, name ); + if ( w ) { + d->customWidgets.replace( className.latin1(), new bool(TRUE) ); + return w; + } + } + + // hope we have a factory which can do it + for ( QWidgetFactory* f = widgetFactories.first(); f; f = widgetFactories.next() ) { + QWidget *w = f->createWidget( className, parent, name ); + if ( w ) + return w; + } + + // no success + return 0; +} + +/*! Returns the names of the widgets this factory can create. */ + +QStringList QWidgetFactory::widgets() +{ + setupWidgetListAndMap(); + return *availableWidgetList; +} + +/*! Returns TRUE if the widget factory can create the specified \a widget; +otherwise returns FALSE. */ + +bool QWidgetFactory::supportsWidget( const QString &widget ) +{ + setupWidgetListAndMap(); + return ( availableWidgetMap->find( widget ) != availableWidgetMap->end() ); +} + +QWidget *QWidgetFactory::createWidgetInternal( const QDomElement &e, QWidget *parent, + QLayout* layout, const QString &classNameArg ) +{ + d->lastItem = 0; + QDomElement n = e.firstChild().toElement(); + QWidget *w = 0; // the widget that got created + QObject *obj = 0; // gets the properties + + QString className = classNameArg; + + int row = e.attribute( "row" ).toInt(); + int col = e.attribute( "column" ).toInt(); + int rowspan = e.attribute( "rowspan" ).toInt(); + int colspan = e.attribute( "colspan" ).toInt(); + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + + bool isQLayoutWidget = FALSE; + + if ( !className.isEmpty() ) { + if ( !layout && className == "QLayoutWidget" ) { + className = "QWidget"; + isQLayoutWidget = TRUE; + } + if ( layout && className == "QLayoutWidget" ) { + // hide layout widgets + w = parent; + } else { + obj = QWidgetFactory::createWidget( className, parent, 0 ); + if ( !obj ) + return 0; + w = (QWidget*)obj; + if ( !toplevel ) + toplevel = w; + if ( w->inherits( "QMainWindow" ) ) + w = ( (QMainWindow*)w )->centralWidget(); + if ( layout ) { + switch( layoutType( layout ) ) { + case HBox: + ( (QHBoxLayout*)layout )->addWidget( w ); + break; + case VBox: + ( (QVBoxLayout*)layout )->addWidget( w ); + break; + case Grid: + ( (QGridLayout*)layout )->addMultiCellWidget( w, row, row + rowspan - 1, + col, col + colspan - 1 ); + break; + default: + break; + } + } + + layout = 0; + } + } +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + QString parentClassName = parent ? parent->className() : 0; + bool isPlugin = parent ? !!d->customWidgets.find( parent->className() ) : FALSE; + if ( isPlugin ) + qWarning( "####### loading custom container widgets without page support not implemented!" ); + // ### TODO loading for custom container widgets without pages +#endif + + int idx = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "spacer" ) { + createSpacer( n, layout ); + } else if ( n.tagName() == "widget" ) { + QMap< QString, QString> *oldDbControls = dbControls; + createWidgetInternal( n, w, layout, n.attribute( "class", "QWidget" ) ); + dbControls = oldDbControls; + } else if ( n.tagName() == "hbox" ) { + QLayout *parentLayout = layout; + if ( layout && layout->inherits( "QGridLayout" ) ) + layout = createLayout( 0, 0, QWidgetFactory::HBox, isQLayoutWidget ); + else + layout = createLayout( w, layout, QWidgetFactory::HBox, isQLayoutWidget ); + obj = layout; + n = n.firstChild().toElement(); + if ( parentLayout && parentLayout->inherits( "QGridLayout" ) ) + ( (QGridLayout*)parentLayout )->addMultiCellLayout( layout, row, + row + rowspan - 1, col, col + colspan - 1 ); + continue; + } else if ( n.tagName() == "grid" ) { + QLayout *parentLayout = layout; + if ( layout && layout->inherits( "QGridLayout" ) ) + layout = createLayout( 0, 0, QWidgetFactory::Grid, isQLayoutWidget ); + else + layout = createLayout( w, layout, QWidgetFactory::Grid, isQLayoutWidget ); + obj = layout; + n = n.firstChild().toElement(); + if ( parentLayout && parentLayout->inherits( "QGridLayout" ) ) + ( (QGridLayout*)parentLayout )->addMultiCellLayout( layout, row, + row + rowspan - 1, col, col + colspan - 1 ); + continue; + } else if ( n.tagName() == "vbox" ) { + QLayout *parentLayout = layout; + if ( layout && layout->inherits( "QGridLayout" ) ) + layout = createLayout( 0, 0, QWidgetFactory::VBox, isQLayoutWidget ); + else + layout = createLayout( w, layout, QWidgetFactory::VBox, isQLayoutWidget ); + obj = layout; + n = n.firstChild().toElement(); + if ( parentLayout && parentLayout->inherits( "QGridLayout" ) ) + ( (QGridLayout*)parentLayout )->addMultiCellLayout( layout, row, + row + rowspan - 1, col, col + colspan - 1 ); + continue; + } else if ( n.tagName() == "property" && obj ) { + setProperty( obj, n.attribute( "name" ), n.firstChild().toElement() ); + } else if ( n.tagName() == "attribute" && w ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( parent ) { + if ( parent->inherits( "QTabWidget" ) ) { + if ( attrib == "title" ) + ( (QTabWidget*)parent )->insertTab( w, translate( v.toString() ) ); + } else if ( parent->inherits( "QWidgetStack" ) ) { + if ( attrib == "id" ) + ( (QWidgetStack*)parent )->addWidget( w, v.toInt() ); + } else if ( parent->inherits( "QToolBox" ) ) { + if ( attrib == "label" ) + ( (QToolBox*)parent )->addItem( w, v.toString() ); + } else if ( parent->inherits( "QWizard" ) ) { + if ( attrib == "title" ) + ( (QWizard*)parent )->addPage( w, translate( v.toString() ) ); +#ifdef QT_CONTAINER_CUSTOM_WIDGETS + } else if ( isPlugin ) { + if ( attrib == "label" ) { + WidgetInterface *iface = 0; + widgetInterfaceManager->queryInterface( parentClassName, &iface ); + if ( iface ) { + QWidgetContainerInterfacePrivate *iface2 = 0; + iface->queryInterface( IID_QWidgetContainer, + (QUnknownInterface**)&iface2 ); + if ( iface2 ) { + iface2->insertPage( parentClassName, + (QWidget*)parent, translate( v.toString() ), -1, w ); + iface2->release(); + } + iface->release(); + } + } +#endif + } + } + } else if ( n.tagName() == "item" ) { + createItem( n, w ); + } else if ( n.tagName() == "column" || n.tagName() == "row" ) { + createColumn( n, w ); + } + + n = n.nextSibling().toElement(); + idx++; + } + + return w; +} + +QLayout *QWidgetFactory::createLayout( QWidget *widget, QLayout* layout, + LayoutType type, bool isQLayoutWidget ) +{ + int spacing = defSpacing; + int margin = defMargin; + + if ( layout || !widget || isQLayoutWidget ) + margin = 0; + + if ( !layout && widget && widget->inherits( "QTabWidget" ) ) + widget = ((QTabWidget*)widget)->currentPage(); + + if ( !layout && widget && widget->inherits( "QWizard" ) ) + widget = ((QWizard*)widget)->currentPage(); + + if ( !layout && widget && widget->inherits( "QWidgetStack" ) ) + widget = ((QWidgetStack*)widget)->visibleWidget(); + + if ( !layout && widget && widget->inherits( "QToolBox" ) ) + widget = ((QToolBox*)widget)->currentItem(); + + QLayout *l = 0; + int align = 0; + if ( !layout && widget && widget->inherits( "QGroupBox" ) ) { + QGroupBox *gb = (QGroupBox*)widget; + gb->setColumnLayout( 0, Qt::Vertical ); + layout = gb->layout(); + layout->setMargin( 0 ); + layout->setSpacing( 0 ); + align = Qt::AlignTop; + } + if ( layout ) { + switch ( type ) { + case HBox: + l = new QHBoxLayout( layout ); + break; + case VBox: + l = new QVBoxLayout( layout ); + break; + case Grid: + l = new QGridLayout( layout ); + break; + default: + return 0; + } + } else { + switch ( type ) { + case HBox: + l = new QHBoxLayout( widget ); + break; + case VBox: + l = new QVBoxLayout( widget ); + break; + case Grid: + l = new QGridLayout( widget ); + break; + default: + return 0; + } + } + l->setAlignment( align ); + l->setMargin( margin ); + l->setSpacing( spacing ); + return l; +} + +QWidgetFactory::LayoutType QWidgetFactory::layoutType( QLayout *layout ) const +{ + if ( layout->inherits( "QHBoxLayout" ) ) + return HBox; + else if ( layout->inherits( "QVBoxLayout" ) ) + return VBox; + else if ( layout->inherits( "QGridLayout" ) ) + return Grid; + return NoLayout; +} + +void QWidgetFactory::setProperty( QObject* obj, const QString &prop, + QVariant value ) +{ + int offset = obj->metaObject()->findProperty( prop, TRUE ); + + if ( offset != -1 ) { + if ( prop == "geometry" && obj == toplevel ) { + toplevel->resize( value.toRect().size() ); + } else if ( prop == "accel" ) { + obj->setProperty( prop, value.toKeySequence() ); + } else { + if ( value.type() == QVariant::String || + value.type() == QVariant::CString ) { + const QMetaProperty *metaProp = + obj->metaObject()->property( offset, TRUE ); + if ( metaProp != 0 && metaProp->isEnumType() ) { + if ( metaProp->isSetType() ) { + QStrList flagsCStr; + QStringList flagsStr = + QStringList::split( '|', value.asString() ); + QStringList::ConstIterator f = flagsStr.begin(); + while ( f != flagsStr.end() ) { + flagsCStr.append( *f ); + ++f; + } + value = QVariant( metaProp->keysToValue(flagsCStr) ); + } else { + QCString key = value.toCString(); + value = QVariant( metaProp->keyToValue(key) ); + } + } + } + obj->setProperty( prop, value ); + } + } else { + if ( obj->isWidgetType() ) { + if ( prop == "toolTip" ) { + if ( !value.toString().isEmpty() ) + QToolTip::add( (QWidget*)obj, translate( value.toString() ) ); + } else if ( prop == "whatsThis" ) { + if ( !value.toString().isEmpty() ) + QWhatsThis::add( (QWidget*)obj, translate( value.toString() ) ); + } else if ( prop == "buddy" ) { + buddies.insert( obj->name(), value.toCString() ); + } else if ( prop == "buttonGroupId" ) { + if ( obj->inherits( "QButton" ) && obj->parent()->inherits( "QButtonGroup" ) ) + ( (QButtonGroup*)obj->parent() )->insert( (QButton*)obj, value.toInt() ); +#ifndef QT_NO_SQL + } else if ( prop == "database" && !obj->inherits( "QDataView" ) + && !obj->inherits( "QDataBrowser" ) ) { + const QStringList& lst = value.asStringList(); + if ( lst.count() > 2 ) { + if ( dbControls ) + dbControls->insert( obj->name(), lst[ 2 ] ); + } else if ( lst.count() == 2 ) { + dbTables.insert( obj->name(), lst ); + } + } else if ( prop == "database" ) { + const QStringList& lst = value.asStringList(); + if ( lst.count() == 2 && obj->inherits( "QWidget" ) ) { + SqlWidgetConnection conn( lst[ 0 ], lst[ 1 ] ); + sqlWidgetConnections.insert( (QWidget*)obj, conn ); + dbControls = conn.dbControls; + } +#endif + } else if ( prop == "frameworkCode" ) { + if ( value.isValid() && !value.toBool() ) + noDatabaseWidgets << obj->name(); + } + } + } +} + +void QWidgetFactory::setProperty( QObject* widget, const QString &prop, const QDomElement &e ) +{ + QString comment; + QVariant value( DomTool::elementToVariant( e, QVariant(), comment ) ); + + if ( e.tagName() == "string" ) { + value = translate( value.asString(), comment ); + } else if ( e.tagName() == "pixmap" ) { + QPixmap pix = loadPixmap( value.toString() ); + if ( !pix.isNull() ) + value = pix; + } else if ( e.tagName() == "iconset" ) { + QPixmap pix = loadPixmap( value.toString() ); + if ( !pix.isNull() ) + value = QIconSet( pix ); + } else if ( e.tagName() == "image" ) { + value = loadFromCollection( value.toString() ); + } else if ( e.tagName() == "palette" ) { + QDomElement n = e.firstChild().toElement(); + QPalette p; + while ( !n.isNull() ) { + QColorGroup cg; + if ( n.tagName() == "active" ) { + cg = loadColorGroup( n ); + p.setActive( cg ); + } else if ( n.tagName() == "inactive" ) { + cg = loadColorGroup( n ); + p.setInactive( cg ); + } else if ( n.tagName() == "disabled" ) { + cg = loadColorGroup( n ); + p.setDisabled( cg ); + } + n = n.nextSibling().toElement(); + } + value = p; + } + setProperty( widget, prop, value ); +} + +void QWidgetFactory::createSpacer( const QDomElement &e, QLayout *layout ) +{ + QDomElement n = e.firstChild().toElement(); + int row = e.attribute( "row" ).toInt(); + int col = e.attribute( "column" ).toInt(); + int rowspan = e.attribute( "rowspan" ).toInt(); + int colspan = e.attribute( "colspan" ).toInt(); + + Qt::Orientation orient = Qt::Horizontal; + int w = 0, h = 0; + QSizePolicy::SizeType sizeType = QSizePolicy::Preferred; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString prop = n.attribute( "name" ); + if ( prop == "orientation" ) { + if ( n.firstChild().firstChild().toText().data() == "Horizontal" ) + orient = Qt::Horizontal; + else + orient = Qt::Vertical; + } else if ( prop == "sizeType" ) { + sizeType = stringToSizeType( n.firstChild().firstChild().toText().data() ); + } else if ( prop == "sizeHint" ) { + w = n.firstChild().firstChild().firstChild().toText().data().toInt(); + h = n.firstChild().firstChild().nextSibling().firstChild().toText().data().toInt(); + } + } + n = n.nextSibling().toElement(); + } + + if ( rowspan < 1 ) + rowspan = 1; + if ( colspan < 1 ) + colspan = 1; + QSpacerItem *item = new QSpacerItem( w, h, orient == Qt::Horizontal ? sizeType : QSizePolicy::Minimum, + orient == Qt::Vertical ? sizeType : QSizePolicy::Minimum ); + if ( layout ) { + if ( layout->inherits( "QBoxLayout" ) ) + ( (QBoxLayout*)layout )->addItem( item ); + else + ( (QGridLayout*)layout )->addMultiCell( item, row, row + rowspan - 1, col, col + colspan - 1, + orient == Qt::Horizontal ? Qt::AlignVCenter : Qt::AlignHCenter ); + } +} + +static QImage loadImageData( QDomElement &n2 ) +{ + QString format = n2.attribute( "format", "PNG" ); + QString hex = n2.firstChild().toText().data(); + int n = hex.length() / 2; + QByteArray data( n ); + for ( int i = 0; i < n; i++ ) + data[i] = (char) hex.mid( 2 * i, 2 ).toUInt( 0, 16 ); + return loadImageData( format, n2.attribute("length").toULong(), data ); +} + +void QWidgetFactory::loadImageCollection( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "image" ) { + Image img; + img.name = n.attribute( "name" ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "data" ) + img.img = loadImageData( n2 ); + n2 = n2.nextSibling().toElement(); + } + images.append( img ); + n = n.nextSibling().toElement(); + } + } +} + +QImage QWidgetFactory::loadFromCollection( const QString &name ) +{ + QValueList::Iterator it = images.begin(); + for ( ; it != images.end(); ++it ) { + if ( ( *it ).name == name ) + return ( *it ).img; + } + return QImage(); +} + +QPixmap QWidgetFactory::loadPixmap( const QString& name ) +{ + QPixmap pix; + if ( usePixmapCollection ) { + const QMimeSource *m = QMimeSourceFactory::defaultFactory()->data( name ); + if ( m ) + QImageDrag::decode( m, pix ); + } else { + pix.convertFromImage( loadFromCollection(name) ); + } + return pix; +} + +QPixmap QWidgetFactory::loadPixmap( const QDomElement &e ) +{ + return loadPixmap( e.firstChild().toText().data() ); +} + +QColorGroup QWidgetFactory::loadColorGroup( const QDomElement &e ) +{ + QColorGroup cg; + int r = -1; + QDomElement n = e.firstChild().toElement(); + QColor col; + while ( !n.isNull() ) { + if ( n.tagName() == "color" ) { + r++; + cg.setColor( (QColorGroup::ColorRole)r, (col = DomTool::readColor( n ) ) ); + } else if ( n.tagName() == "pixmap" ) { + QPixmap pix = loadPixmap( n ); + cg.setBrush( (QColorGroup::ColorRole)r, QBrush( col, pix ) ); + } + n = n.nextSibling().toElement(); + } + return cg; +} + +struct Connection +{ + QObject *sender, *receiver; + QCString signal, slot; + bool operator==( const Connection &c ) const { + return sender == c.sender && receiver == c.receiver && + signal == c.signal && slot == c.slot ; + } + + Connection() : sender( 0 ), receiver( 0 ) { } +}; + +class NormalizeObject : public QObject +{ +public: + NormalizeObject() : QObject() {} + static QCString normalizeSignalSlot( const char *signalSlot ) { return QObject::normalizeSignalSlot( signalSlot ); } +}; + +void QWidgetFactory::loadConnections( const QDomElement &e, QObject *connector ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "connection" ) { + QString lang = n.attribute( "language", "C++" ); + QDomElement n2 = n.firstChild().toElement(); + Connection conn; + while ( !n2.isNull() ) { + if ( n2.tagName() == "sender" ) { + QString name = n2.firstChild().toText().data(); + if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) { + conn.sender = toplevel; + } else { + if ( name == "this" ) + name = toplevel->name(); + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) + conn.sender = l->first(); + delete l; + } + } + if ( !conn.sender ) + conn.sender = findAction( name ); + } else if ( n2.tagName() == "signal" ) { + conn.signal = n2.firstChild().toText().data(); + } else if ( n2.tagName() == "receiver" ) { + QString name = n2.firstChild().toText().data(); + if ( name == "this" || qstrcmp( toplevel->name(), name ) == 0 ) { + conn.receiver = toplevel; + } else { + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) + conn.receiver = l->first(); + delete l; + } + } + } else if ( n2.tagName() == "slot" ) { + conn.slot = n2.firstChild().toText().data(); + } + n2 = n2.nextSibling().toElement(); + } + + conn.signal = NormalizeObject::normalizeSignalSlot( conn.signal ); + conn.slot = NormalizeObject::normalizeSignalSlot( conn.slot ); + + if ( !conn.sender || !conn.receiver ) { + n = n.nextSibling().toElement(); + continue; + } + + QObject *sender = 0, *receiver = 0; + QObjectList *l = toplevel->queryList( 0, conn.sender->name(), FALSE ); + if ( qstrcmp( conn.sender->name(), toplevel->name() ) == 0 ) { + sender = toplevel; + } else { + if ( !l || !l->first() ) { + delete l; + n = n.nextSibling().toElement(); + continue; + } + sender = l->first(); + delete l; + } + if ( !sender ) + sender = findAction( conn.sender->name() ); + + if ( qstrcmp( conn.receiver->name(), toplevel->name() ) == 0 ) { + receiver = toplevel; + } else { + l = toplevel->queryList( 0, conn.receiver->name(), FALSE ); + if ( !l || !l->first() ) { + delete l; + n = n.nextSibling().toElement(); + continue; + } + receiver = l->first(); + delete l; + } + + QString s = "2""%1"; + s = s.arg( conn.signal ); + QString s2 = "1""%1"; + s2 = s2.arg( conn.slot ); + + QStrList signalList = sender->metaObject()->signalNames( TRUE ); + QStrList slotList = receiver->metaObject()->slotNames( TRUE ); + + // if this is a connection to a custom slot and we have a connector, try this as receiver + if ( slotList.find( conn.slot ) == -1 && receiver == toplevel && connector ) { + slotList = connector->metaObject()->slotNames( TRUE ); + receiver = connector; + } + + // avoid warnings + if ( signalList.find( conn.signal ) == -1 || + slotList.find( conn.slot ) == -1 ) { + n = n.nextSibling().toElement(); + continue; + } + QObject::connect( sender, s, receiver, s2 ); + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::loadTabOrder( const QDomElement &e ) +{ + QWidget *last = 0; + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "tabstop" ) { + QString name = n.firstChild().toText().data(); + QObjectList *l = toplevel->queryList( 0, name, FALSE ); + if ( l ) { + if ( l->first() ) { + QWidget *w = (QWidget*)l->first(); + if ( last ) + toplevel->setTabOrder( last, w ); + last = w; + } + delete l; + } + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::createListViewColumn( QListView *lv, const QString& txt, + const QPixmap& pix, bool clickable, + bool resizable ) +{ + if ( pix.isNull() ) { + lv->addColumn( txt ); + } else { + lv->addColumn( pix, txt ); + } + + int i = lv->header()->count() - 1; + if ( !pix.isNull() ) + lv->header()->setLabel( i, pix, txt ); + if ( !clickable ) + lv->header()->setClickEnabled( clickable, i ); + if ( !resizable ) + lv->header()->setResizeEnabled( resizable, i ); +} + +#ifndef QT_NO_TABLE +void QWidgetFactory::createTableColumnOrRow( QTable *table, const QString& txt, + const QPixmap& pix, + const QString& field, bool isRow ) +{ +#ifndef QT_NO_SQL + bool isSql = table->inherits( "QDataTable" ); +#endif + if ( isRow ) + table->setNumRows( table->numRows() + 1 ); + else { +#ifndef QT_NO_SQL + if ( !isSql ) +#endif + table->setNumCols( table->numCols() + 1 ); + } + + QValueList fieldMap; + if ( fieldMaps.find( table ) != fieldMaps.end() ) { + fieldMap = *fieldMaps.find( table ); + fieldMaps.remove( table ); + } + + int i = isRow ? table->numRows() - 1 : table->numCols() - 1; + QHeader *h = !isRow ? table->horizontalHeader() : table->verticalHeader(); + if ( !pix.isNull() ) { +#ifndef QT_NO_SQL + if ( isSql ) + ((QDataTable*)table)->addColumn( field, txt, -1, pix ); + else +#endif + h->setLabel( i, pix, txt ); + } else { +#ifndef QT_NO_SQL + if ( isSql ) + ((QDataTable*)table)->addColumn( field, txt ); + else +#endif + h->setLabel( i, txt ); + } + if ( !isRow && !field.isEmpty() ) { + fieldMap.append( Field( txt, pix, field ) ); + fieldMaps.insert( table, fieldMap ); + } + +} +#endif + +void QWidgetFactory::createColumn( const QDomElement &e, QWidget *widget ) +{ + if ( widget->inherits( "QListView" ) && e.tagName() == "column" ) { + QListView *lv = (QListView*)widget; + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + QString txt; + bool clickable = TRUE, resizable = TRUE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + txt = translate( v.toString() ); + else if ( attrib == "pixmap" ) + pix = loadPixmap( n.firstChild().toElement().toElement() ); + else if ( attrib == "clickable" ) + clickable = v.toBool(); + else if ( attrib == "resizable" || attrib == "resizeable" ) + resizable = v.toBool(); + } + n = n.nextSibling().toElement(); + } + createListViewColumn( lv, txt, pix, clickable, resizable ); + } +#ifndef QT_NO_TABLE + else if ( widget->inherits( "QTable" ) ) { + QTable *table = (QTable*)widget; + + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + QString txt; + QString field; + + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + txt = translate( v.toString() ); + else if ( attrib == "pixmap" ) { + if ( !n.firstChild().firstChild().toText().data().isEmpty() ) + pix = loadPixmap( n.firstChild().toElement().toElement() ); + } else if ( attrib == "field" ) + field = translate( v.toString() ); + } + n = n.nextSibling().toElement(); + } + createTableColumnOrRow( table, txt, pix, field, e.tagName() == "row" ); + } +#endif +} + +void QWidgetFactory::loadItem( const QDomElement &e, QPixmap &pix, QString &txt, bool &hasPixmap ) +{ + QDomElement n = e; + hasPixmap = FALSE; + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + txt = translate( v.toString() ); + else if ( attrib == "pixmap" ) { + pix = loadPixmap( n.firstChild().toElement() ); + hasPixmap = !pix.isNull(); + } + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::createItem( const QDomElement &e, QWidget *widget, QListViewItem *i ) +{ + if ( widget->inherits( "QListBox" ) || widget->inherits( "QComboBox" ) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + loadItem( n, pix, txt, hasPixmap ); + QListBox *lb = 0; + if ( widget->inherits( "QListBox" ) ) { + lb = (QListBox*)widget; + } else { + QComboBox *cb = (QComboBox*)widget; + lb = cb->listBox(); + if (!lb) { + lb = new QListBox(cb); + cb->setListBox(lb); + } + } + if ( hasPixmap ) { + new QListBoxPixmap( lb, pix, txt ); + } else { + new QListBoxText( lb, txt ); + } +#ifndef QT_NO_ICONVIEW + } else if ( widget->inherits( "QIconView" ) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + bool hasPixmap = FALSE; + QString txt; + loadItem( n, pix, txt, hasPixmap ); + + QIconView *iv = (QIconView*)widget; + new QIconViewItem( iv, txt, pix ); +#endif + } else if ( widget->inherits( "QListView" ) ) { + QDomElement n = e.firstChild().toElement(); + QPixmap pix; + QValueList pixmaps; + QStringList textes; + QListViewItem *item = 0; + QListView *lv = (QListView*)widget; + if ( i ) + item = new QListViewItem( i, d->lastItem ); + else + item = new QListViewItem( lv, d->lastItem ); + while ( !n.isNull() ) { + if ( n.tagName() == "property" ) { + QString attrib = n.attribute( "name" ); + QVariant v = DomTool::elementToVariant( n.firstChild().toElement(), QVariant() ); + if ( attrib == "text" ) + textes << translate( v.toString() ); + else if ( attrib == "pixmap" ) { + QString s = v.toString(); + if ( s.isEmpty() ) { + pixmaps << QPixmap(); + } else { + pix = loadPixmap( n.firstChild().toElement() ); + pixmaps << pix; + } + } + } else if ( n.tagName() == "item" ) { + item->setOpen( TRUE ); + createItem( n, widget, item ); + } + + n = n.nextSibling().toElement(); + } + + for ( int i = 0; i < lv->columns(); ++i ) { + item->setText( i, textes[ i ] ); + item->setPixmap( i, pixmaps[ i ] ); + } + d->lastItem = item; + } +} + + + +void QWidgetFactory::loadChildAction( QObject *parent, const QDomElement &e ) +{ + QDomElement n = e; + QAction *a = 0; + bool hasMenuText = FALSE; + if ( n.tagName() == "action" ) { + a = new QAction( parent ); + QDomElement n2 = n.firstChild().toElement(); + + while ( !n2.isNull() ) { + if ( n2.tagName() == "property" ) { + QString prop(n2.attribute("name")); + if (prop == "menuText") + hasMenuText = TRUE; + setProperty( a, prop, n2.firstChild().toElement() ); + } + n2 = n2.nextSibling().toElement(); + } + if ( !parent->inherits( "QAction" ) ) + actionList.append( a ); + } else if ( n.tagName() == "actiongroup" ) { + a = new QActionGroup( parent ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "property" ) { + QString prop(n2.attribute("name")); + if (prop == "menuText") + hasMenuText = TRUE; + setProperty( a, prop, n2.firstChild().toElement() ); + } else if ( n2.tagName() == "action" || + n2.tagName() == "actiongroup" ) { + loadChildAction( a, n2 ); + + } + n2 = n2.nextSibling().toElement(); + } + if ( !parent->inherits( "QAction" ) ) + actionList.append( a ); + } + + if (a && !hasMenuText && !a->text().isEmpty() && uiFileVersion < "3.3") + a->setMenuText(a->text()); +} + +void QWidgetFactory::loadActions( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "action" ) { + loadChildAction( toplevel, n ); + } else if ( n.tagName() == "actiongroup" ) { + loadChildAction( toplevel, n ); + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::loadToolBars( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + QMainWindow *mw = ( (QMainWindow*)toplevel ); + QToolBar *tb = 0; + while ( !n.isNull() ) { + if ( n.tagName() == "toolbar" ) { + Qt::Dock dock = (Qt::Dock)n.attribute( "dock" ).toInt(); + tb = new QToolBar( QString::null, mw, dock ); + tb->setLabel( n.attribute( "label" ) ); + tb->setName( n.attribute( "name" ) ); + QDomElement n2 = n.firstChild().toElement(); + while ( !n2.isNull() ) { + if ( n2.tagName() == "action" ) { + QAction *a = findAction( n2.attribute( "name" ) ); + if ( a ) + a->addTo( tb ); + } else if ( n2.tagName() == "separator" ) { + tb->addSeparator(); + } else if ( n2.tagName() == "widget" ) { + (void)createWidgetInternal( n2, tb, 0, n2.attribute( "class", "QWidget" ) ); + } else if ( n2.tagName() == "property" ) { + setProperty( tb, n2.attribute( "name" ), n2.firstChild().toElement() ); + } + n2 = n2.nextSibling().toElement(); + } + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::loadMenuBar( const QDomElement &e ) +{ + QDomElement n = e.firstChild().toElement(); + QMainWindow *mw = ( (QMainWindow*)toplevel ); + QMenuBar *mb = mw->menuBar(); + while ( !n.isNull() ) { + if ( n.tagName() == "item" ) { + QPopupMenu *popup = new QPopupMenu( mw ); + loadPopupMenu( popup, n ); + popup->setName( n.attribute( "name" ) ); + mb->insertItem( translate( n.attribute( "text" ) ), popup ); + } else if ( n.tagName() == "property" ) { + setProperty( mb, n.attribute( "name" ), n.firstChild().toElement() ); + } else if ( n.tagName() == "separator" ) { + mb->insertSeparator(); + } + n = n.nextSibling().toElement(); + } +} + +void QWidgetFactory::loadPopupMenu( QPopupMenu *p, const QDomElement &e ) +{ + QMainWindow *mw = ( (QMainWindow*)toplevel ); + QDomElement n = e.firstChild().toElement(); + while ( !n.isNull() ) { + if ( n.tagName() == "action" || n.tagName() == "actiongroup" ) { + QAction *a = findAction( n.attribute( "name" ) ); + QDomElement n2 = n.nextSibling().toElement(); + if ( n2.tagName() == "item") { // load submenu + QPopupMenu *popup = new QPopupMenu( mw ); + popup->setName( n2.attribute( "name" ) ); + if ( a ) { + p->setAccel( a->accel(), p->insertItem( a->iconSet(), + translate( n2.attribute( "text" ).utf8().data() ), + popup ) ); + } else { + p->insertItem( translate( n2.attribute( "text" ).utf8().data() ), popup ); + } + loadPopupMenu( popup, n2 ); + n = n2; + } else { + if ( a ) { + a->addTo( p ); + } + } + a = 0; + } else if ( n.tagName() == "separator" ) { + p->insertSeparator(); + } + n = n.nextSibling().toElement(); + } +} + +// compatibility with early 3.0 betas +// ### remove for 4.0 +void QWidgetFactory::loadFunctions( const QDomElement & ) +{ +} + +QAction *QWidgetFactory::findAction( const QString &name ) +{ + for ( QAction *a = actionList.first(); a; a = actionList.next() ) { + if ( QString( a->name() ) == name ) + return a; + QAction *ac = (QAction*)a->child( name.latin1(), "QAction" ); + if ( ac ) + return ac; + } + return 0; +} + +/*! + If you use a pixmap collection (which is the default for new + projects) rather than saving the pixmaps within the .ui XML file, + you must load the pixmap collection. QWidgetFactory looks in the + default QMimeSourceFactory for the pixmaps. Either add it there + manually, or call this function and specify the directory where + the images can be found, as \a dir. This is normally the + directory called \c images in the project's directory. +*/ + +void QWidgetFactory::loadImages( const QString &dir ) +{ + QDir d( dir ); + QStringList l = d.entryList( QDir::Files ); + for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) + QMimeSourceFactory::defaultFactory()->setPixmap( *it, QPixmap( d.path() + "/" + *it, "PNG" ) ); + +} + +void QWidgetFactory::loadExtraSource() +{ + if ( !qwf_language || !languageInterfaceManager ) + return; + QString lang = *qwf_language; + LanguageInterface *iface = 0; + languageInterfaceManager->queryInterface( lang, &iface ); + if ( !iface ) + return; + QFile f( qwf_currFileName + iface->formCodeExtension() ); + if ( f.open( IO_ReadOnly ) ) { + QTextStream ts( &f ); + code = ts.read(); + } +} + +QString QWidgetFactory::translate( const QString& sourceText, const QString& comment ) +{ + return qApp->translate( d->translationContext, sourceText.utf8(), comment.utf8(), + QApplication::UnicodeUTF8 ); +} + +QString QWidgetFactory::translate( const char *sourceText, const char *comment ) +{ + return qApp->translate( d->translationContext, sourceText, comment, + QApplication::UnicodeUTF8 ); +} diff --git a/tools/designer/uilib/qwidgetfactory.h b/tools/designer/uilib/qwidgetfactory.h new file mode 100644 index 0000000..daf5db6 --- /dev/null +++ b/tools/designer/uilib/qwidgetfactory.h @@ -0,0 +1,187 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QWIDGETFACTORY_H +#define QWIDGETFACTORY_H + +#ifndef QT_H +#include +#include +#include +#include +#include +#include +#include +#endif // QT_H + +class QDomDocument; +class QDomElement; +class QLayout; +class QListView; +class QListViewItem; +class QMenuBar; +class QTable; +class QWidget; +class QWidgetFactoryPrivate; +class UibStrTable; + +class QWidgetFactory +{ +public: + QWidgetFactory(); + virtual ~QWidgetFactory(); + + static QWidget *create( const QString &uiFile, QObject *connector = 0, QWidget *parent = 0, const char *name = 0 ); + static QWidget *create( QIODevice *dev, QObject *connector = 0, QWidget *parent = 0, const char *name = 0 ); + static void addWidgetFactory( QWidgetFactory *factory ); + static void loadImages( const QString &dir ); + + virtual QWidget *createWidget( const QString &className, QWidget *parent, const char *name ) const; + static QStringList widgets(); + static bool supportsWidget( const QString &widget ); + +private: + enum LayoutType { HBox, VBox, Grid, NoLayout }; + void loadImageCollection( const QDomElement &e ); + void loadConnections( const QDomElement &e, QObject *connector ); + void loadTabOrder( const QDomElement &e ); + QWidget *createWidgetInternal( const QDomElement &e, QWidget *parent, QLayout* layout, const QString &classNameArg ); + QLayout *createLayout( QWidget *widget, QLayout* layout, LayoutType type, bool isQLayoutWidget = FALSE ); + LayoutType layoutType( QLayout *l ) const; + void setProperty( QObject* widget, const QString &prop, QVariant value ); + void setProperty( QObject* widget, const QString &prop, const QDomElement &e ); + void createSpacer( const QDomElement &e, QLayout *layout ); + QImage loadFromCollection( const QString &name ); + QPixmap loadPixmap( const QString &name ); + QPixmap loadPixmap( const QDomElement &e ); + QColorGroup loadColorGroup( const QDomElement &e ); + void createListViewColumn( QListView *lv, const QString& txt, + const QPixmap& pix, bool clickable, + bool resizable ); +#ifndef QT_NO_TABLE + void createTableColumnOrRow( QTable *table, const QString& txt, + const QPixmap& pix, const QString& field, + bool isRow ); +#endif + void createColumn( const QDomElement &e, QWidget *widget ); + void loadItem( const QDomElement &e, QPixmap &pix, QString &txt, bool &hasPixmap ); + void createItem( const QDomElement &e, QWidget *widget, QListViewItem *i = 0 ); + void loadChildAction( QObject *parent, const QDomElement &e ); + void loadActions( const QDomElement &e ); + void loadToolBars( const QDomElement &e ); + void loadMenuBar( const QDomElement &e ); + void loadPopupMenu( QPopupMenu *p, const QDomElement &e ); + void loadFunctions( const QDomElement &e ); + QAction *findAction( const QString &name ); + void loadExtraSource(); + QString translate( const char *sourceText, const char *comment = "" ); + QString translate( const QString& sourceText, const QString& comment = QString::null ); + + void unpackUInt16( QDataStream& in, Q_UINT16& n ); + void unpackUInt32( QDataStream& in, Q_UINT32& n ); + void unpackByteArray( QDataStream& in, QByteArray& array ); + void unpackCString( const UibStrTable& strings, QDataStream& in, + QCString& cstr ); + void unpackString( const UibStrTable& strings, QDataStream& in, + QString& str ); + void unpackStringSplit( const UibStrTable& strings, QDataStream& in, + QString& str ); + void unpackVariant( const UibStrTable& strings, QDataStream& in, + QVariant& value ); + void inputSpacer( const UibStrTable& strings, QDataStream& in, + QLayout *parent ); + void inputColumnOrRow( const UibStrTable& strings, QDataStream& in, + QObject *parent, bool isRow ); + void inputItem( const UibStrTable& strings, QDataStream& in, + QObject *parent, QListViewItem *parentItem = 0 ); + void inputMenuItem( QObject **objects, const UibStrTable& strings, + QDataStream& in, QMenuBar *menuBar ); + QObject *inputObject( QObject **objects, int& numObjects, + const UibStrTable& strings, QDataStream& in, + QWidget *ancestorWidget, QObject *parent, + QCString className = "" ); + QWidget *createFromUiFile( QDomDocument doc, QObject *connector, + QWidget *parent, const char *name ); + QWidget *createFromUibFile( QDataStream& in, QObject *connector, + QWidget *parent, const char *name ); + +private: + struct Image { + QImage img; + QString name; + bool operator==( const Image &i ) const { + return ( i.name == name && + i.img == img ); + } + }; + + struct Field + { + Field() {} + Field( const QString &s1, const QPixmap &p, const QString &s2 ) : name( s1 ), pix( p ), field( s2 ) {} + QString name; + QPixmap pix; + QString field; + Q_DUMMY_COMPARISON_OPERATOR( Field ) + }; + + struct SqlWidgetConnection + { + SqlWidgetConnection() {} + SqlWidgetConnection( const QString &c, const QString &t ) + : conn( c ), table( t ), dbControls( new QMap() ) {} + QString conn; + QString table; + QMap *dbControls; + Q_DUMMY_COMPARISON_OPERATOR( SqlWidgetConnection ) + }; + + QValueList images; + QWidget *toplevel; + QWidgetFactoryPrivate *d; + QMap *dbControls; + QMap dbTables; + QMap sqlWidgetConnections; + QMap buddies; + QMap > fieldMaps; + QPtrList actionList; + QMap languageSlots; + QStringList noDatabaseWidgets; + bool usePixmapCollection; + int defMargin; + int defSpacing; + QString code; + QString uiFileVersion; +}; + +#endif diff --git a/tools/designer/uilib/test/main.cpp b/tools/designer/uilib/test/main.cpp new file mode 100644 index 0000000..f5f0559 --- /dev/null +++ b/tools/designer/uilib/test/main.cpp @@ -0,0 +1,50 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt GUI Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include "../qwidgetfactory.h" + +int main( int argc, char ** argv ) +{ + QApplication a( argc, argv ); + if ( argc == 1 ) + return 0; + if ( argc == 3 ) + QWidgetFactory::loadImages( argv[ 2 ] ); + QWidget *w = QWidgetFactory::create( argv[ 1 ] ); + if ( !w ) + return 0; + w->show(); + a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) ); + return a.exec(); +} diff --git a/tools/designer/uilib/test/test.pro b/tools/designer/uilib/test/test.pro new file mode 100644 index 0000000..b2459c0 --- /dev/null +++ b/tools/designer/uilib/test/test.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +CONFIG += qt warn_on release +HEADERS = +SOURCES = main.cpp +TARGET = test +LIBS += -L$$QT_BUILD_TREE/lib -lqui + diff --git a/tools/designer/uilib/uilib.pro b/tools/designer/uilib/uilib.pro new file mode 100644 index 0000000..bf98d7b --- /dev/null +++ b/tools/designer/uilib/uilib.pro @@ -0,0 +1,30 @@ +TEMPLATE = lib +CONFIG += qt warn_on release +win32:CONFIG += static +win32:CONFIG -= dll +SOURCES = qwidgetfactory.cpp \ + ../shared/domtool.cpp \ + ../shared/uib.cpp + +HEADERS = ../shared/domtool.h \ + ../shared/uib.h + +sql:SOURCES += ../designer/database.cpp +sql:HEADERS += ../designer/database2.h + +DEFINES += QT_INTERNAL_XML +!win32-borland:DEFINES += Q_TEMPLATE_EXTERN=extern +include( ../../../src/qt_professional.pri ) +TARGET = qui +INCLUDEPATH += ../shared +DESTDIR = ../../../lib +VERSION = 1.0.0 +DEFINES += RESOURCE + +unix { + target.path=$$libs.path + + INSTALLS += target +} + +mac:QMAKE_LFLAGS_PREBIND = -prebind -seg1addr 0xB9000000 diff --git a/tools/linguist/LICENSE.GPL b/tools/linguist/LICENSE.GPL new file mode 100644 index 0000000..3221c03 --- /dev/null +++ b/tools/linguist/LICENSE.GPL @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/tools/linguist/book/images/doneandnext.png b/tools/linguist/book/images/doneandnext.png new file mode 100644 index 0000000..47efaec Binary files /dev/null and b/tools/linguist/book/images/doneandnext.png differ diff --git a/tools/linguist/book/images/editcopy.png b/tools/linguist/book/images/editcopy.png new file mode 100644 index 0000000..efe8d03 Binary files /dev/null and b/tools/linguist/book/images/editcopy.png differ diff --git a/tools/linguist/book/images/editcut.png b/tools/linguist/book/images/editcut.png new file mode 100644 index 0000000..146388a Binary files /dev/null and b/tools/linguist/book/images/editcut.png differ diff --git a/tools/linguist/book/images/editfind.png b/tools/linguist/book/images/editfind.png new file mode 100644 index 0000000..59c63bf Binary files /dev/null and b/tools/linguist/book/images/editfind.png differ diff --git a/tools/linguist/book/images/editpaste.png b/tools/linguist/book/images/editpaste.png new file mode 100644 index 0000000..13f9a0f Binary files /dev/null and b/tools/linguist/book/images/editpaste.png differ diff --git a/tools/linguist/book/images/editredo.png b/tools/linguist/book/images/editredo.png new file mode 100644 index 0000000..6a30e26 Binary files /dev/null and b/tools/linguist/book/images/editredo.png differ diff --git a/tools/linguist/book/images/editundo.png b/tools/linguist/book/images/editundo.png new file mode 100644 index 0000000..38a7357 Binary files /dev/null and b/tools/linguist/book/images/editundo.png differ diff --git a/tools/linguist/book/images/fileopen.png b/tools/linguist/book/images/fileopen.png new file mode 100644 index 0000000..44107d3 Binary files /dev/null and b/tools/linguist/book/images/fileopen.png differ diff --git a/tools/linguist/book/images/fileprint.png b/tools/linguist/book/images/fileprint.png new file mode 100644 index 0000000..2936658 Binary files /dev/null and b/tools/linguist/book/images/fileprint.png differ diff --git a/tools/linguist/book/images/filesave.png b/tools/linguist/book/images/filesave.png new file mode 100644 index 0000000..03e10f9 Binary files /dev/null and b/tools/linguist/book/images/filesave.png differ diff --git a/tools/linguist/book/images/finddialog.png b/tools/linguist/book/images/finddialog.png new file mode 100644 index 0000000..c3b0f43 Binary files /dev/null and b/tools/linguist/book/images/finddialog.png differ diff --git a/tools/linguist/book/images/linguist.png b/tools/linguist/book/images/linguist.png new file mode 100644 index 0000000..519c185 Binary files /dev/null and b/tools/linguist/book/images/linguist.png differ diff --git a/tools/linguist/book/images/menubar.png b/tools/linguist/book/images/menubar.png new file mode 100644 index 0000000..7ba43c6 Binary files /dev/null and b/tools/linguist/book/images/menubar.png differ diff --git a/tools/linguist/book/images/next.png b/tools/linguist/book/images/next.png new file mode 100644 index 0000000..7434fa2 Binary files /dev/null and b/tools/linguist/book/images/next.png differ diff --git a/tools/linguist/book/images/nextunfinished.png b/tools/linguist/book/images/nextunfinished.png new file mode 100644 index 0000000..618fc94 Binary files /dev/null and b/tools/linguist/book/images/nextunfinished.png differ diff --git a/tools/linguist/book/images/phrasebookdialog.png b/tools/linguist/book/images/phrasebookdialog.png new file mode 100644 index 0000000..d1a323a Binary files /dev/null and b/tools/linguist/book/images/phrasebookdialog.png differ diff --git a/tools/linguist/book/images/phrasebookopen.png b/tools/linguist/book/images/phrasebookopen.png new file mode 100644 index 0000000..4f76b7d Binary files /dev/null and b/tools/linguist/book/images/phrasebookopen.png differ diff --git a/tools/linguist/book/images/prev.png b/tools/linguist/book/images/prev.png new file mode 100644 index 0000000..f9fbd93 Binary files /dev/null and b/tools/linguist/book/images/prev.png differ diff --git a/tools/linguist/book/images/prevunfinished.png b/tools/linguist/book/images/prevunfinished.png new file mode 100644 index 0000000..25cc1a2 Binary files /dev/null and b/tools/linguist/book/images/prevunfinished.png differ diff --git a/tools/linguist/book/images/toolbar.png b/tools/linguist/book/images/toolbar.png new file mode 100644 index 0000000..5e6021f Binary files /dev/null and b/tools/linguist/book/images/toolbar.png differ diff --git a/tools/linguist/book/images/tt1_en.png b/tools/linguist/book/images/tt1_en.png new file mode 100644 index 0000000..66e54e0 Binary files /dev/null and b/tools/linguist/book/images/tt1_en.png differ diff --git a/tools/linguist/book/images/tt1_la.png b/tools/linguist/book/images/tt1_la.png new file mode 100644 index 0000000..a701349 Binary files /dev/null and b/tools/linguist/book/images/tt1_la.png differ diff --git a/tools/linguist/book/images/tt2_en.png b/tools/linguist/book/images/tt2_en.png new file mode 100644 index 0000000..c71e201 Binary files /dev/null and b/tools/linguist/book/images/tt2_en.png differ diff --git a/tools/linguist/book/images/tt2_fr.png b/tools/linguist/book/images/tt2_fr.png new file mode 100644 index 0000000..acc2515 Binary files /dev/null and b/tools/linguist/book/images/tt2_fr.png differ diff --git a/tools/linguist/book/images/tt2_nl.png b/tools/linguist/book/images/tt2_nl.png new file mode 100644 index 0000000..4631de2 Binary files /dev/null and b/tools/linguist/book/images/tt2_nl.png differ diff --git a/tools/linguist/book/images/tt3_10_en.png b/tools/linguist/book/images/tt3_10_en.png new file mode 100644 index 0000000..e95bff9 Binary files /dev/null and b/tools/linguist/book/images/tt3_10_en.png differ diff --git a/tools/linguist/book/images/tt3_10_pt_bad.png b/tools/linguist/book/images/tt3_10_pt_bad.png new file mode 100644 index 0000000..05cb5f3 Binary files /dev/null and b/tools/linguist/book/images/tt3_10_pt_bad.png differ diff --git a/tools/linguist/book/images/tt3_10_pt_good.png b/tools/linguist/book/images/tt3_10_pt_good.png new file mode 100644 index 0000000..b0f855f Binary files /dev/null and b/tools/linguist/book/images/tt3_10_pt_good.png differ diff --git a/tools/linguist/book/images/tt3_11_about_pt.png b/tools/linguist/book/images/tt3_11_about_pt.png new file mode 100644 index 0000000..4467314 Binary files /dev/null and b/tools/linguist/book/images/tt3_11_about_pt.png differ diff --git a/tools/linguist/book/images/tt3_11_en.png b/tools/linguist/book/images/tt3_11_en.png new file mode 100644 index 0000000..7d98b98 Binary files /dev/null and b/tools/linguist/book/images/tt3_11_en.png differ diff --git a/tools/linguist/book/images/tt3_11_pt.png b/tools/linguist/book/images/tt3_11_pt.png new file mode 100644 index 0000000..02910cf Binary files /dev/null and b/tools/linguist/book/images/tt3_11_pt.png differ diff --git a/tools/linguist/book/images/validateaccelerators.png b/tools/linguist/book/images/validateaccelerators.png new file mode 100644 index 0000000..68201fe Binary files /dev/null and b/tools/linguist/book/images/validateaccelerators.png differ diff --git a/tools/linguist/book/images/validatephrases.png b/tools/linguist/book/images/validatephrases.png new file mode 100644 index 0000000..62fe5f2 Binary files /dev/null and b/tools/linguist/book/images/validatephrases.png differ diff --git a/tools/linguist/book/images/validatepunctuation.png b/tools/linguist/book/images/validatepunctuation.png new file mode 100644 index 0000000..8ce2648 Binary files /dev/null and b/tools/linguist/book/images/validatepunctuation.png differ diff --git a/tools/linguist/book/linguist-manager.leaf b/tools/linguist/book/linguist-manager.leaf new file mode 100644 index 0000000..aa99e01 --- /dev/null +++ b/tools/linguist/book/linguist-manager.leaf @@ -0,0 +1,138 @@ +\chapter Release Manager + +\index Release Manager + +Two tools are provided for the release manager, \l lupdate and \l +lrelease. These tools depend on \e qmake project files. You don't +have to use \e qmake, though. + +A third tool, \c qm2ts, can be used for converting Qt 2.x message +files to \c .ts files. + +\section1 Qt Project Files + +\index .pro Files +\index Project Files +\index qmake!Project Files + +\l lupdate and \l lrelease depend on information in the application's +\c .pro Qt project file. There must be an entry in the \c TRANSLATIONS +section of the project file for each language that is additional to +the native language. A typical entry looks like this: + +\index TRANSLATIONS!in Project Files + +\quotefile tt2/tt2.pro +\skipto TRANSLATIONS +\printline tt2_fr +\printline tt2_nl + +Using a locale within the translation file name is useful for +determining which language to load at runtime. This is explained in +\link Programmers Chapter 4: Programmers \endlink. + +\index HEADERS!in Project Files +\index SOURCES!in Project Files +\index FORMS!in Project Files +\index TRANSLATIONS!in Project Files + +An example of a complete \c .pro file with four translation source files: +\code + HEADERS = main-dlg.h \ + options-dlg.h + SOURCES = main-dlg.cpp \ + options-dlg.cpp \ + main.cpp + FORMS = search-dlg.ui + TRANSLATIONS = superapp_dk.ts \ + superapp_fi.ts \ + superapp_no.ts \ + superapp_se.ts +\endcode + +\index QApplication!defaultCodec() +\index defaultCodec()!QApplication +\index DEFAULTCODEC!in Project Files +\index Chinese Language +\index Japanese Language + +\l QTextCodec::setCodecForTr() makes it possible to choose a +8-bit encoding for literal strings that appear within \c tr() calls. +This is useful for applications whose source language is, for example, +Chinese or Japanese. If no encoding is set, \c tr() uses Latin-1. + +If you do use the \l QTextCodec::codecForTr() mechanism in your +application, \e {Qt Linguist} needs you to set the \c DEFAULTCODEC +entry in the \c .pro file as well. For example: +\code + DEFAULTCODEC = ISO-8859-5 +\endcode + +\section1 lupdate + +\index lupdate + +Usage: \c {lupdate myproject.pro} + + \index Qt Designer + +This is a simple command line tool. \l lupdate reads a Qt \c .pro +project file, finds the translatable strings in the specified source, +header and \e {Qt Designer} interface files, and produces or updates +the \c .ts translation files listed in the project file. The +translation files are given to the translator who uses \e {Qt +Linguist} to read the files and insert the translations. + +Companies that have their own translators in-house may find it useful +to run \l lupdate regularly, perhaps monthly, as the application +develops. This will lead to a fairly low volume of translation work +spread evenly over the life of the project and will allow the +translators to support a number of projects simultaneously. + +Companies that hire in translators as required may prefer to run \l +lupdate only a few times in the application's life cycle, the first +time might be just before the first test phase. This will provide the +translator with a substantial single block of work and any bugs that +the translator detects may easily be included with those found during +the initial test phase. The second and any subsequent \l lupdate runs +would probably take place during the final beta phase. + +\index .ts Files +\index Translation Source Files +\index XML + +The \c .ts file format is a simple human-readable XML format that can +be used with version control systems if required. + +\section1 lrelease + +\index lrelease + +Usage: \c {lrelease myproject.pro} + +\index .qm Files +\index Qt Message Files + +This is another simple command line tool. It reads a Qt \c .pro +project file and produces the \c .qm files used by the application, +one for each \c .ts translation source file listed in the project +file. The \c .qm file format is a compact binary format that provides +extremely fast lookups for translations. + +This tool is run whenever a release of the application is to be made, +from initial test version through to final release version. If the \c +.qm files are not created, e.g. because an alpha release is required +before any translation has been undertaken, the application will run +perfectly well using the text the programmers placed in the source +files. Once the \c .qm files are available the application will +detect them and use them automatically. + +Note that \l lrelease will only incorporate translations that are +marked as "done". If a translation is missing, or has failed +validation, the original text will be used instead. + +\section1 Missing Translations + +Both \l lupdate and \l lrelease may be used with \c .ts translation +source files which are incomplete. Missing translations will be replaced +with the native language phrases at runtime. diff --git a/tools/linguist/book/linguist-manual.book b/tools/linguist/book/linguist-manual.book new file mode 100644 index 0000000..b98cd9b --- /dev/null +++ b/tools/linguist/book/linguist-manual.book @@ -0,0 +1,90 @@ +\title Guide to the Qt Translation Tools +\granularity chapter + +\chapter Introduction + +Qt provides excellent support for translating applications into local +languages. This Guide explains how to use Qt's translation tools for +each of the roles involved in translating an application. The Guide +begins with a brief overview of the issues that must be considered, +followed by chapters devoted to each role and the supporting tools +provided. + +\link Release... Chapter 2: Release Manager \endlink is aimed at the +person with overall responsibility for the release of the +application. They will typically coordinate the work of the software +engineers and the translator. The chapter describes the use of two +tools. The \l lupdate tool is used to synchronize source code and +translations. The \l lrelease tool is used to create runtime +translation files for use by the released application. + +\link Translators Chapter 3: Translators \endlink is for translators. +It describes the use of the \e {Qt Linguist} tool. No computer +knowledge beyond the ability to start a program and use a text editor +or word processor is required. + +\link Programmers Chapter 4: Programmers \endlink is for Qt +programmers. It explains how to create Qt applications that are able +to use translated text. It also provides guidance on how to help the +translator identify the context in which phrases appear. This +chapter's three short tutorials cover everything the programmer needs +to do. + +\section1 Overview of the Translation Process + +Most of the text that must be translated in an application program +consists of either single words or short phrases. These typically +appear as window titles, menu items, pop-up help text (balloon help), +and labels to buttons, check boxes and radio buttons. + +The phrases are entered into the source code by the programmer in +their native language using a simple but special syntax to identify +that the phrases require translation. The Qt tools provide context +information for each of the phrases to help the translator, and the +programmer is able to add additional context information to phrases +when necessary. The release manager generates a set of translation +files that are produced from the source files and passes these to the +translator. The translator opens the translation files using \e {Qt +Linguist}, enters their translations and saves the results back into +the translation files, which they pass back to the release manager. +The release manager then generates fast compact versions of these +translation files ready for use by the application. The tools are +designed to be used in repeated cycles as applications change and +evolve, preserving existing translations and making it easy to +identify which new translations are required. \e {Qt Linguist} also +provides a phrase book facility to help ensure consistent +translations across multiple applications and projects. + +Translators and programmers must address a number of issues because +of the subtleties and complexities of human language: + +\list +\i A single phrase may need to be translated into several different +forms depending on context, e.g. \e open in English might become \e +\OEFFNEN, "open file", or \e aufbauen, "open internet connection", in +German. +\i Keyboard accelerators may need to be changed but without +introducing conflicts, e.g. "\&Quit" in English becomes "Avslutt" in +Norwegian which doesn't contain a "Q". We cannot use a letter that is +already in use -- unless we change several accelerators. +\i Phrases that contain variables, for example, "The 25 files selected will +take 63 seconds to process", where the two numbers are inserted +programmatically at runtime may need to be reworded because in a +different language the word order and therefore the placement of the +variables may have to change. +\endlist + +The Qt translation tools provide clear and simple solutions to these +issues. + +\RULE + +Please send comments and suggestions regarding this tutorial to the +\link mailto:doc@trolltech.com?subject=Translation_Tutorial Qt doc +team \endlink. Bugs in the tools should be sent to \link +mailto:qt-bugs@trolltech.com?subject=Translation_Tutorial +qt-bugs\endlink. + +\input linguist-manager.leaf +\input linguist-translator.leaf +\input linguist-programmer.leaf diff --git a/tools/linguist/book/linguist-programmer.leaf b/tools/linguist/book/linguist-programmer.leaf new file mode 100644 index 0000000..d2a079b --- /dev/null +++ b/tools/linguist/book/linguist-programmer.leaf @@ -0,0 +1,1145 @@ +\chapter Programmers + +Support for multiple languages is extremely simple in Qt +applications, and adds little overhead to the programmer's workload. + +Qt minimizes the performance cost of using translations by +translating the phrases for each window as they are created. In most +applications the main window is created just once. Dialogs are often +created once and then shown and hidden as required. Once the initial +translation has taken place there is no further runtime overhead for +the translated windows. Only those windows that are created, +destroyed and subsequently created will have a translation +performance cost. + +Creating applications that can switch language at runtime is possible +with Qt, but requires a certain amount of programmer intervention and +will of course incur some runtime performance cost. + +\section1 Making the Application Translation Aware + +Programmers should make their application look for and load the +appropriate translation file and mark user-visible text and Ctrl +keyboard accelerators as targets for translation. + +Each piece of text that requires translating requires context to help +the translator identify where in the program the text occurs. In the +case of multiple identical texts that require different translations, +the translator also requires some information to disambiguate the +source texts. Marking text for translation will automatically cause +the class name to be used as basic context information. In some cases +the programmer may be required to add additional information to help +the translator. + +\section2 Creating Translation Files + +\index .ts Files +\index Translation Source Files + +Translation files consist of all the user-visible text and Ctrl key +accelerators in an application and translations of that text. +Translation files are created as follows: + +\index lupdate +\index lrelease + +\list 1 +\i Run \l lupdate initially to generate the first set of \c .ts +translation source files with all the user-visible text but no +translations. +\i The \c .ts files are given to the translator who adds translations +using \e {Qt Linguist}. \e {Qt Linguist} takes care of any changed +or deleted source text. +\i Run \l lupdate to incorporate any new text added to the +application. \l lupdate synchronizes the user-visible text from the +application with the translations; it does not destroy any data. +\i Steps 2 and 3 are repeated as often as necessary. +\i When a release of the application is needed \l lrelease is run to +read the \c .ts files and produce the \c .qm files used by the +application at runtime. +\endlist + +\index .pro Files +\index Project Files +\index qmake!Project Files + +For \l lupdate to work successfully, it must know which translation +files to produce. The files are simply listed in the application's \c +.pro Qt project file, for example: +\quotefile tt2/tt2.pro +\skipto TRANSLATIONS +\printline TRANSLATIONS +\printline + +See the \link lupdate "lupdate" \endlink and \link lrelease +"lrelease" \endlink sections. + +\section2 Loading Translations + +\quotefile tt1/main.cpp +\skipto main( +\printline main( +\printuntil QApplication + +\index main() + +This is how a simple \c main() function of a Qt application begins. + +\index QTranslator!load() +\index load()!QTranslator +\index QApplication!installTranslator() +\index installTranslator()!QApplication + +\quotefile tt1/main.cpp +\skipto main( +\printline main( +\printuntil app.installTrans + +For a translation-aware application a translator object is created, a +translation is loaded and the translator object installed into the +application. + +\quotefile tt2/main.cpp +\skipto main( +\printline main( +\printuntil app.installTrans + +In production applications a more flexible approach, for example, +loading translations according to locale, might be more appropriate. If +the \c .ts files are all named according to a convention such as +\e appname_locale, e.g. \c tt2_fr, \c tt2_de etc, then the +code above will load the current locale's translation at runtime. + +If there is no translation file for the current locale the application +will fall back to using the original source text. + +\section2 Making the Application Translate User-Visible Strings + +\index tr() +\index QObject!tr() + +User-visible strings are marked as translation targets by wrapping them +in a \c tr() call, for example: +\code + button = new QPushButton( "&Quit", this ); +\endcode + +would become + +\code + button = new QPushButton( tr("&Quit"), this); +\endcode + +\index Q_OBJECT + +All \l QObject subclasses that use the \c Q_OBJECT macro implement +the \c tr() function. + +Although the \c tr() call is normally made directly since it is +usually called as a member function of a \l QObject subclass, in +other cases an explicit class name can be supplied, for example: + +\code + QPushButton::tr("&Quit") +\endcode + +or + +\code + QObject::tr("&Quit") +\endcode + +\section2 Distinguishing Identical Strings That Require Different +Translations + +\index Translation Contexts +\index Contexts!for Translation +\index lupdate + +The \l lupdate program automatically provides a \e context for every +source text. This context is the class name of the class that contains +the \c tr() call. This is sufficient in the vast majority of cases. +Sometimes however, the translator will need further information to +uniquely identify a source text; for example, a dialog that contained +two separate frames, each of which contained an "Enabled" option would +need each identified because in some languages the translation would +differ between the two. This is easily achieved using the +two argument form of the \c tr() call, e.g. + +\code + rbc = new QRadioButton( tr("Enabled", "Color frame"), this ); +\endcode + +and + +\code + rbh = new QRadioButton( tr("Enabled", "Hue frame"), this ); +\endcode + +\index Ctrl Key + +Ctrl key accelerators are also translatable: + +\quotefile tt3/mainwindow.cpp +\skipto quit() +\printline quit() +\printuntil Quit + +It is strongly recommended that the two argument form of \c tr() is used +for Ctrl key accelerators. The second argument is the only clue the +translator has as to the function performed by the accelerator. + +\section2 Helping The Translator With Navigation Information + +\index TRANSLATOR!in Comments +\index Translator Comments +\index Comments!for Translators + +In large complex applications it may be difficult for the translator to +see where a particular source text comes from. This problem can be +solved by adding a comment using the keyword \e TRANSLATOR which +describes the navigation steps to reach the text in question; e.g. + +\code + /* TRANSLATOR FindDialog + + Choose Edit|Find from the menu bar or press Ctrl+F to pop up the + Find dialog. + */ +\endcode + +These comments are particularly useful for widget classes. + +\section2 Coping With C++ Namespaces + +\index Namespaces +\index C++!Namespaces +\index lupdate + +C++ namespaces and the \c {using namespace} statement can confuse +\l lupdate. It will interpret \c MyClass::tr() as meaning just +that, not as \c MyNamespace::MyClass::tr(), even if \c MyClass is +defined in the \c MyNamespace namespace. Runtime translation of +these strings will fail because of that. + +\index TRANSLATOR!in Comments +\index Translator Comments +\index Comments!for Translators + +You can work around this limitation by putting a \e TRANSLATOR +comment at the beginning of the source files that use \c +MyClass::tr(): +\code + /* TRANSLATOR MyNamespace::MyClass */ +\endcode +After the comment, all references to \c MyClass::tr() will be +understood as meaning \c MyNamespace::MyClass::tr(). + +\section2 Translating Text that is Outside of a QObject subclass + +\section3 Using QApplication::translate() + +If the quoted text is not in a member function of a QObject subclass, +use either the tr() function of an appropriate class, or the +QApplication::translate() function directly: + +\code + void some_global_function( LoginWidget *logwid ) + { + QLabel *label = new QLabel( + LoginWidget::tr("Password:"), logwid ); + } + + void same_global_function( LoginWidget *logwid ) + { + QLabel *label = new QLabel( + qApp->translate("LoginWidget", "Password:"), + logwid ); + } +\endcode + +\section3 Using QT_TR_NOOP() and QT_TRANSLATE_NOOP() + +If you need to have translatable text completely outside a function, +there are two macros to help: QT_TR_NOOP() and QT_TRANSLATE_NOOP(). +These macros merely mark the text for extraction by \l{lupdate}. +The macros expand to just the text (without the context). + +Example of QT_TR_NOOP(): +\code + QString FriendlyConversation::greeting( int greet_type ) + { + static const char* greeting_strings[] = { + QT_TR_NOOP( "Hello" ), + QT_TR_NOOP( "Goodbye" ) + }; + return tr( greeting_strings[greet_type] ); + } +\endcode + +Example of QT_TRANSLATE_NOOP(): +\code + static const char* greeting_strings[] = { + QT_TRANSLATE_NOOP( "FriendlyConversation", "Hello" ), + QT_TRANSLATE_NOOP( "FriendlyConversation", "Goodbye" ) + }; + + QString FriendlyConversation::greeting( int greet_type ) + { + return tr( greeting_strings[greet_type] ); + } + + QString global_greeting( int greet_type ) + { + return qApp->translate( "FriendlyConversation", + greeting_strings[greet_type] ); + } +\endcode + +\section1 Tutorials + +Three tutorials are presented. The first demonstrates the creation of +a \l QTranslator object. It also shows the simplest use of the \c +tr() function to mark user-visible source text for translation. The +second tutorial explains how to make the application load the +translation file applicable to the current locale. It also shows the +use of the two-argument form of \c tr() which provides additional +information to the translator. The third tutorial explains how +identical source texts can be distinguished even when they occur in +the same context. This tutorial also discusses how the translation +tools help minimize the translator's work when an application is +upgraded. + +\section2 Tutorial 1: Loading and Using Translations + +\img tt1_en.png +\caption Tutorial 1 Screenshot, English version + +\include tt1/tt1.pro +\caption \c tt1.pro + +\include tt1/main.cpp +\caption \c main.cpp + +This example is a reworking of the \link tutorial1-01.html +"hello-world" \endlink example from \link tutorial.html Tutorial +#1\endlink, with a Latin translation. The \e {Tutorial 1 Screenshot, +English version}, above, shows the English version. + +\quotefile tt1/main.cpp + +\section3 Line by Line Walk-through + +\quotefile tt1/main.cpp + +\skipto qtranslator +\printline qtranslator + +\index QTranslator + +This line includes the definition of the \l QTranslator class. +Objects of this class provide translations for user-visible text. + +\skipto QTranslator +\printuntil tor + +Creates a \l QTranslator object without a parent. + +\printline load + +\index tt1_la.qm + +Tries to load a file called \c tt1_la.qm (the \c .qm file extension is +implicit) that contains Latin translations for the source texts used in +the program. No error will occur if the file is not found. + +\index QApplication!installTranslator() +\index installTranslator()!QApplication + +\printline installTranslator + +Adds the translations from \c tt1_la.qm to the pool of translations used +by the program. + +\index Hello World + +\printline hello + +Creates a push button that displays "Hello world!". If \c tt1_la.qm +was found and contains a translation for "Hello world!", the +translation appears; if not, the source text appears. + +\index tr() +\index QObject!tr() + +All classes that inherit \l QObject have a \c tr() function. Inside +a member function of a \l QObject class, we simply write \c tr("Hello +world!") instead of \c QPushButton::tr("Hello world!") or \c +QObject::tr("Hello world!"). + +\section3 Running the Application in English + +\index English Language + +Since we haven't made the translation file \c tt1_la.qm, the source text +is shown when we run the application: + +\img tt1_en.png +\caption Tutorial 1 Screenshot, English version + +\section3 Creating a Latin Message File + +\index tt1.pro +\index Latin + +The first step is to create a project file, \c tt1.pro, that lists +all the source files for the project. The project file can be a qmake +project file, or even an ordinary makefile. Any file that contains + +\index SOURCES!in Project Files +\index TRANSLATIONS!in Project Files + +\quotefile tt1/tt1.pro +\skipto SOURCES +\printline SOURCES +\skipto TRANSLATIONS +\printline TRANSLATIONS + +will work. \e TRANSLATIONS specifies the message files we want to +maintain. In this example, we just maintain one set of translations, +namely Latin. + +\index .ts Files +\index Translation Source Files +\index .qm Files +\index Qt Message Files + +Note that the file extension is \c .ts, not \c .qm. The \c .ts +translation source format is designed for use during the +application's development. Programmers or release managers run the \l +lupdate program to generate and update \c .ts files with the source +text that is extracted from the source code. Translators read and +update the \c .ts files using \e {Qt Linguist} adding and editing +their translations. + +\index XML + +The \c .ts format is human-readable XML that can be emailed directly +and is easy to put under version control. If you edit this file +manually, be aware that the default encoding for XML is UTF-8, not +Latin-1 (ISO 8859-1). One way to type in a Latin-1 character such as +'\OSLASH' (Norwegian o with slash) is to use an XML entity: +"\ø". This will work for any Unicode character. + +Once the translations are complete the \l lrelease program is used to +convert the \c .ts files into the \c .qm Qt message file format. The +\c .qm format is a compact binary format designed to deliver very +fast lookup performance. Both \l lupdate and \l lrelease read all the +project's source and header files (as specified in the HEADERS and +SOURCES lines of the project file) and extract the strings that +appear in \c tr() function calls. + +\index lupdate + +\l lupdate is used to create and update the message files (\c tt1_la.ts +in this case) to keep them in sync with the source code. It is safe to +run \l lupdate at any time, as \l lupdate does not remove any +information. For example, you can put it in the makefile, so the \c .ts +files are updated whenever the source changes. + +\index .ts Files +\index Translation Source Files +\index XML + +Try running \l lupdate right now, like this: +\code + lupdate -verbose tt1.pro +\endcode +(The \c -verbose option instructs \c lupdate to display messages that +explain what it is doing.) You should now have a file \c tt1_la.ts in +the current directory, containing this: +\code + + + QPushButton + + Hello world! + + + + +\endcode +You don't need to understand the file format since it is read and +updated using tools (\l lupdate, \e {Qt Linguist}, \l lrelease). + +\section3 Translating to Latin with Qt Linguist + +\index Qt Linguist +\index Linguist + +We will use \e {Qt Linguist} to provide the translation, although +you can use any XML or plain text editor to enter a translation into a +\c .ts file. + +To start \e {Qt Linguist}, type +\code + linguist tt1_la.ts +\endcode + +You should now see the text "QPushButton" in the top left pane. +Double-click it, then click on "Hello world!" and enter "Orbis, te +saluto!" in the \e Translation pane (the middle right of the +window). Don't forget the exclamation mark! + +Click the \e Done checkbox and choose \e File|Save from the +menu bar. The \c .ts file will no longer contain +\code + +\endcode +but instead will have +\code + Orbis, te saluto! +\endcode + +\section3 Running the Application in Latin + +\index Latin +\index lrelease + +To see the application running in Latin, we have to generate a \c .qm +file from the \c .ts file. Generating a \c .qm file can be achieved +either from within \e {Qt Linguist} (for a single \c .ts file), or +by using the command line program \l lrelease which will produce one \c +.qm file for each of the \c .ts files listed in the project file. +Generate \c tt1_la.qm from \c tt1_la.ts by choosing +\e File|Release from \e {Qt Linguist}'s menu bar and pressing +\e Save in the file save dialog that pops up. Now run the \e tt1 example +program again. This time the button will be labelled "Orbis, te +saluto!". + +\img tt1_la.png +\caption Tutorial 1 Screenshot, Latin version + +\section2 Tutorial 2: Using Two or More Languages + +\img tt2_en.png +\caption Tutorial 2 Screenshot, English version + +\index .pro Files +\index Project Files +\index qmake!Project Files + +\include tt2/tt2.pro +\caption tt2.pro + +\index Translation Contexts +\index Contexts!for Translation + +This example is a slightly more involved and introduces a key +\e {Qt Linguist} concept: "contexts". + +\list +\i \c arrowpad.h contains the definition of \c ArrowPad, a custom widget; +\i \c arrowpad.cpp contains the implementation of \c ArrowPad; +\i \c mainwindow.h contains the definition of \c MainWindow, a subclass of + \l QMainWindow +\i \c mainwindow.cpp contains the implementation of \c MainWindow; +\i \c main.cpp contains main(). +\endlist + +\index tt2.pro +\index French Language +\index Dutch Language + +We will use two translations, French and Dutch, although there is no +effective limit on the number of possible translations that can be used +with an application. The relevant lines of \c tt2.pro are + +\quotefile tt2/tt2.pro +\skipto HEADERS +\printuntil tt2_nl.ts + +\index lupdate +\index tt2_fr.ts +\index tt2_nl.ts + +Run \l lupdate; it should produce two identical message files +\c tt2_fr.ts and \c tt2_nl.ts. These files will contain all the source +texts marked for translation with \c tr() calls and their contexts. + +\section3 Line by Line Walk-through + +\index ArrowPad!in Translation Tutorial +\index English Language + +In \c arrowpad.h we define the \c ArrowPad subclass which is a +subclass of \l QWidget. In the \e {Tutorial 2 Screenshot, English +version}, above, the central widget with the four buttons is an +\c ArrowPad. + +\quotefile tt2/arrowpad.h +\skipto class ArrowPad +\printline class ArrowPad + +\index Q_OBJECT +\index tr() +\index QObject!tr() +\index Translation Contexts +\index Contexts!for Translation + +When \l lupdate is run it not only extracts the source texts but it +also groups them into contexts. A context is the name of the class in +which the source text appears. Thus, in this example, "ArrowPad" is a +context: it is the context of the texts in the \c ArrowPad class. +The \c Q_OBJECT macro defines \c tr(x) in \c ArrowPad like this + +\index QApplication!translate() +\index translate()!QApplication + +\code + qApp->translate( "ArrowPad", x ) +\endcode + +Knowing which class each source text appears in enables \e {Qt +Linguist} to group texts that are logically related together, e.g. +all the text in a dialog will have the context of the dialog's class +name and will be shown together. This provides useful information for +the translator since the context in which text appears may influence how +it should be translated. For some translations keyboard +accelerators may need to be changed and having all the source texts in a +particular context (class) grouped together makes it easier for the +translator to perform any accelerator changes without introducing +conflicts. + +In \c arrowpad.cpp we implement the \c ArrowPad class. + +\quotefile tt2/arrowpad.cpp +\skipto QPushButton +\printline QPushButton + +We call \c ArrowPad::tr() for each button's label since the labels are +user-visible text. + +\img tt2_en.png +\caption Tutorial 2 Screenshot, English version + +\index Q_OBJECT +\index MainWindow!in Translation Tutorial + +\quotefile tt2/mainwindow.h +\skipto QMainWindow +\printline QMainWindow +\printuntil Q_OBJECT + +In the \e {Tutorial 2 Screenshot, English version}, above, the whole +window is a \c MainWindow. This is defined in the \c mainwindow.h +header file. Here too, we use \c Q_OBJECT, so that \c MainWindow will +become a context in \e {Qt Linguist}. + +In the implementation of \c MainWindow, \c mainwindow.cpp, we create +an instance of our \c ArrowPad class + +\quotefile tt2/mainwindow.cpp +\skipto arrow pad +\printline arrow pad + +We also call \c MainWindow::tr() twice, once for the menu item and +once for the accelerator. + +\index Ctrl Key +\index Alt Key + +\skipto quit() +\printline quit() +\printuntil Ctrl+Q + +Note the use of \c tr() to support different keys in other languages. +"Ctrl+Q" is a good choice for Quit in English, but a Dutch translator +might want to use "Ctrl+A" (for Afsluiten) and a German translator +"Strg+E" (for Beenden). When using \c tr() for Ctrl key accelerators, +the two argument form should be used with the second argument +describing the function that the accelerator performs. + +\index main() + +Our \c main() function is defined in \c main.cpp as usual. + +\quotefile tt2/main.cpp +\skipto QTranslator +\printline QTranslator +\printuntil install + +\index QTextCodec!locale() +\index locale()!QTextCodec +\index LANG!Environment Variable +\index Environment Variables!LANG + +We choose which translation to use according to the current locale. +\l QTextCodec::locale() can be influenced by setting the \c LANG +environment variable, for example. Notice that the use of a naming +convention that incorporates the locale for \c .qm message files, +(and \c .ts files), makes it easy to implement choosing the +translation file according to locale. + +If there is no \c .qm message file for the locale chosen the original +source text will be used and no error raised. + +\section3 Translating to French and Dutch + +We'll begin by translating the example application into French. Start +\e {Qt Linguist} with \c tt2_fr.ts. You should get the seven source +texts ("\&Up", "\&Left", etc.) grouped in two contexts ("ArrowPad" +and "MainWindow"). + +Now, enter the following translations: + +\list +\i \c ArrowPad + \list + \i \&Up - \&Haut + \i \&Left - \&Gauche + \i \&Right - \&Droite + \i \&Down - \&Bas + \endlist +\i \c MainWindow + \list + \i E\&xit - \&Quitter + \i Ctrl+Q - Ctrl+Q + \i \&File - \&Fichier + \endlist +\endlist + +It's quickest to press \Key Alt+D (which clicks the \e {Done \& Next} +button) after typing each translation, since this marks the +translation as done and moves on to the next source text. + +Save the file and do the same for Dutch working with \c tt2_nl.ts: + +\list +\i \c ArrowPad + \list + \i \&Up - \&Boven + \i \&Left - \&Links + \i \&Right - \&Rechts + \i \&Down - \&Onder + \endlist +\i \c MainWindow + \list + \i E\&xit - \&Afsluiten + \i Ctrl+Q - Ctrl+A + \i File - \&Bestand + \endlist +\endlist + +We have to convert the \c tt1_fr.ts and \c tt1_nl.ts translation source +files into \c .qm files. We could use \e {Qt Linguist} as we've done +before; however using the command line tool \l lrelease ensures that +\e all the \c .qm files for the application are created without us +having to remember to load and \e File|Release each one +individually from \e {Qt Linguist}. + +In practice we would include calls to \l lupdate and \l lrelease in the +application's makefile to ensure that the latest translations are +used. + +\omit +an example of a makefile or .pro file that did this would be nice +\endomit + +Type + +\code + lrelease tt2.pro +\endcode + +\index LANG!Environment Variable +\index export!Unix Command +\index setenv!Unix Command + +This should create both \c tt2_fr.qm and \c tt2_nl.qm. Set the \c +LANG environment variable to \c fr. In Unix, one of the two following +commands should work + +\code + export LANG=fr + setenv LANG fr +\endcode + +\index + +\index autoexec.bat +\index set!Windows Command + +In Windows, either modify \c autoexec.bat or run + +\code + set LANG=fr +\endcode + +When you run the program, you should now see the French version: + +\img tt2_fr.png +\caption Tutorial 2 Screenshot, French version + +Try the same with Dutch, by setting \c LANG=nl. Now the Dutch +version should appear: + +\img tt2_nl.png +\caption Tutorial 2 Screenshot, Dutch version + +\section3 Exercises + +Mark one of the translations in \e {Qt Linguist} as not done, i.e. +by unchecking the "done" checkbox; run \l lupdate, then \l lrelease, +then the example. What effect did this change have? + +\index Canada +\index French Canada + +Set \c LANG=fr_CA (French Canada) and run the example program again. +Explain why the result is the same as with \c LANG=fr. + +Change one of the accelerators in the Dutch translation to eliminate the +conflict between \e \&Bestand and \e \&Boven. + + +\section2 Tutorial 3: Disambiguating Identical Strings + +\img tt3_10_en.png +\caption Tutorial 3 Screenshot, "Troll Print 1.0", English version + +\include tt3/tt3.pro +\caption \c tt3.pro + +\index Portuguese Language +\index Brazilian Language + +We've included a translation file, \c tt3_pt.ts, which contains some +Portuguese translations for this example. + +\index Troll Print + +We will consider two releases of the same application: Troll Print +1.0 and 1.1. We will learn to reuse the translations created for one +release in a subsequent release. (In this tutorial, you need to edit +some source files. It's probably best to copy all the files to a new +temporary directory and work from there.) + +Troll Print is a toy example application that lets the user choose +printer settings. It comes in two versions: English and Portuguese. + +Version 1.0 consists of these files: + +\index tt3.pro +\index tt3_pt.ts + +\list +\i \c printpanel.h contains the definition of PrintPanel; +\i \c printpanel.cpp contains the implementation of PrintPanel; +\i \c mainwindow.h contains the definition of \c MainWindow; +\i \c mainwindow.cpp contains the implementation of \c MainWindow; +\i \c main.cpp contains main(); +\i \c tt3.pro is the \e qmake project file. +\i \c tt3_pt.ts is the Portuguese message file. +\endlist + +\section3 Line by Line Walk-through + +The PrintPanel is defined in \c printpanel.h. + +\quotefile tt3/printpanel.h +\skipto QVBox +\printline QVBox +\printuntil Q_OBJECT + +\index Q_OBJECT + +\index PrintPanel!in Translation Tutorial + +PrintPanel is a \l QWidget. It needs the \c Q_OBJECT macro for \c +tr() to work properly. + +The implementation file is \c printpanel.cpp. + +\quotefile tt3/printpanel.cpp +\skipto setSpacing +\skipto / +\printline / +\printline +\printline +\printline + +\index Troll Print + +Some of the code is commented out in Troll Print 1.0; you will uncomment +it later, for Troll Print 1.1. + +\quotefile tt3/printpanel.cpp +\skipto twoSided +\printline twoSided +\printuntil toggle +\printline +\printuntil toggle + +Notice the two occurrences of \c tr("Enabled") and of \c +tr("Disabled") in PrintPanel. Since both "Enabled"s and "Disabled"s +appear in the same context \e {Qt Linguist} will only display one +occurrence of each and will use the same translations for the +duplicates that it doesn't display. Whilst this is a useful +timesaver, in some languages, such as Portuguese, the second +occurrence requires a separate translation. We will see how \e {Qt +Linguist} can be made to display all the occurrences for separate +translation shortly. + +\index MainWindow!in Translation Tutorial + +The header file for \c MainWindow, \c mainwindow.h, contains no +surprises. In the implementation, \c mainwindow.cpp, we have some +user-visible source texts that must be marked for translation. + +\quotefile tt3/mainwindow.cpp +\skipto setCaption +\printline setCaption + +We must translate the window's caption. + +\skipto quit +\printline quit +\printuntil Help + +We also need to translate the menu items. Note that the two argument +form of \c tr() is used for the keyboard accelerator, "Ctrl+Q", since +the second argument is the only clue the translator has to indicate +what function that accelerator will perform. + +\quotefile tt3/main.cpp +\skipto QTranslator +\printuntil installTranslator + +\index main() + +The \c main() function in \c main.cpp is the same as the one in \link +{Tutorial 2...} Tutorial 2 \endlink. In particular it chooses a +translation file based on the current locale. + +\section3 Running Troll Print 1.0 in English and in Portuguese + +We will use the translations in the \c tt3_pt.ts file that is provided. + +Set the \c LANG environment variable to \c pt, and then run \c tt3. +You should still see the English version, as shown in the \e +{Tutorial 3 Screenshot, "Troll Print 1.0", English version}, above. +Now run \l lrelease, e.g. \c {lrelease tt3.pro}, and then run the +example again. Now you should see the Portuguese edition (Troll +Imprimir 1.0): + +\img tt3_10_pt_bad.png +\caption Tutorial 3 Screenshot, "Troll Imprimir 1.0", (Bad) Portuguese version + +Whilst the translation has appeared correctly, it is in fact wrong. In +good Portuguese, the second occurrence of "Enabled" should be +"Ativadas", not "Ativado" and the ending for the second translation of +"Disabled" must change similarly too. + +If you open \c tt3_pt.ts using \e {Qt Linguist}, you will see that +there is just one occurrence of "Enabled" and of "Disabled" in the +translation source file, even though there are two of each in the +source code. This is because \e {Qt Linguist} tries to minimize the +translator's work by using the same translation for duplicate source +texts. In cases such as this where an identical translation is wrong, +the programmer must disambiguate the duplicate occurrences. This is +easily achieved by using the two argument form of \c tr(). + +We can easily determine which file must be changed because the +translator's "context" is in fact the class name for the class where +the texts that must be changed appears. In this case the file is \c +printpanel.cpp, where the there are four lines to change. Add the +second argument "two-sided" in the appropriate \c tr() calls to the +first pair of radio buttons: + +\code + but = new QRadioButton( tr("Enabled", "two-sided"), twoSided ); + but = new QRadioButton( tr("Disabled", "two-sided"), twoSided ); +\endcode + +and add the second argument "colors" in the appropriate \c tr() calls +for the second pair of radio buttons: + +\code + but = new QRadioButton( tr("Enabled", "colors"), colors ); + but = new QRadioButton( tr("Disabled", "colors"), colors ); +\endcode + +\index lupdate +\index tt3_pt.ts + +Now run \l lupdate and open \c tt3_pt.ts with \e {Qt Linguist}. You +should now see two changes. + +First, the translation source file now contains \e three "Enabled", +"Disabled" pairs. The first pair is marked "(obs.)" signifying that they +are obsolete. This is because these texts appeared in \c tr() calls that +have been replaced by new calls with two arguments. The second pair has +"two-sided" as their comment, and the third pair has "colors" as their +comment. The comments are shown in the \e {Source text and comments} +area in \e {Qt Linguist}. + +Second, the translation text "Ativado" and "Desativado" have been +automatically used as translations for the new "Enabled" and "Disabled" +texts, again to minimize the translator's work. Of course in this case +these are not correct for the second occurrence of each word, but they +provide a good starting point. + +Change the second "Ativado" into "Ativadas" and the second +"Desativado" into "Desativadas", then save and quit. Run \l lrelease +to obtain an up-to-date binary \c tt3_pt.qm file, and run Troll Print +(or rather Troll Imprimir). + +\img tt3_10_pt_good.png +\caption Tutorial 3 Screenshot, "Troll Imprimir 1.0", (Good) Portuguese version + +\index Translator Comments +\index Comments!for Translators + +The second argument to \c tr() calls, called "comments" in \e {Qt +Linguist}, distinguish between identical source texts that occur in +the same context (class). They are also useful in other cases to give +clues to the translator, and in the case of Ctrl key accelerators are +the only means of conveying the function performed by the accelerator to +the translator. + +\index TRANSLATOR!in Comments +\index Translator Comments +\index Comments!for Translators + +An additional way of helping the translator is to provide information on +how to navigate to the particular part of the application that contains +the source texts they must translate. This helps them see the context +in which the translation appears and also helps them to find and test +the translations. This can be achieved by using a \e TRANSLATOR comment +in the source code: +\code + /* TRANSLATOR MainWindow + + In this application the whole application is a MainWindow. + Choose Help|About from the menu bar to see some text + belonging to MainWindow. + */ +\endcode + +Try adding these comments to some source files, particularly to +dialog classes, describing the navigation necessary to reach the +dialogs. You could also add them to the example files, e.g. \c +mainwindow.cpp and \c printpanel.cpp are appropriate files. Run \l +lupdate and then start \e {Qt Linguist} and load in \c tt3_pt.ts. +You should see the comments in the \e {Source text and comments} area +as you browse through the list of source texts. + +Sometimes, particularly with large programs, it can be difficult for +the translator to find their translations and check that they're +correct. Comments that provide good navigation information can save +them time: + +\code + /* TRANSLATOR ZClientErrorDialog + + Choose Client|Edit to reach the Client Edit dialog, then choose + Client Specification from the drop down list at the top and pick + client Bartel Leendert van der Waerden. Now check the Profile + checkbox and then click the Start Processing button. You should + now see a pop up window with the text "Error: Name too long!". + This window is a ZClientErrorDialog. + */ +\endcode + + +\section3 Troll Print 1.1 + +We'll now prepare release 1.1 of Troll Print. Start your favorite text +editor and follow these steps: + +\list +\i Uncomment the two lines that create a \l QLabel with the text + "\TROLL PRINT\" in \c printpanel.cpp. +\i Word-tidying: Replace "2-sided" by "Two-sided" in \c printpanel.cpp. +\i Replace "1.0" with "1.1" everywhere it occurs in \c mainwindow.cpp. +\i Update the copyright year to 1999-2000 in \c mainwindow.cpp. +\endlist + +(Of course the version number and copyright year would be consts or +#defines in a real application.) + +Once finished, run \l lupdate, then open \c tt3_pt.ts in \e {Qt +Linguist}. The following items are of special interest: + +\list +\i \c MainWindow + \list + \i Troll Print 1.0 - marked "(obs.)", obsolete + \i About Troll Print 1.0 - marked "(obs.)", obsolete + \i Troll Print 1.0. Copyright 1999 Macroshaft, Inc. - + marked "(obs.)", obsolete + \i Troll Print 1.1 - automatically translated as + "Troll Imprimir 1.1" + \i About Troll Print 1.1 - automatically translated as + "Troll Imprimir 1.1" + \i Troll Print 1.1. Copyright 1999-2000 Macroshaft, + Inc. - automatically translated as "Troll Imprimir 1.1. + Copyright 1999-2000 Macroshaft, Inc." + \endlist +\i \c PrintPanel + \list + \i 2-sided - marked "(obs.)", obsolete + \i \TROLL PRINT\ - unmarked, i.e. untranslated + \i Two-sided - unmarked, i.e. untranslated. + \endlist +\endlist + +Notice that \l lupdate works hard behind the scenes to make revisions +easier, and it's pretty smart with numbers. + +Go over the translations in \c MainWindow and mark these as "done". +Translate "\TROLL PRINT\" as "\TROLL IMPRIMIR\". +When you're translating "Two-sided", press the \e {Guess Again} +button to translate "Two-sided", but change the "2" into "Dois". + +Save and quit, then run \l lrelease. The Portuguese version +should look like this: + +\img tt3_11_pt.png +\caption Tutorial 3 Screenshot, "Troll Imprimir 1.1", Portuguese version + +Choose \e{Ajuda|Sobre}, (\e{Help|About}), to see the about box + +\img tt3_11_about_pt.png +\caption Tutorial 3 Screenshot, About box, Portuguese version + +\index English Language +\index Translating Qt +\index Qt!Translating Qt + +If you choose \e {Ajuda|Sobre Qt}, (\e {Help|About Qt}), you'll get +an English dialog. Oops! Qt itself needs to be translated. See the +document \link i18n.html#qt-itself Internationalization with Qt +\endlink for details. + +Now set \c LANG=en to get the original English version: + +\img tt3_11_en.png +\caption Tutorial 3 Screenshot, "Troll Print 1.1", English version + +\section2 Summary + +These tutorials cover all that you need to know to prepare your Qt +applications for translation. + +At the beginning of a project add the translation source files to be +used to the project file and add calls to \l lupdate and \l lrelease to +the make file. + +During the project all the programmer must do is wrap any user-visible +text in \c tr() calls. They should also use the two argument form for +Ctrl key accelerators, or when asked by the translator for the cases +where the same text translates into two different forms in the same +context. The programmer should also include \e TRANSLATION comments to +help the translator navigate the application. diff --git a/tools/linguist/book/linguist-translator.leaf b/tools/linguist/book/linguist-translator.leaf new file mode 100644 index 0000000..7a71b6a --- /dev/null +++ b/tools/linguist/book/linguist-translator.leaf @@ -0,0 +1,582 @@ +\chapter Translators + +\img linguist.png +\caption Linguist Main Window + +\section1 The One Minute Guide to Using Qt Linguist + +\index Linguist +\index Qt Linguist +\index Contexts!for Translation + +\e {Qt Linguist} is a tool for adding translations to Qt +applications. It introduces the concept of a translation "context" +which means a group of phrases that appear together on the screen +e.g. in the same menu or dialog. + +To start, run \e {Qt Linguist}, either from the taskbar menu, or by +double clicking the desktop icon, or type \c {linguist} (followed by +\Key Enter) at the command line. Once \e {Qt Linguist} has started +choose \Menu File|Open from the menu bar and select a \c .ts +translation source file to work on. + +\e {Qt Linguist}'s main window is divided into four main areas. The +left hand side contains the Context list, the top right is the Source +text area, the middle right is the translation area and the bottom +right is the phrases and guesses area. We'll describe them in detail +later. + +Click on one of the contexts in the context list (left hand side) and +then click on one of the phrases that appears in the Source text area +(top right). The phrase will be copied into the translation area +(middle right). Click under the word 'Translation' and type in the +translation. Click \Key Ctrl+Enter (Done \& Next) to confirm that you +have completed the translation and to move on to the next phrase that +requires translation. + +The cycle of entering a translation then pressing \Key Ctrl+Enter can +be repeated until all the translations are done or until you finish +the session. Linguist will attempt to fill the "phrases and guesses" +area with possible translations from any open phrase books and any +previous translations. Each has a keyboard shortcut, e.g. +\Key Ctrl+1, \Key Ctrl+2, etc., which you can use to copy the +guess into the Translation area. (Mouse users can double click a +phrase or guess to move it into the Translation area.) At the end of +the session choose \Menu File|Save from the menu bar and then +\Menu File|Exit to quit. + +\section1 Qt Linguist's Main Window + +\section2 Context List + +\index Contexts!for Translation + +This appears at the left hand side of the main window by default. The +first column, 'Done', identifies whether or not the translations for the +context have been done. A tick indicates that all the translations have +been done and are valid. A question mark indicates that one or more +translations have not been done or have failed validation. The second +column, 'Context' is the name of the context in which the translation +phrases appear. The third column, 'Items' shows two numbers, the first +is the number of translations that have been done, and the second is the +number of phrases that are in the context; if the numbers are equal then +all the translations have been done. Note that a greyed out tick +indicates an obsolete translation, i.e. a phrase that was translated in +a previous version of the application but which does not occur in the +new version. + +The contexts are ordered alphabetically. The phrases within each context +are in the order in which they appear in the source program and this may +not be the order in which they are shown on screen. + +The Context List is a dockable window so it can be dragged to another +position in the main window, or dragged out of the main window to be a +window in its own right. If you move the Context List, \e {Qt +Linguist} will remember its position and restore it whenever you +start the program. + +\section2 Source Text Area + +This appears at the top right of the main window by default. The first +column, 'Done', signifies the status of the translation. A tick +indicates that the phrase has been translated and passed validation. A +question mark indicates that the translation has not been done. An +exclamation mark indicates that the translation has failed validation. +The second column 'Source text' shows the text that must be translated. +The third column shows the translation. + +\e{Qt Linguist} provides three kinds of validation: accelerator, +punctuation and phrase. If the source text contains an accelerator +i.e. an ampersand, '\&' and the translated text does not contain an +ampersand the translation will fail the accelerator validation. +Similarly, if the source text ends with a particular punctuation +mark, e.g. '?', '!' or '.' and the translation ends with a different +punctuation mark the translation will fail the punctuation +validation. If the source text has a translation in one of the open +phrase books that differs from the translation used the translation +will fail phrase validation. (See \l Validation.) + +The Source Text Area is a dockable window. + +\section2 Translation Area + +This area appears at the middle right of the main window by default. It +is comprised of three vertical sections. The first section is labelled +'Source text' below which the source text appears. The second section +contains contextual information on a light blue background that the +programmer has added to assist the translator. If no contextual +information has been given this section does not appear. The third +section is labelled 'Translation' and this is where you enter the +translation of the source text. + +\section2 Phrases and Guesses Area + +\index Phrases!in Qt Linguist +\index Guesses!in Qt Linguist + +This area appears at the bottom right of the main window by default. +When you move to a new phrase if the phrase is in one of the phrase +books that has been loaded the phrase will appear in this area with its +translation. If the phrase is the same or similar to another phrase that +has already been translated the phrase and translation will be shown in +this area. To copy a translation from the phrases and guesses area press +\Key F6 to move to the phrases and guesses area, use the up and down arrow +keys to move to the phrase you want to use and press Enter to copy it. +If you decide that you don't want to copy a phrase after all, press Esc. +In both cases the focus will return to the Translation area. +Alternatively, double click the translation you want to use and it will +be copied into the translation area. + +The Phrases and Guesses Area is a dockable window. + +\section1 Common Tasks + +\section2 Leaving a Translation for Later + +If you wish to leave a translation press \Key Ctrl+L (Next Unfinished) to +move to the next unfinished translation. An unfinished translation is +one that either has not been translated at all or one which fails +validation. To move to the next phrase press \Key Shift+Ctrl+L. You can also +navigate using the Translation menu. If you want to go to a different +context entirely, click the context you want to work on in the Context +list, then click the source text in the Source Text area. + +\section2 Phrases That Require Multiple Translations Depending on Context + +\index Contexts!for Translation +\index Comments!for Translators + +The same phrase may occur in two or more contexts without conflict. Once +a phrase has been translated in one context, \e {Qt Linguist} notes +that the translation has been made and when the translator reaches a +later occurrence of the same phrase \e {Qt Linguist} will provide +the previous translation as a possible translation candidate in the +phrases and guesses area. If the +previous translation is acceptable just click the \e {Done \& Next} +button (press \Key Ctrl+Enter) to move on to the next unfinished phrase. + +If a phrase occurs more than once in a particular context it will only +be shown once in \e {Qt Linguist}'s context list and +the translation will be applied to every occurrence within the context. +If the same phrase needs to be translated differently within the same +context the programmer must provide a distinguishing comment for each of +the phrases concerned. If such comments are used the duplicate phrases +will appear in the context list. The programmers comments will appear in +the translation area on a light blue background. + +\section2 Changing Keyboard Accelerators + +\index Accelerators +\index Keyboard Accelerators + +A keyboard accelerator is a key combination that when pressed will +cause an application to perform an action. Keyboard accelerators +normally come in two forms: Alt key and Ctrl key accelerators. + +\index Alt Key + +Alt key accelerators are used for menus and buttons. The underlining +signifies that pressing the Alt key with the underlined letter is the +same as clicking the menu item with the mouse. For example, most +applications have a \e File menu with the "F" in the word "file" +underlined. In these applications the file menu can be invoked either by +clicking the word "File" on the menu bar or by pressing Alt+F. The +accelerator key which is underlined is signified by preceeding it with +an ampersand, e.g. \e \&File. If a source phrase appears with an +ampersand in it then the translation should also contain an ampersand, +preferably in front of the same letter. The meaning of Alt key +accelerators can be determined from the phrase in which the ampersand is +embedded. The translator may need to change the letter used with the Alt +key, e.g. if the translated phrase does not contain the original +accelerator letter. Conflicts with other keys, i.e. having two Alt key +accelerators using the same letter in the same context, must be avoided. +Note that some Alt key accelerators, usually those on the menu bar, may +apply in other contexts. + +\index Ctrl Key + +Ctrl key accelerators can exist independently of any visual control. +They are often used to invoke actions in menus that would otherwise +take several keystrokes or mouse clicks. They may also be used to +perform actions that do not appear in any menu or on any button. For +example, most applications that have a \e File menu have a submenu +item called \e New. In many applications this will appear as "\NEW +Ctrl+N". This menu option could be invoked by clicking \e File then +clicking \e New with the mouse. Or you could press Alt+F then press N +since these letters are underlined. But the same thing can be achieved +simply by pressing \Key Ctrl+N. Accelerators that use the Ctrl key are +shown literally in the source text, e.g. \Key Ctrl+Enter. Ctrl key +accelerators have no phrase so the translator \index Comments!for +Translators must rely on the programmer to add a "comment" which +appears in the top right hand pane. This comment should explain what +action the Ctrl key accelerator performs. Ideally Ctrl key +accelerators are translated simply by copying them by chossing the \e +{Begin from Source} entry in the \Menu Translations menu. However in +some cases the letter will not make sense in the target language and +must be changed. Whatever letter (or digit) is chosen, the translation +should always be in the form "Ctrl+" followed by the letter or digit +in upper case. As with Alt key accelerators, if the translator changes +the key it must not conflict with any other Ctrl key accelerator. + +Later versions of \e {Qt Linguist} are expected to help the +translator avoid accelerator conflicts. + +\section2 Dealing with Phrases that Contain Variables + +Some phrases contain variables. Variables are placeholders for items of +text that are filled in at runtime. They are signified in the source +text with a percent sign followed by a digit, e.g. \e {After processing +file %1, file %2 is next in line}. In this example, \c %1 will be +replaced at runtime with the name of the first file to be processed and +\c %2 with the name of the next file to be processed. In the translated +version the variables must still appear. For example a German +translation might reverse the phrases, e.g. \e {Datei %2 wird +bearbeitet, wenn. Datei %1 fertig ist}. Note that both variables +are still used but their order has changed. The order in which variables +appear does not matter; \c %1 will always be replaced by the same text +at runtime no matter where it appears in the source text or translation +and similarly \c %2, etc. + +\section2 Reusing Translations + +If the translated text is similar to the source text, choose the \e +{Begin from Source} entry in the \Menu Translations menu (press \Key +Ctrl+B) which will copy the source text into the translation area. + +\e {Qt Linguist} automatically lists phrases from the open phrase +books and similar or identical phrases that have already been translated +in the Phrases and guesses area. + +\section1 Creating and Using Phrase Books + +\index Phrases!in Qt Linguist +\index Phrase Books + +\img phrasebookdialog.png +\caption Phrase Book Dialog + +A \e {Qt Linguist} phrase book is a set of source phrases, target +(translated) phrases, and optional definitions. Phrase Books are created +independently of any application, although typically one phrase book +will be created per application or family of applications. + +If the translator reaches an untranslated phrase that is the same as a +source phrase in the phrase book, \e {Qt Linguist} will show the +phrase book entry in the \e {Relevant phrases} panel at the bottom +right of the main window. Phrases which have translations that conflict +with those given in the phrase book are marked with a question mark in +the source text pane. Phrase Books are used to provide a common set of +translations to help ensure consistency. They can also be used to avoid +duplication of effort since the translations for a family of +applications can be produced once in the phrase book and the phrase book +used for the majority of translations in each application. + +Before a phrase book can be edited it must be created or if it already +exists, opened. Create a new phrase book by selecting +\Menu {Phrase|New Phrase Book} from the menu bar. You must enter a +filename and may change the location of the file if you wish. A newly +created phrase book is automatically opened. Open an existing phrase +book by choosing \Menu {Phrase|Open Phrase Book} from the menu bar. + +To add a new phrase click the \Button {New Phrase} button (or press +Alt+N) and type in a new source phrase. Press Tab and type in the +translation. Optionally press Tab and enter a definition -- this is +useful to distinguish different translations of the same source phrase. +This process may be repeated as often as necessary. + +You can delete a phrase by selecting it in the phrases list and clicking +Remove Phrase. + +Click the \e Save button (press Alt+S) and then click the \e Close +button (press Esc) once you've finished adding (and removing) phrases. + +When a phrase or set of phrases appears in the phrase book double +clicking the required target phrase will copy it to the translation +pane at the text cursor position. If you want to \e replace the text +in the translation pane with the target phrase, click the translation +pane, choose \Menu {Edit|Select All} (press \Key Alt+A) and then +double click the target phrase. + +\section1 Validation + +\index Validation of Translations +\index Accelerators!Validation +\index Punctuation!Validation +\index Phrases!Validation + +\e {Qt Linguist} provides three kinds of validation on translated +phrases. + +\list 1 +\i \e {Accelerator validation} detects translated phrases +that do not have an ampersand when the source phrase does and vice +versa. +\i \e {Punctuation validation} detects differences in the +terminating punctuation between source and translated phrases when this +may be significant, e.g. warns if the source phrase ends with an +ellipsis, exclamation mark or question mark, and the translated phrase +doesn't and vice versa. +\i \e {Phrases validation} detects source phrases that are +also in the phrase book but whose translation differs from that given in +the phrase book. +\endlist + +Validation may be switched on or off from the menu bar's Validation item +or using the toolbar buttons. Phrases that fail validation are marked +with a question mark in the source text pane. If you switch validation +off and then switch it on later, \e{Qt Linguist} will recheck all +phrases and mark any that fail validation. + +If any phrase in a context is invalid then the context itself will be +marked with a question mark; if all the phrases in a context are done +and are valid the context will be marked with a tick. + +Note that only phrases which are marked as done (with a tick) will +appear in the application. Invalid phrases and phrases which are +translated but not marked as done are kept in the translation source +file but are not used by the application. + +\section1 Qt Linguist Reference + +\section2 File Types + +\e {Qt Linguist} makes use of three kinds of file: + +\index .ts Files +\index Translation Source Files +\index .qm Files +\index Qt Message Files +\index .qph Files +\index Qt Phrase Book Files + +\list +\i \c .ts \e {translation source files} \BR are human-readable XML +files containing source phrases and their translations. These files are +usually created and updated by \l lupdate and are specific to an +application. +\i \c .qm \e {Qt message files} \BR are binary files that contain +translations used by an application at runtime. These files are +generated by \l lrelease, but can also be generated by \e {Qt +Linguist}. +\i \c .qph \e {Qt phrase book files} \BR are human-readable XML +files containing standard phrases and their translations. These files +are created and updated by \e {Qt Linguist} and may be used by any +number of projects and applications. +\endlist + +\section2 The Menu Bar + +\img menubar.png +\caption Menu Bar + +\list +\i \e {File} + \list + \i \e {Open... Ctrl+O} \BR pops up an open file dialog from which a + translation source \c .ts file can be chosen. + \i \e {Save Ctrl+S} \BR saves the current translation source \c .ts file. + \i \e {Save As...} \BR pops up a save as file dialog so that the + current translation source \c .ts file may be saved with a different + name and/or put in a different location. + \i \e {Release...} \BR pops up a save as file dialog. The + filename entered will be a Qt message \c .qm file of the translation + based on the current translation source file. The release manager's + command line tool \l lrelease performs the same function on + \e all of an application's translation source files. + \i \e {Print... Ctrl+P} \BR pops up a print dialog. If you click + OK the translation source and the translations will be printed. + \i \e {Recently opened files} \BR shows the \c .ts files that + have been opened recently, click one to open it. + \i \e {Exit Ctrl+Q} \BR closes \e {Qt Linguist}. + \endlist + +\i \e {Edit} + \list + \i \e {Undo Ctrl+Z} \BR undoes the last editing action in the + translation pane. + \i \e {Redo Ctrl+Y} \BR redoes the last editing action in the + translation pane. + \i \e {Cut Ctrl+X} \BR deletes any highlighted text in the + translation pane and saves a copy to the clipboard. + \i \e {Copy Ctrl+C} \BR copies the highlighted text in the + translation pane to the clipboard. + \i \e {Paste Ctrl+V} \BR pastes the clipboard text into the + translation pane. +\omit + \i \e {Delete} \BR deletes the highlighted text in the + translation pane. +\endomit + \i \e {Select All Ctrl+A} \BR selects all the text in the + translation pane ready for copying or deleting. + \i \e {Find... Ctrl+F} \BR pops up the + \link {The Find Dialog} Find dialog \endlink. When the dialog pops up + enter the text to be found and click the \e {Find Next} button. + Source phrases, translations and comments may be searched. + \i \e {Find Next F3} \BR finds the next occurrence of the text that + was last entered in the Find dialog. + \endlist + +\i \e {Translation} + \list + \i \e {Prev Unfinished Ctrl+K} \BR moves to the nearest previous + unfinished source phrase (unfinished means untranslated or + translated but failed validation). + \i \e {Next Unfinished Ctrl+L} \BR moves to the next unfinished source + phrase. + \i \e {Prev Shift+Ctrl+K} \BR moves to the previous source phrase. + \i \e {Next Shift+Ctrl+L} \BR moves to the next source phrase. + \i \e {Done \& NextCtrl+Enter} \BR mark this phrase as 'done' + (translated) and move to the next unfinished source phrase. + \i \e {Begin from Source Ctrl+B} \BR copies the source text into + the translation. + \endlist + +\i \e {Validation} (See the \l Validation section) + \list + \i \e {Accelerators} \BR toggles validation on or off for Alt + accelerators. + \i \e {Ending Punctuation} \BR switches validation on or off + for phrase ending punctuation, e.g. ellipsis, exclamation mark, + question mark, etc. + \i \e {Phrase Matches} \BR sets validation on or off for + matching against translations that are in the current phrase book. + \endlist + +\i \e {Phrase} (See the section \l {Creating ... Phrase +Books} for details.) + \list + \i \e {New Phrase Book... Ctrl+N} \BR pops up a save as file dialog. + You must enter a filename to be used for the phrase book and save + the file. Once saved you should open the phrase book to begin using + it. + \i \e {Open Phrase Book... Ctrl+H} \BR pops up an open file dialog. + Find and choose a phrase book to open. + \i \e {Close Phrase Book} \BR closes the current phrase book. + This will stop any further phrase validation taking place. + The same effect can be achieved by switching off phrase validation + using the Validation menu or the phrase toolbar button. + \i \e {Edit Phrase Book...} \BR pops up the + \link {The Phrase Dialog} phrase book dialog \endlink where you can + add, edit or delete phrases. + \i \e {Print Phrase Book...} \BR pops up a print dialog. If + you click OK the phrase book will be printed. + \endlist + +\i \e {View} + \list + \i \e {Revert Sorting} \BR puts the phrases in the source text + pane into their original order. + \i \e {Display Guesses} \BR turns the display of phrases and + guesses on or off. + \i \e {Statistics} \BR toggles the visibility of the Statistics dialog. + \i \e {Views} \BR toggles the visibility of the Context, Source text and + Phrase views. + \i \e {Toolbars} \BR toggles the visibility of the different toolbars. +\omit + \i \e {Large Icons} \BR switches between large or standard + size icons on the toolbar. + \i \e {Text Labels} \BR toggles the use of text labels on the + toolbar icons. +\endomit + \endlist + +\endlist + +\section2 The Toolbar + +\img toolbar.png +\caption Toolbar + +\list +\i \img fileopen.png +\BR +Pops up the open file dialog to open a new translation source \c .ts +file. + +\i \img filesave.png +\BR +Saves the current translation source \c .ts file. + +\i \img fileprint.png +\BR +Prints the current translation source \c .ts file. + +\i \img phrasebookopen.png +\BR +Pops up the file open dialog to open a new phrase book \c .qph file. + +\i \img editundo.png +\BR +Undoes the last editing action in the translation pane. + +\i \img editredo.png +\BR +Redoes the last editing action in the translation pane. + +\i \img editcut.png +\BR +Deletes any highlighted text in the translation pane and save a copy to +the clipboard. + +\i \img editcopy.png +\BR +Copies the highlighted text in the translation pane to the clipboard. + +\i \img editpaste.png +\BR +Pastes the clipboard text into the translation pane. + +\i \img editfind.png +\BR +Pops up the \link {The Find Dialog} Find dialog \endlink. + +\i \img prev.png +\BR +Moves to the previous source phrase. + +\i \img next.png +\BR +Moves to the next source phrase. + +\i \img prevunfinished.png +\BR +Moves to the previous unfinished source phrase. + +\i \img nextunfinished.png +\BR +Moves to the next unfinished source phrase. + +\i \img doneandnext.png +\BR +Marks the phrase as 'done' (translated) and move to the next +unfinished source phrase. + +\i \img validateaccelerators.png +\BR +Toggles accelerator validation on and off. + +\i \img validatepunctuation.png +\BR +Toggles phrase ending punctuation validation on and off. + +\i \img validatephrases.png +\BR +Toggles phrase book validation on or off. +\endlist + +\section2 The Find Dialog + +\img finddialog.png +\caption The Find Dialog + +Choose \Menu Edit|Find from the menu bar or press \Key Ctrl+F to pop +up the Find dialog. Press \Key F3 to repeat the last search. By +default the source phrases, translations and comments will all be +searched and the search will be case-insensitive. These settings can +be changed by checking or unchecking the checkboxes to reflect your +preferences. + +\section2 The Phrase Dialog + +This dialog is explained in the \l {Creating and Using Phrase Books} +section. diff --git a/tools/linguist/linguist.pro b/tools/linguist/linguist.pro new file mode 100644 index 0000000..3f1f286 --- /dev/null +++ b/tools/linguist/linguist.pro @@ -0,0 +1,11 @@ +TEMPLATE = subdirs +SUBDIRS = linguist \ + tutorial/tt1 \ + tutorial/tt2 \ + tutorial/tt3 \ + lrelease \ + lupdate \ + qm2ts +CONFIG += ordered + +REQUIRES=full-config nocrosscompiler diff --git a/tools/linguist/linguist/about.ui b/tools/linguist/linguist/about.ui new file mode 100644 index 0000000..b2fb6b4 --- /dev/null +++ b/tools/linguist/linguist/about.ui @@ -0,0 +1,223 @@ + +AboutDialog +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + AboutDialog + + + + 0 + 0 + 484 + 640 + + + + Qt Linguist + + + + unnamed + + + 11 + + + 6 + + + + PixmapLabel1 + + + NoFrame + + + Plain + + + splash.png + + + false + + + AlignCenter + + + + + + + versionLabel + + + AlignCenter + + + + + + + TextLabel1_2 + + + Copyright (C) 2000-2008 Trolltech ASA. All Rights Reserved. + + + AlignCenter + + + + + + + TextLabel1_3 + + + + 1 + 0 + 0 + 0 + + + + <p>Qt Commercial Edition license holders: This program is licensed to you under the terms of the Qt Commercial License Agreement. For details, see the file LICENSE that came with this software distribution.</p><p></p><p>Qt Open Source Edition users: This program is licensed to you under the terms of the GNU General Public License Version 2. For details, see the file LICENSE.GPL that came with this software distribution.</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> + + + WordBreak|AlignVCenter|AlignLeft + + + + + + + Spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + PushButton1 + + + OK + + + true + + + true + + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + + + PushButton1 + clicked() + AboutDialog + accept() + + + + init() + destroy() + + + + diff --git a/tools/linguist/linguist/finddialog.cpp b/tools/linguist/linguist/finddialog.cpp new file mode 100644 index 0000000..385bd31 --- /dev/null +++ b/tools/linguist/linguist/finddialog.cpp @@ -0,0 +1,183 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +/* TRANSLATOR FindDialog + + Choose Edit|Find from the menu bar or press Ctrl+F to pop up the + Find dialog +*/ + +#include "finddialog.h" + +#include +#include +#include +#include +#include +#include + +FindDialog::FindDialog( bool replace, QWidget *parent, const char *name, + bool modal ) + : QDialog( parent, name, modal ) +{ + sourceText = 0; + + led = new QLineEdit( this, "find line edit" ); + QLabel *findWhat = new QLabel( led, tr("Fi&nd what:"), this, "find what" ); + QLabel *replaceWith = 0; + QPushButton *findNxt = new QPushButton( tr("&Find Next"), this, + "find next" ); + findNxt->setDefault( TRUE ); + connect( findNxt, SIGNAL(clicked()), this, SLOT(emitFindNext()) ); + QPushButton *cancel = new QPushButton( tr("Cancel"), this, "cancel find" ); + connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) ); + + QVBoxLayout *bl = new QVBoxLayout( 6, "find button layout" ); + bl->addWidget( findNxt ); + + matchCase = new QCheckBox( tr("&Match case"), this, "find match case" ); + matchCase->setChecked( FALSE ); + + if ( replace ) { + QWhatsThis::add( this, tr("This window allows you to search and replace" + " some text in the translations.") ); + + red = new QLineEdit( this, "replace line edit" ); + replaceWith = new QLabel( red, tr("Replace &with:"), this, + "replace with" ); + setTabOrder( led, red ); + + QPushButton *replace = new QPushButton( tr("&Replace"), this, + "replace" ); + connect( replace, SIGNAL(clicked()), this, SLOT(emitReplace()) ); + QPushButton *replaceAll = new QPushButton( tr("Replace &All"), this, + "replace all" ); + connect( replaceAll, SIGNAL(clicked()), this, SLOT(emitReplaceAll()) ); + setTabOrder( findNxt, replace ); + setTabOrder( replace, replaceAll ); + setTabOrder( replaceAll, cancel ); + + QWhatsThis::add( replace, tr("Click here to replace the next occurrence" + " of the text you typed in.") ); + QWhatsThis::add( replaceAll, tr("Click here to replace all occurrences" + " of the text you typed in.") ); + + bl->addWidget( replace ); + bl->addWidget( replaceAll ); + + QGridLayout *gl = new QGridLayout( this, 4, 3, 11, 11, + "find outer layout" ); + gl->addWidget( findWhat, 0, 0 ); + gl->addWidget( led, 0, 1 ); + gl->addWidget( replaceWith, 1, 0 ); + gl->addWidget( red, 1, 1 ); + gl->addMultiCellWidget( matchCase, 2, 2, 0, 1 ); + gl->addMultiCell( bl, 0, 3, 3, 3 ); + } else { + QWhatsThis::add( this, tr("This window allows you to search for some" + " text in the translation source file.") ); + + sourceText = new QCheckBox( tr("&Source texts"), this, + "find in source texts" ); + sourceText->setChecked( TRUE ); + translations = new QCheckBox( tr("&Translations"), this, + "find in translations" ); + translations->setChecked( TRUE ); + comments = new QCheckBox( tr("&Comments"), this, "find in comments" ); + comments->setChecked( TRUE ); + + QWhatsThis::add( sourceText, tr("Source texts are searched when" + " checked.") ); + QWhatsThis::add( translations, tr("Translations are searched when" + " checked.") ); + QWhatsThis::add( comments, tr("Comments and contexts are searched when" + " checked.") ); + + QVBoxLayout *cl = new QVBoxLayout( 6, "find checkbox layout" ); + + QGridLayout *gl = new QGridLayout( this, 3, 4, 11, 11, + "find outer layout" ); + gl->addWidget( findWhat, 0, 0 ); + gl->addMultiCellWidget( led, 0, 0, 1, 2 ); + gl->addWidget( matchCase, 1, 2 ); + gl->addMultiCell( bl, 0, 2, 3, 3 ); + gl->addMultiCell( cl, 1, 2, 0, 1 ); + gl->setColStretch( 0, 0 ); + gl->addColSpacing( 1, 40 ); + gl->setColStretch( 2, 1 ); + gl->setColStretch( 3, 0 ); + + cl->addWidget( sourceText ); + cl->addWidget( translations ); + cl->addWidget( comments ); + cl->addStretch( 1 ); + } + + QWhatsThis::add( led, tr("Type in the text to search for.") ); + + QWhatsThis::add( matchCase, tr("Texts such as 'TeX' and 'tex' are" + " considered as different when checked.") ); + QWhatsThis::add( findNxt, tr("Click here to find the next occurrence of the" + " text you typed in.") ); + QWhatsThis::add( cancel, tr("Click here to close this window.") ); + + bl->addWidget( cancel ); + bl->addStretch( 1 ); + + resize( 400, 1 ); + setMaximumHeight( height() ); + + led->setFocus(); +} + +void FindDialog::emitFindNext() +{ + int where; + if ( sourceText != 0 ) + where = ( sourceText->isChecked() ? SourceText : 0 ) | + ( translations->isChecked() ? Translations : 0 ) | + ( comments->isChecked() ? Comments : 0 ); + else + where = Translations; + emit findNext( led->text(), where, matchCase->isChecked() ); +} + +void FindDialog::emitReplace() +{ + emit replace( led->text(), red->text(), matchCase->isChecked(), FALSE ); +} + +void FindDialog::emitReplaceAll() +{ + emit replace( led->text(), red->text(), matchCase->isChecked(), TRUE ); +} diff --git a/tools/linguist/linguist/finddialog.h b/tools/linguist/linguist/finddialog.h new file mode 100644 index 0000000..5d06e8e --- /dev/null +++ b/tools/linguist/linguist/finddialog.h @@ -0,0 +1,68 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef FINDDIALOG_H +#define FINDDIALOG_H + +#include + +class QCheckBox; +class QLineEdit; + +class FindDialog : public QDialog +{ + Q_OBJECT +public: + enum { SourceText = 0x1, Translations = 0x2, Comments = 0x4 }; + + FindDialog( bool replace, QWidget *parent = 0, const char *name = 0, bool modal = FALSE ); + +signals: + void findNext( const QString& text, int where, bool matchCase ); + void replace( const QString& before, const QString& after, bool matchCase, bool all ); + +private slots: + void emitFindNext(); + void emitReplace(); + void emitReplaceAll(); + +private: + QLineEdit *led; + QLineEdit *red; + QCheckBox *sourceText; + QCheckBox *translations; + QCheckBox *comments; + QCheckBox *matchCase; +}; + +#endif diff --git a/tools/linguist/linguist/images/accelerator.png b/tools/linguist/linguist/images/accelerator.png new file mode 100644 index 0000000..173adb4 Binary files /dev/null and b/tools/linguist/linguist/images/accelerator.png differ diff --git a/tools/linguist/linguist/images/appicon.png b/tools/linguist/linguist/images/appicon.png new file mode 100644 index 0000000..90e143b Binary files /dev/null and b/tools/linguist/linguist/images/appicon.png differ diff --git a/tools/linguist/linguist/images/book.png b/tools/linguist/linguist/images/book.png new file mode 100644 index 0000000..dd850ab Binary files /dev/null and b/tools/linguist/linguist/images/book.png differ diff --git a/tools/linguist/linguist/images/d_accelerator.png b/tools/linguist/linguist/images/d_accelerator.png new file mode 100644 index 0000000..eaa2be6 Binary files /dev/null and b/tools/linguist/linguist/images/d_accelerator.png differ diff --git a/tools/linguist/linguist/images/d_book.png b/tools/linguist/linguist/images/d_book.png new file mode 100644 index 0000000..b61d611 Binary files /dev/null and b/tools/linguist/linguist/images/d_book.png differ diff --git a/tools/linguist/linguist/images/d_doneandnext.png b/tools/linguist/linguist/images/d_doneandnext.png new file mode 100644 index 0000000..e3a3fe1 Binary files /dev/null and b/tools/linguist/linguist/images/d_doneandnext.png differ diff --git a/tools/linguist/linguist/images/d_editcopy.png b/tools/linguist/linguist/images/d_editcopy.png new file mode 100644 index 0000000..578b591 Binary files /dev/null and b/tools/linguist/linguist/images/d_editcopy.png differ diff --git a/tools/linguist/linguist/images/d_editcut.png b/tools/linguist/linguist/images/d_editcut.png new file mode 100644 index 0000000..8d50ae0 Binary files /dev/null and b/tools/linguist/linguist/images/d_editcut.png differ diff --git a/tools/linguist/linguist/images/d_editpaste.png b/tools/linguist/linguist/images/d_editpaste.png new file mode 100644 index 0000000..78cab10 Binary files /dev/null and b/tools/linguist/linguist/images/d_editpaste.png differ diff --git a/tools/linguist/linguist/images/d_fileopen.png b/tools/linguist/linguist/images/d_fileopen.png new file mode 100644 index 0000000..ddbd33d Binary files /dev/null and b/tools/linguist/linguist/images/d_fileopen.png differ diff --git a/tools/linguist/linguist/images/d_filesave.png b/tools/linguist/linguist/images/d_filesave.png new file mode 100644 index 0000000..5d1476d Binary files /dev/null and b/tools/linguist/linguist/images/d_filesave.png differ diff --git a/tools/linguist/linguist/images/d_next.png b/tools/linguist/linguist/images/d_next.png new file mode 100644 index 0000000..f455e1f Binary files /dev/null and b/tools/linguist/linguist/images/d_next.png differ diff --git a/tools/linguist/linguist/images/d_nextunfinished.png b/tools/linguist/linguist/images/d_nextunfinished.png new file mode 100644 index 0000000..c2b06ec Binary files /dev/null and b/tools/linguist/linguist/images/d_nextunfinished.png differ diff --git a/tools/linguist/linguist/images/d_phrase.png b/tools/linguist/linguist/images/d_phrase.png new file mode 100644 index 0000000..acdd253 Binary files /dev/null and b/tools/linguist/linguist/images/d_phrase.png differ diff --git a/tools/linguist/linguist/images/d_prev.png b/tools/linguist/linguist/images/d_prev.png new file mode 100644 index 0000000..a68fe54 Binary files /dev/null and b/tools/linguist/linguist/images/d_prev.png differ diff --git a/tools/linguist/linguist/images/d_prevunfinished.png b/tools/linguist/linguist/images/d_prevunfinished.png new file mode 100644 index 0000000..ce956a7 Binary files /dev/null and b/tools/linguist/linguist/images/d_prevunfinished.png differ diff --git a/tools/linguist/linguist/images/d_print.png b/tools/linguist/linguist/images/d_print.png new file mode 100644 index 0000000..b2791a7 Binary files /dev/null and b/tools/linguist/linguist/images/d_print.png differ diff --git a/tools/linguist/linguist/images/d_punctuation.png b/tools/linguist/linguist/images/d_punctuation.png new file mode 100644 index 0000000..8eebab8 Binary files /dev/null and b/tools/linguist/linguist/images/d_punctuation.png differ diff --git a/tools/linguist/linguist/images/d_redo.png b/tools/linguist/linguist/images/d_redo.png new file mode 100644 index 0000000..6e993cc Binary files /dev/null and b/tools/linguist/linguist/images/d_redo.png differ diff --git a/tools/linguist/linguist/images/d_s_check_danger.png b/tools/linguist/linguist/images/d_s_check_danger.png new file mode 100644 index 0000000..3fadeb1 Binary files /dev/null and b/tools/linguist/linguist/images/d_s_check_danger.png differ diff --git a/tools/linguist/linguist/images/d_s_check_obs.png b/tools/linguist/linguist/images/d_s_check_obs.png new file mode 100644 index 0000000..4836e2f Binary files /dev/null and b/tools/linguist/linguist/images/d_s_check_obs.png differ diff --git a/tools/linguist/linguist/images/d_s_check_off.png b/tools/linguist/linguist/images/d_s_check_off.png new file mode 100644 index 0000000..58f7fb6 Binary files /dev/null and b/tools/linguist/linguist/images/d_s_check_off.png differ diff --git a/tools/linguist/linguist/images/d_s_check_on.png b/tools/linguist/linguist/images/d_s_check_on.png new file mode 100644 index 0000000..4836e2f Binary files /dev/null and b/tools/linguist/linguist/images/d_s_check_on.png differ diff --git a/tools/linguist/linguist/images/d_searchfind.png b/tools/linguist/linguist/images/d_searchfind.png new file mode 100644 index 0000000..e85e33f Binary files /dev/null and b/tools/linguist/linguist/images/d_searchfind.png differ diff --git a/tools/linguist/linguist/images/d_undo.png b/tools/linguist/linguist/images/d_undo.png new file mode 100644 index 0000000..22ac97f Binary files /dev/null and b/tools/linguist/linguist/images/d_undo.png differ diff --git a/tools/linguist/linguist/images/doneandnext.png b/tools/linguist/linguist/images/doneandnext.png new file mode 100644 index 0000000..1cf8888 Binary files /dev/null and b/tools/linguist/linguist/images/doneandnext.png differ diff --git a/tools/linguist/linguist/images/editcopy.png b/tools/linguist/linguist/images/editcopy.png new file mode 100644 index 0000000..804c98c Binary files /dev/null and b/tools/linguist/linguist/images/editcopy.png differ diff --git a/tools/linguist/linguist/images/editcut.png b/tools/linguist/linguist/images/editcut.png new file mode 100644 index 0000000..a911482 Binary files /dev/null and b/tools/linguist/linguist/images/editcut.png differ diff --git a/tools/linguist/linguist/images/editpaste.png b/tools/linguist/linguist/images/editpaste.png new file mode 100644 index 0000000..1938141 Binary files /dev/null and b/tools/linguist/linguist/images/editpaste.png differ diff --git a/tools/linguist/linguist/images/fileopen.png b/tools/linguist/linguist/images/fileopen.png new file mode 100644 index 0000000..3005290 Binary files /dev/null and b/tools/linguist/linguist/images/fileopen.png differ diff --git a/tools/linguist/linguist/images/filesave.png b/tools/linguist/linguist/images/filesave.png new file mode 100644 index 0000000..c137165 Binary files /dev/null and b/tools/linguist/linguist/images/filesave.png differ diff --git a/tools/linguist/linguist/images/next.png b/tools/linguist/linguist/images/next.png new file mode 100644 index 0000000..4b29ff4 Binary files /dev/null and b/tools/linguist/linguist/images/next.png differ diff --git a/tools/linguist/linguist/images/nextunfinished.png b/tools/linguist/linguist/images/nextunfinished.png new file mode 100644 index 0000000..9892b65 Binary files /dev/null and b/tools/linguist/linguist/images/nextunfinished.png differ diff --git a/tools/linguist/linguist/images/pagecurl.png b/tools/linguist/linguist/images/pagecurl.png new file mode 100644 index 0000000..2d3f2ff Binary files /dev/null and b/tools/linguist/linguist/images/pagecurl.png differ diff --git a/tools/linguist/linguist/images/phrase.png b/tools/linguist/linguist/images/phrase.png new file mode 100644 index 0000000..d7dfcb5 Binary files /dev/null and b/tools/linguist/linguist/images/phrase.png differ diff --git a/tools/linguist/linguist/images/prev.png b/tools/linguist/linguist/images/prev.png new file mode 100644 index 0000000..4e3556c Binary files /dev/null and b/tools/linguist/linguist/images/prev.png differ diff --git a/tools/linguist/linguist/images/prevunfinished.png b/tools/linguist/linguist/images/prevunfinished.png new file mode 100644 index 0000000..a3bed54 Binary files /dev/null and b/tools/linguist/linguist/images/prevunfinished.png differ diff --git a/tools/linguist/linguist/images/print.png b/tools/linguist/linguist/images/print.png new file mode 100644 index 0000000..cc083ed Binary files /dev/null and b/tools/linguist/linguist/images/print.png differ diff --git a/tools/linguist/linguist/images/punctuation.png b/tools/linguist/linguist/images/punctuation.png new file mode 100644 index 0000000..849d4a9 Binary files /dev/null and b/tools/linguist/linguist/images/punctuation.png differ diff --git a/tools/linguist/linguist/images/redo.png b/tools/linguist/linguist/images/redo.png new file mode 100644 index 0000000..abdad26 Binary files /dev/null and b/tools/linguist/linguist/images/redo.png differ diff --git a/tools/linguist/linguist/images/s_check_danger.png b/tools/linguist/linguist/images/s_check_danger.png new file mode 100644 index 0000000..7005304 Binary files /dev/null and b/tools/linguist/linguist/images/s_check_danger.png differ diff --git a/tools/linguist/linguist/images/s_check_obs.png b/tools/linguist/linguist/images/s_check_obs.png new file mode 100644 index 0000000..b171b2a Binary files /dev/null and b/tools/linguist/linguist/images/s_check_obs.png differ diff --git a/tools/linguist/linguist/images/s_check_off.png b/tools/linguist/linguist/images/s_check_off.png new file mode 100644 index 0000000..cf45bc0 Binary files /dev/null and b/tools/linguist/linguist/images/s_check_off.png differ diff --git a/tools/linguist/linguist/images/s_check_on.png b/tools/linguist/linguist/images/s_check_on.png new file mode 100644 index 0000000..b5238f7 Binary files /dev/null and b/tools/linguist/linguist/images/s_check_on.png differ diff --git a/tools/linguist/linguist/images/searchfind.png b/tools/linguist/linguist/images/searchfind.png new file mode 100644 index 0000000..3f369fd Binary files /dev/null and b/tools/linguist/linguist/images/searchfind.png differ diff --git a/tools/linguist/linguist/images/splash.png b/tools/linguist/linguist/images/splash.png new file mode 100644 index 0000000..8e80718 Binary files /dev/null and b/tools/linguist/linguist/images/splash.png differ diff --git a/tools/linguist/linguist/images/undo.png b/tools/linguist/linguist/images/undo.png new file mode 100644 index 0000000..839a823 Binary files /dev/null and b/tools/linguist/linguist/images/undo.png differ diff --git a/tools/linguist/linguist/images/whatsthis.xpm b/tools/linguist/linguist/images/whatsthis.xpm new file mode 100644 index 0000000..e45dc26 --- /dev/null +++ b/tools/linguist/linguist/images/whatsthis.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char *magick[] = { +/* columns rows colors chars-per-pixel */ +"16 16 3 1", +" c None", +"o c #000000000000", +"a c #000000008000", +/* pixels */ +"o aaaaa ", +"oo aaa aaa ", +"ooo aaa aaa", +"oooo aa aa", +"ooooo aa aa", +"oooooo a aaa", +"ooooooo aaa ", +"oooooooo aaa ", +"ooooooooo aaa ", +"ooooo aaa ", +"oo ooo ", +"o ooo aaa ", +" ooo aaa ", +" ooo ", +" ooo ", +" ooo "}; diff --git a/tools/linguist/linguist/linguist.icns b/tools/linguist/linguist/linguist.icns new file mode 100644 index 0000000..f51565e Binary files /dev/null and b/tools/linguist/linguist/linguist.icns differ diff --git a/tools/linguist/linguist/linguist.ico b/tools/linguist/linguist/linguist.ico new file mode 100644 index 0000000..2816c7c Binary files /dev/null and b/tools/linguist/linguist/linguist.ico differ diff --git a/tools/linguist/linguist/linguist.pro b/tools/linguist/linguist/linguist.pro new file mode 100644 index 0000000..da4d782 --- /dev/null +++ b/tools/linguist/linguist/linguist.pro @@ -0,0 +1,109 @@ +TEMPLATE = app +LANGUAGE = C++ +CONFIG += qt warn_on + + +SOURCES += finddialog.cpp \ + main.cpp \ + msgedit.cpp \ + phrase.cpp \ + phrasebookbox.cpp \ + phraselv.cpp \ + printout.cpp \ + simtexth.cpp \ + trwindow.cpp \ + listviews.cpp \ + ../shared/metatranslator.cpp +HEADERS += finddialog.h \ + msgedit.h \ + phrase.h \ + phrasebookbox.h \ + phraselv.h \ + printout.h \ + trwindow.h \ + listviews.h \ + ../shared/metatranslator.h + + +TRANSLATIONS = linguist_de.ts \ + linguist_fr.ts + +DEFINES += QT_INTERNAL_XML +include( ../../../src/qt_professional.pri ) + +DESTDIR = ../../../bin +TARGET = linguist + + +LIBS += -L$$QT_BUILD_TREE/lib -lqassistantclient + +win32:RC_FILE = linguist.rc + +mac { + staticlib:CONFIG -= global_init_link_order #yuck + RC_FILE = linguist.icns +} + +PROJECTNAME = Qt Linguist + +target.path=$$bins.path +INSTALLS += target + +linguisttranslations.files = *.qm +linguisttranslations.path = $$translations.path +INSTALLS += linguisttranslations + +phrasebooks.path=$$data.path/phrasebooks +phrasebooks.files = ../phrasebooks/* +INSTALLS += phrasebooks +FORMS = about.ui \ + statistics.ui +IMAGES = images/accelerator.png \ + images/book.png \ + images/s_check_danger.png \ + images/s_check_obs.png \ + images/s_check_off.png \ + images/s_check_on.png \ + images/d_s_check_danger.png \ + images/d_s_check_obs.png \ + images/d_s_check_off.png \ + images/d_s_check_on.png \ + images/d_accelerator.png \ + images/d_book.png \ + images/d_doneandnext.png \ + images/d_editcopy.png \ + images/d_editcut.png \ + images/d_editpaste.png \ + images/d_fileopen.png \ + images/d_filesave.png \ + images/d_next.png \ + images/d_nextunfinished.png \ + images/d_prev.png \ + images/d_prevunfinished.png \ + images/d_phrase.png \ + images/d_print.png \ + images/d_punctuation.png \ + images/d_redo.png \ + images/d_searchfind.png \ + images/d_undo.png \ + images/doneandnext.png \ + images/editcopy.png \ + images/editcut.png \ + images/editpaste.png \ + images/punctuation.png \ + images/fileopen.png \ + images/filesave.png \ + images/appicon.png \ + images/next.png \ + images/nextunfinished.png \ + images/pagecurl.png \ + images/phrase.png \ + images/prev.png \ + images/prevunfinished.png \ + images/print.png \ + images/redo.png \ + images/searchfind.png \ + images/splash.png \ + images/undo.png \ + images/whatsthis.xpm +INCLUDEPATH += ../shared diff --git a/tools/linguist/linguist/linguist.rc b/tools/linguist/linguist/linguist.rc new file mode 100644 index 0000000..865e021 --- /dev/null +++ b/tools/linguist/linguist/linguist.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "linguist.ico" diff --git a/tools/linguist/linguist/linguist_de.ts b/tools/linguist/linguist/linguist_de.ts new file mode 100644 index 0000000..06d818b --- /dev/null +++ b/tools/linguist/linguist/linguist_de.ts @@ -0,0 +1,993 @@ + + + AboutDialog + + Qt Linguist + + + + Copyright (C) 2000-2008 Trolltech ASA. All Rights Reserved. + + + + <p>This program is licensed to you under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation. This gives you legal permission to copy, distribute and/or modify this software under certain conditions. For details, see the file 'LICENSE.GPL' that came with this software distribution. If you did not get the file, send email to info@trolltech.com.</p> +<p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> + + + + OK + + + + + EditorPage + + Source text + + + + Translation + + + + + FindDialog + Choose Edit|Find from the menu bar or press Ctrl+F to pop up the Find dialog + + Fi&nd what: + + + + &Find Next + + + + Cancel + + + + &Match case + + + + This window allows you to search and replace some text in the translations. + + + + Replace &with: + + + + &Replace + + + + Replace &All + + + + Click here to replace the next occurrence of the text you typed in. + + + + Click here to replace all occurrences of the text you typed in. + + + + This window allows you to search for some text in the translation source file. + + + + &Source texts + + + + &Translations + + + + &Comments + + + + Source texts are searched when checked. + + + + Translations are searched when checked. + + + + Comments and contexts are searched when checked. + + + + Type in the text to search for. + + + + Texts such as 'TeX' and 'tex' are considered as different when checked. + + + + Click here to find the next occurrence of the text you typed in. + + + + Click here to close this window. + + + + + MessageEditor + + bell + + + + backspace + + + + new page + + + + new line + + + + carriage return + + + + tab + + + + Source text + + + + Done + + + + Translation + + + + Phrases + + + + Phrases and guesses: + + + + This whole panel allows you to view and edit the translation of some source text. + + + + This area shows the source text. + + + + This area shows a comment that may guide you, and the context in which the text occurs. + + + + This is where you can enter or modify the translation of some source text. + + + + Guess + + + + Guess (%1) + + + + + PageCurl + + Next unfinished phrase + + + + Previous unfinished phrase + + + + + PhraseBookBox + Go to Phrase > Edit Phrase Book... The dialog that pops up is a PhraseBookBox. + + S&ource phrase: + + + + &Translation: + + + + &Definition: + + + + &New Phrase + + + + &Remove Phrase + + + + &Save + + + + Close + + + + This window allows you to add, modify, or delete phrases in a phrase book. + + + + This is the phrase in the source language. + + + + This is the phrase in the target language corresponding to the source phrase. + + + + This is a definition for the source phrase. + + + + Click here to add the phrase to the phrase book. + + + + Click here to remove the phrase from the phrase book. + + + + Click here to save the changes made. + + + + Click here to close this window. + + + + Qt Linguist + + + + Cannot save phrase book '%1'. + + + + + PhraseLV + The phrase list in the right panel of the main window (with Source phrase, Target phrase, and Definition in its header) is a PhraseLV object. + + (New Phrase) + + + + This is a list of phrase entries relevant to the source text. Each phrase is supplemented with a suggested translation and a definition. + + + + <p><u>%1:</u>&nbsp;&nbsp;%2</p><p><u>%3:</u>&nbsp;&nbsp;%4</p><p><u>%5:</u>&nbsp;&nbsp;%6</p> + + + + Source phrase + + + + Translation + + + + Definition + + + + + QObject + + Qt Linguist + + + + + TrWindow + This is the application's main window. + + Context + + + + Done + + + + Items + + + + MOD + + + + Qt Linguist + + + + This panel lists the source contexts. + + + + This panel lists the source texts. Items that violate validation rules are marked with a warning. + + + + Loading... + + + + %1 source phrase(s) loaded. + + + + Cannot open '%1'. + + + + Qt translation source (*.ts) +All files (*) + + + + File saved. + + + + Cannot save '%1'. + + + + Qt message files for released applications (*.qm) +All files (*) + + + + Release + + + + File created. + + + + Printing... + + + + Context: %1 + + + + finished + + + + unresolved + + + + obsolete + + + + Printing... (page %1) + + + + Printing completed + + + + Printing aborted + + + + Search wrapped. + + + + Cannot find the string '%1'. + + + + Qt phrase books (*.qph) +All files (*) + + + + Create New Phrase Book + + + + A file called '%1' already exists. Please choose another name. + + + + Phrase book created. + + + + %1 phrase(s) loaded. + + + + %1 - %2 + + + + Do you want to save '%1'? + + + + Qt Linguist by Trolltech + + + + No phrase to translate. + + + + No untranslated phrases left. + + + + &File + + + + &Edit + + + + &Translation + + + + V&alidation + + + + &Phrases + + + + &View + + + + &Help + + + + &Open... + + + + Ctrl+O + + + + &Save + + + + Ctrl+S + + + + Save &As... + + + + &Release... + + + + &Print... + + + + Ctrl+P + + + + Re&cently opened files + + + + E&xit + + + + Ctrl+Q + + + + &Undo + + + + Ctrl+Z + + + + &Redo + + + + Ctrl+Y + + + + Cu&t + + + + Ctrl+X + + + + &Copy + + + + Ctrl+C + + + + &Paste + + + + Ctrl+V + + + + Select &All + + + + Ctrl+A + + + + &Find... + + + + Ctrl+F + + + + Find &Next + + + + &Replace... + + + + Ctrl+H + + + + &Prev Unfinished + + + + Ctrl+K + + + + &Next Unfinished + + + + Ctrl+L + + + + P&rev + + + + Ctrl+Shift+K + + + + Ne&xt + + + + Ctrl+Shift+L + + + + Done and &Next + + + + Ctrl+Enter + + + + Ctrl+Return + + + + &Begin from Source + + + + Ctrl+B + + + + &New Phrase Book... + + + + Ctrl+N + + + + &Open Phrase Book... + + + + &Close Phrase Book + + + + &Edit Phrase Book... + + + + &Print Phrase Book... + + + + &Accelerators + + + + &Ending Punctuation + + + + &Phrase Matches + + + + &Revert Sorting + + + + &Display guesses + + + + Vie&ws + + + + &Toolbars + + + + &Manual + + + + &About + + + + About &Qt + + + + &What's This? + + + + Open a Qt translation source file (TS file) for editing. + + + + Save changes made to this Qt translation source file. + + + + Save changes made to this Qt translationsource file into a new file. + + + + Create a Qt message file suitable for released applications from the current message file. + + + + Print a list of all the phrases in the current Qt translation source file. + + + + Close this window and exit. + + + + Undo the last editing operation performed on the translation. + + + + Redo an undone editing operation performed on the translation. + + + + Copy the selected translation text to the clipboard and deletes it. + + + + Copy the selected translation text to the clipboard. + + + + Paste the clipboard text into the translation. + + + + Select the whole translation text. + + + + Search for some text in the translation source file. + + + + Continue the search where it was left. + + + + Search for some text in the translation source file and replace it by another text. + + + + Create a new phrase book. + + + + Open a phrase book to assist translation. + + + + Toggle validity checks of accelerators. + + + + Toggle validity checks of ending punctuation. + + + + Toggle checking that phrase suggestions are used. + + + + Sort the items back in the same order as in the message file. + + + + Set whether or not to display translation guesses. + + + + Display the manual for %1. + + + + Display information about %1. + + + + Display information about the Qt toolkit by Trolltech. + + + + Enter What's This? mode. + + + + Copies the source text into the translation field. + + + + Moves to the next item. + + + + Moves to the previous item. + + + + Moves to the next unfinished item. + + + + Moves to the previous unfinished item. + + + + Marks this item as done and moves to the next unfinished item. + + + + File + + + + Edit + + + + Translation + + + + Validation + + + + Help + + + + Open + + + + Save + + + + Print + + + + Open Phrase Book + + + + Undo + + + + Redo + + + + Cut + + + + Copy + + + + Paste + + + + Find + + + + Replace + + + + Prev + + + + Next + + + + Prev Unfinished + + + + Next Unfinished + + + + Done and Next + + + + Accelerators + + + + Punctuation + + + + Phrases + + + + What's This? + + + + Cannot read from phrase book '%1'. + + + + Close this phrase book. + + + + Allow you to add, modify, or delete phrases of this phrase book. + + + + Print the entries of the phrase book. + + + + Cannot create phrase book '%1'. + + + + Accelerator possibly superfluous in translation. + + + + Accelerator possibly missing in translation. + + + + Translation does not end with the same punctuation as the source text. + + + + A phrase book suggestion for '%1' was ignored. + + + + ... + + + + Version %1 + + + + diff --git a/tools/linguist/linguist/linguist_fr.ts b/tools/linguist/linguist/linguist_fr.ts new file mode 100644 index 0000000..06d818b --- /dev/null +++ b/tools/linguist/linguist/linguist_fr.ts @@ -0,0 +1,993 @@ + + + AboutDialog + + Qt Linguist + + + + Copyright (C) 2000-2008 Trolltech ASA. All Rights Reserved. + + + + <p>This program is licensed to you under the terms of the GNU General Public License Version 2 as published by the Free Software Foundation. This gives you legal permission to copy, distribute and/or modify this software under certain conditions. For details, see the file 'LICENSE.GPL' that came with this software distribution. If you did not get the file, send email to info@trolltech.com.</p> +<p>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</p> + + + + OK + + + + + EditorPage + + Source text + + + + Translation + + + + + FindDialog + Choose Edit|Find from the menu bar or press Ctrl+F to pop up the Find dialog + + Fi&nd what: + + + + &Find Next + + + + Cancel + + + + &Match case + + + + This window allows you to search and replace some text in the translations. + + + + Replace &with: + + + + &Replace + + + + Replace &All + + + + Click here to replace the next occurrence of the text you typed in. + + + + Click here to replace all occurrences of the text you typed in. + + + + This window allows you to search for some text in the translation source file. + + + + &Source texts + + + + &Translations + + + + &Comments + + + + Source texts are searched when checked. + + + + Translations are searched when checked. + + + + Comments and contexts are searched when checked. + + + + Type in the text to search for. + + + + Texts such as 'TeX' and 'tex' are considered as different when checked. + + + + Click here to find the next occurrence of the text you typed in. + + + + Click here to close this window. + + + + + MessageEditor + + bell + + + + backspace + + + + new page + + + + new line + + + + carriage return + + + + tab + + + + Source text + + + + Done + + + + Translation + + + + Phrases + + + + Phrases and guesses: + + + + This whole panel allows you to view and edit the translation of some source text. + + + + This area shows the source text. + + + + This area shows a comment that may guide you, and the context in which the text occurs. + + + + This is where you can enter or modify the translation of some source text. + + + + Guess + + + + Guess (%1) + + + + + PageCurl + + Next unfinished phrase + + + + Previous unfinished phrase + + + + + PhraseBookBox + Go to Phrase > Edit Phrase Book... The dialog that pops up is a PhraseBookBox. + + S&ource phrase: + + + + &Translation: + + + + &Definition: + + + + &New Phrase + + + + &Remove Phrase + + + + &Save + + + + Close + + + + This window allows you to add, modify, or delete phrases in a phrase book. + + + + This is the phrase in the source language. + + + + This is the phrase in the target language corresponding to the source phrase. + + + + This is a definition for the source phrase. + + + + Click here to add the phrase to the phrase book. + + + + Click here to remove the phrase from the phrase book. + + + + Click here to save the changes made. + + + + Click here to close this window. + + + + Qt Linguist + + + + Cannot save phrase book '%1'. + + + + + PhraseLV + The phrase list in the right panel of the main window (with Source phrase, Target phrase, and Definition in its header) is a PhraseLV object. + + (New Phrase) + + + + This is a list of phrase entries relevant to the source text. Each phrase is supplemented with a suggested translation and a definition. + + + + <p><u>%1:</u>&nbsp;&nbsp;%2</p><p><u>%3:</u>&nbsp;&nbsp;%4</p><p><u>%5:</u>&nbsp;&nbsp;%6</p> + + + + Source phrase + + + + Translation + + + + Definition + + + + + QObject + + Qt Linguist + + + + + TrWindow + This is the application's main window. + + Context + + + + Done + + + + Items + + + + MOD + + + + Qt Linguist + + + + This panel lists the source contexts. + + + + This panel lists the source texts. Items that violate validation rules are marked with a warning. + + + + Loading... + + + + %1 source phrase(s) loaded. + + + + Cannot open '%1'. + + + + Qt translation source (*.ts) +All files (*) + + + + File saved. + + + + Cannot save '%1'. + + + + Qt message files for released applications (*.qm) +All files (*) + + + + Release + + + + File created. + + + + Printing... + + + + Context: %1 + + + + finished + + + + unresolved + + + + obsolete + + + + Printing... (page %1) + + + + Printing completed + + + + Printing aborted + + + + Search wrapped. + + + + Cannot find the string '%1'. + + + + Qt phrase books (*.qph) +All files (*) + + + + Create New Phrase Book + + + + A file called '%1' already exists. Please choose another name. + + + + Phrase book created. + + + + %1 phrase(s) loaded. + + + + %1 - %2 + + + + Do you want to save '%1'? + + + + Qt Linguist by Trolltech + + + + No phrase to translate. + + + + No untranslated phrases left. + + + + &File + + + + &Edit + + + + &Translation + + + + V&alidation + + + + &Phrases + + + + &View + + + + &Help + + + + &Open... + + + + Ctrl+O + + + + &Save + + + + Ctrl+S + + + + Save &As... + + + + &Release... + + + + &Print... + + + + Ctrl+P + + + + Re&cently opened files + + + + E&xit + + + + Ctrl+Q + + + + &Undo + + + + Ctrl+Z + + + + &Redo + + + + Ctrl+Y + + + + Cu&t + + + + Ctrl+X + + + + &Copy + + + + Ctrl+C + + + + &Paste + + + + Ctrl+V + + + + Select &All + + + + Ctrl+A + + + + &Find... + + + + Ctrl+F + + + + Find &Next + + + + &Replace... + + + + Ctrl+H + + + + &Prev Unfinished + + + + Ctrl+K + + + + &Next Unfinished + + + + Ctrl+L + + + + P&rev + + + + Ctrl+Shift+K + + + + Ne&xt + + + + Ctrl+Shift+L + + + + Done and &Next + + + + Ctrl+Enter + + + + Ctrl+Return + + + + &Begin from Source + + + + Ctrl+B + + + + &New Phrase Book... + + + + Ctrl+N + + + + &Open Phrase Book... + + + + &Close Phrase Book + + + + &Edit Phrase Book... + + + + &Print Phrase Book... + + + + &Accelerators + + + + &Ending Punctuation + + + + &Phrase Matches + + + + &Revert Sorting + + + + &Display guesses + + + + Vie&ws + + + + &Toolbars + + + + &Manual + + + + &About + + + + About &Qt + + + + &What's This? + + + + Open a Qt translation source file (TS file) for editing. + + + + Save changes made to this Qt translation source file. + + + + Save changes made to this Qt translationsource file into a new file. + + + + Create a Qt message file suitable for released applications from the current message file. + + + + Print a list of all the phrases in the current Qt translation source file. + + + + Close this window and exit. + + + + Undo the last editing operation performed on the translation. + + + + Redo an undone editing operation performed on the translation. + + + + Copy the selected translation text to the clipboard and deletes it. + + + + Copy the selected translation text to the clipboard. + + + + Paste the clipboard text into the translation. + + + + Select the whole translation text. + + + + Search for some text in the translation source file. + + + + Continue the search where it was left. + + + + Search for some text in the translation source file and replace it by another text. + + + + Create a new phrase book. + + + + Open a phrase book to assist translation. + + + + Toggle validity checks of accelerators. + + + + Toggle validity checks of ending punctuation. + + + + Toggle checking that phrase suggestions are used. + + + + Sort the items back in the same order as in the message file. + + + + Set whether or not to display translation guesses. + + + + Display the manual for %1. + + + + Display information about %1. + + + + Display information about the Qt toolkit by Trolltech. + + + + Enter What's This? mode. + + + + Copies the source text into the translation field. + + + + Moves to the next item. + + + + Moves to the previous item. + + + + Moves to the next unfinished item. + + + + Moves to the previous unfinished item. + + + + Marks this item as done and moves to the next unfinished item. + + + + File + + + + Edit + + + + Translation + + + + Validation + + + + Help + + + + Open + + + + Save + + + + Print + + + + Open Phrase Book + + + + Undo + + + + Redo + + + + Cut + + + + Copy + + + + Paste + + + + Find + + + + Replace + + + + Prev + + + + Next + + + + Prev Unfinished + + + + Next Unfinished + + + + Done and Next + + + + Accelerators + + + + Punctuation + + + + Phrases + + + + What's This? + + + + Cannot read from phrase book '%1'. + + + + Close this phrase book. + + + + Allow you to add, modify, or delete phrases of this phrase book. + + + + Print the entries of the phrase book. + + + + Cannot create phrase book '%1'. + + + + Accelerator possibly superfluous in translation. + + + + Accelerator possibly missing in translation. + + + + Translation does not end with the same punctuation as the source text. + + + + A phrase book suggestion for '%1' was ignored. + + + + ... + + + + Version %1 + + + + diff --git a/tools/linguist/linguist/listviews.cpp b/tools/linguist/linguist/listviews.cpp new file mode 100644 index 0000000..6bf67fd --- /dev/null +++ b/tools/linguist/linguist/listviews.cpp @@ -0,0 +1,350 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "listviews.h" + +#include + +static const int Text0MaxLen = 150; +static const int Text1MaxLen = 150; + +/* + LVI implementation +*/ + +static QString rho( int n ) +{ + QString s; + s.sprintf( "%.10d", n ); + return s; +} + +int LVI::count = 0; + +LVI::LVI( QListView * parent, QString text ) + : QListViewItem( parent, text ) +{ + setText( 0, rho(count++) ); +} + +LVI::LVI( QListViewItem * parent, QString text ) + : QListViewItem( parent, text ) +{ + setText( 0, rho(count++) ); +} + +/* + This is a cut-down version of QListViewItem::paintCell() - + it is needed to produce the effect we want on obsolete items + */ +void LVI::drawObsoleteText( QPainter * p, const QColorGroup & cg, int column, + int width, int align ) +{ + QListView * lv = listView(); + int marg = lv ? lv->itemMargin() : 1; + int r = marg; + p->fillRect( 0, 0, width, height(), cg.brush( QColorGroup::Base ) ); + if ( isSelected() && (column==0 || listView()->allColumnsShowFocus()) ) + p->fillRect( r - marg, 0, width - r + marg, height(), + cg.brush( QColorGroup::Highlight ) ); + + // Do the ellipsis thingy + QString t = text( column ); + QString tmp; + int i = 0; + if ( p->fontMetrics().width( t ) > width ) { + tmp = "..."; + while ( p->fontMetrics().width( tmp + t[i] ) < width ) + tmp += t[ i++ ]; + tmp.remove( (uint)0, 3 ); + if ( tmp.isEmpty() ) + tmp = t.left( 1 ); + tmp += "..."; + t = tmp; + } + if ( isSelected() ) + p->setPen( lv->palette().disabled().highlightedText() ); + else + p->setPen( lv->palette().disabled().text() ); + + if ( !t.isEmpty() ) { + p->drawText( r, 0, width-marg-r, height(), + align | AlignVCenter | SingleLine, t ); + } + +} + +int LVI::compare( QListViewItem *other, int column, bool ascending ) const +{ + QString thisKey = key( column, ascending ); + QString otherKey = other->key( column, ascending ); + + if ( thisKey.contains('&') || otherKey.contains('&') ) { + QString nicerThisKey = thisKey; + QString nicerOtherKey = otherKey; + + nicerThisKey.replace( "&", "" ); + nicerOtherKey.replace( "&", "" ); + + int delta = nicerThisKey.localeAwareCompare( nicerOtherKey ); + if ( delta != 0 ) + return delta; + } + return thisKey.localeAwareCompare( otherKey ); +} + +static QString fixEllipsis( const QString & str, int len ) +{ + QString shortened = str.simplifyWhiteSpace(); + if ( (int) shortened.length() > len ) { + QString dots = TrWindow::tr( "..." ); + shortened.truncate( len - dots.length() ); + shortened.append( dots ); + } + return shortened; +} + +/* + MessageLVI implementation +*/ +MessageLVI::MessageLVI( QListView *parent, + const MetaTranslatorMessage & message, + const QString& text, const QString& comment, + ContextLVI * c ) + : LVI( parent ), m( message ), tx( text ), com( comment ), ctxt( c ) +{ + if ( m.translation().isEmpty() ) { + QString t = ""; + m.setTranslation( t ); + } + setText( 1, fixEllipsis( text, Text0MaxLen ) ); + fini = TRUE; + d = FALSE; + + if( m.type() == MetaTranslatorMessage::Unfinished ) + setFinished( FALSE ); +} + +void MessageLVI::updateTranslationText() +{ + setText( 2, fixEllipsis( m.translation(), Text1MaxLen ) ); +} + +void MessageLVI::paintCell( QPainter * p, const QColorGroup & cg, int column, + int width, int align ) +{ + if ( column == 0 ) { + int x = (width/2) - TrWindow::pxOn->width()/2; + int y = (height()/2) - TrWindow::pxOn->height()/2; + + int marg = listView() ? listView()->itemMargin() : 1; + int r = marg; + + if ( isSelected() ) + p->fillRect( r - marg, 0, width - r + marg, height(), + cg.brush( QColorGroup::Highlight ) ); + else + p->fillRect( 0, 0, width, height(), + cg.brush( QColorGroup::Base ) ); + + if ( m.type() == MetaTranslatorMessage::Unfinished && danger() ) + p->drawPixmap( x, y, *TrWindow::pxDanger ); + else if ( m.type() == MetaTranslatorMessage::Finished ) + p->drawPixmap( x, y, *TrWindow::pxOn ); + else if ( m.type() == MetaTranslatorMessage::Unfinished ) + p->drawPixmap( x, y, *TrWindow::pxOff ); + else if ( m.type() == MetaTranslatorMessage::Obsolete ) + p->drawPixmap( x, y, *TrWindow::pxObsolete ); + } else { + if ( m.type() == MetaTranslatorMessage::Obsolete ) + drawObsoleteText( p, cg, column, width, align ); + else + QListViewItem::paintCell( p, cg, column, width, align ); + } +} + + +void MessageLVI::setTranslation( const QString& translation ) +{ + m.setTranslation( translation ); +} + +void MessageLVI::setFinished( bool finished ) +{ + if ( !fini && finished ) { + m.setType( MetaTranslatorMessage::Finished ); + repaint(); + ctxt->decrementUnfinishedCount(); + } else if ( fini && !finished ) { + m.setType( MetaTranslatorMessage::Unfinished ); + repaint(); + ctxt->incrementUnfinishedCount(); + } + fini = finished; +} + +void MessageLVI::setDanger( bool danger ) +{ + if ( !d && danger ) { + ctxt->incrementDangerCount(); + repaint(); + } else if ( d && !danger ) { + ctxt->decrementDangerCount(); + repaint(); + } + d = danger; +} + +QString MessageLVI::context() const +{ + return QString( m.context() ); +} + +MetaTranslatorMessage MessageLVI::message() const +{ + return m; +} + +/* + ContextLVI implementation +*/ +ContextLVI::ContextLVI( QListView *lv, const QString& context ) + : LVI( lv ), com( "" ) +{ + messageItems.setAutoDelete( TRUE ); + + unfinishedCount = 0; + dangerCount = 0; + obsoleteCount = 0; + itemCount = 0; + setText( 1, context ); +} + +void ContextLVI::instantiateMessageItem( QListView * lv, MessageLVI * i ) +{ + itemCount++; + appendMessageItem( lv, i ); +} + +void ContextLVI::appendMessageItem( QListView * lv, MessageLVI * i ) +{ + lv->takeItem( i ); + messageItems.append( i ); +} + +void ContextLVI::updateStatus() +{ + QString s; + s.sprintf( "%d/%d", itemCount - unfinishedCount - obsoleteCount, + itemCount - obsoleteCount ); + setText( 2, s ); +} + +void ContextLVI::paintCell( QPainter * p, const QColorGroup & cg, int column, + int width, int align ) +{ + if ( column == 0 ) { + int x = (width/2) - TrWindow::pxOn->width()/2; + int y = (height()/2) - TrWindow::pxOn->height()/2; + + int marg = listView() ? listView()->itemMargin() : 1; + int r = marg; + + if ( isSelected() ) + p->fillRect( r - marg, 0, width - r + marg, height(), + cg.brush( QColorGroup::Highlight ) ); + else + p->fillRect( 0, 0, width, height(), + cg.brush( QColorGroup::Base ) ); + + if ( isContextObsolete() ) + p->drawPixmap( x, y, *TrWindow::pxObsolete ); + else if ( unfinishedCount == 0 ) + p->drawPixmap( x, y, *TrWindow::pxOn ); + else + p->drawPixmap( x, y, *TrWindow::pxOff ); + + } else { + if ( isContextObsolete() ) + drawObsoleteText( p, cg, column, width, align ); + else + QListViewItem::paintCell( p, cg, column, width, align ); + } +} + +void ContextLVI::appendToComment( const QString& x ) +{ + if ( !com.isEmpty() ) + com += QString( "\n\n" ); + com += x; +} + +void ContextLVI::incrementUnfinishedCount() +{ + if ( unfinishedCount++ == 0 ) + repaint(); +} + +void ContextLVI::decrementUnfinishedCount() +{ + if ( --unfinishedCount == 0 ) + repaint(); +} + +void ContextLVI::incrementDangerCount() +{ + if ( dangerCount++ == 0 ) + repaint(); +} + +void ContextLVI::decrementDangerCount() +{ + if ( --dangerCount == 0 ) + repaint(); +} + +void ContextLVI::incrementObsoleteCount() +{ + if ( obsoleteCount++ == 0 ) + repaint(); +} + +bool ContextLVI::isContextObsolete() +{ + return (obsoleteCount == itemCount); +} + +QString ContextLVI::fullContext() const +{ + return comment().stripWhiteSpace(); +} diff --git a/tools/linguist/linguist/listviews.h b/tools/linguist/linguist/listviews.h new file mode 100644 index 0000000..f843aa3 --- /dev/null +++ b/tools/linguist/linguist/listviews.h @@ -0,0 +1,135 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LISTVIEWS_H +#define LISTVIEWS_H + +#include "msgedit.h" + +#include +#include +#include +#include + +class LVI : public QListViewItem +{ +public: + LVI( QListView *parent, QString text = QString::null ); + LVI( QListViewItem *parent, QString text = QString::null ); + virtual int compare( QListViewItem *other, int column, + bool ascending ) const; + virtual bool danger() const { return FALSE; } + +protected: + void drawObsoleteText( QPainter * p, const QColorGroup & cg, int column, + int width, int align ); + +private: + static int count; +}; + +class MessageLVI; +class ContextLVI : public LVI +{ +public: + ContextLVI( QListView *lv, const QString& context ); + + virtual bool danger() const { return dangerCount > 0; } + + void appendToComment( const QString& x ); + void incrementUnfinishedCount(); + void decrementUnfinishedCount(); + void incrementDangerCount(); + void decrementDangerCount(); + void incrementObsoleteCount(); + bool isContextObsolete(); + void updateStatus(); + + QString context() const { return text( 1 ); } + QString comment() const { return com; } + QString fullContext() const; + bool finished() const { return unfinishedCount == 0; } + + MessageLVI * firstMessageItem() { return messageItems.first(); } + MessageLVI * nextMessageItem() { return messageItems.next(); } + MessageLVI * takeMessageItem( int i ) { return messageItems.take( i ); } + void appendMessageItem( QListView * lv, MessageLVI * i ); + void instantiateMessageItem( QListView * lv, MessageLVI * i ); + int messageItemsInList() { return messageItems.count(); } + + void paintCell( QPainter * p, const QColorGroup & cg, int column, + int width, int align ); +private: + QPtrList messageItems; + QString com; + int unfinishedCount; + int dangerCount; + int obsoleteCount; + int itemCount; +}; + +class MessageLVI : public LVI +{ +public: + MessageLVI( QListView *parent, const MetaTranslatorMessage & message, + const QString& text, const QString& comment, ContextLVI * c ); + + virtual bool danger() const { return d; } + + void setTranslation( const QString& translation ); + void setFinished( bool finished ); + void setDanger( bool danger ); + + void setContextLVI( ContextLVI * c ) { ctxt = c; } + ContextLVI * contextLVI() const { return ctxt; } + void updateTranslationText(); + + QString context() const; + QString sourceText() const { return tx; } + QString comment() const { return com; } + QString translation() const { return m.translation(); } + bool finished() const { return fini; } + MetaTranslatorMessage message() const; + + void paintCell( QPainter * p, const QColorGroup & cg, int column, + int width, int align ); +private: + MetaTranslatorMessage m; + QString tx; + QString com; + bool fini; + bool d; + ContextLVI * ctxt; +}; + +#endif diff --git a/tools/linguist/linguist/main.cpp b/tools/linguist/linguist/main.cpp new file mode 100644 index 0000000..e9490af --- /dev/null +++ b/tools/linguist/linguist/main.cpp @@ -0,0 +1,89 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "trwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + QApplication::setOverrideCursor( Qt::waitCursor ); + + + QTranslator translator( 0 ); + translator.load( QString( "linguist_" ) + QTextCodec::locale(), "." ); + app.installTranslator( &translator ); + + bool showSplash = TRUE; + + QString keybase("/Qt Linguist/3.1/"); + QSettings config; + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + QRect r( QApplication::desktop()->screenGeometry() ); + r.setX( config.readNumEntry( keybase + "Geometry/MainwindowX", r.x() ) ); + r.setY( config.readNumEntry( keybase + "Geometry/MainwindowY", r.y() ) ); + r.setWidth( config.readNumEntry( keybase + "Geometry/MainwindowWidth", r.width() ) ); + r.setHeight( config.readNumEntry( keybase + "Geometry/MainwindowHeight", r.height() ) ); + + QSplashScreen *splash = 0; + if ( showSplash ) { + splash = new QSplashScreen( QPixmap::fromMimeSource("splash.png"), + Qt::WDestructiveClose ); + splash->show(); + } + + TrWindow *tw = new TrWindow; + app.setMainWidget( tw ); + + if ( app.argc() > 1 ) + tw->openFile( QString(app.argv()[app.argc() - 1]) ); + + if ( config.readBoolEntry( keybase + "Geometry/MainwindowMaximized", FALSE ) ) + tw->showMaximized(); + else + tw->show(); + if ( splash ) + splash->finish( tw ); + QApplication::restoreOverrideCursor(); + + return app.exec(); +} diff --git a/tools/linguist/linguist/msgedit.cpp b/tools/linguist/linguist/msgedit.cpp new file mode 100644 index 0000000..09e60a1 --- /dev/null +++ b/tools/linguist/linguist/msgedit.cpp @@ -0,0 +1,834 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +/* TRANSLATOR MsgEdit + + This is the right panel of the main window. +*/ + +#include "msgedit.h" + +#include "trwindow.h" +#include "phraselv.h" +#include "simtexth.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const int MaxCandidates = 5; + +class MED : public QTextEdit +{ +public: + MED( QWidget *parent, const char *name = 0 ) + : QTextEdit( parent, name ) {} + + int cursorX() const { return textCursor()->x(); } + int cursorY() const { return textCursor()->paragraph()->rect().y() + + textCursor()->y(); } +}; + + +QString richMeta( const QString& text ) +{ + return QString( "(" ) + text + + QString( ")" ); +} + +QString richText( const QString& text ) +{ + const char backTab[] = "\a\b\f\n\r\t"; + const char * const friendlyBackTab[] = { + QT_TRANSLATE_NOOP( "MessageEditor", "bell" ), + QT_TRANSLATE_NOOP( "MessageEditor", "backspace" ), + QT_TRANSLATE_NOOP( "MessageEditor", "new page" ), + QT_TRANSLATE_NOOP( "MessageEditor", "new line" ), + QT_TRANSLATE_NOOP( "MessageEditor", "carriage return" ), + QT_TRANSLATE_NOOP( "MessageEditor", "tab" ) + }; + QString rich; + + for ( int i = 0; i < (int) text.length(); i++ ) { + int ch = text[i].unicode(); + + if ( ch < 0x20 ) { + const char *p = strchr( backTab, ch ); + if ( p == 0 ) + rich += richMeta( QString::number(ch, 16) ); + else + rich += richMeta( MessageEditor::tr(friendlyBackTab[p - backTab]) ); + } else if ( ch == '<' ) { + rich += QString( "<" ); + } else if ( ch == '>' ) { + rich += QString( ">" ); + } else if ( ch == '&' ) { + rich += QString( "&" ); + } else if ( ch == ' ' ) { + if ( i == 0 || i == (text.length()-1) || text[i - 1] == ' ' || text[i + 1] == ' ' ) { + rich += richMeta( MessageEditor::tr("sp") ); + } else { + rich += ' '; + } + } else { + rich += QChar( ch ); + } + if ( ch == '\n' ) + rich += QString( "
    " ); + } + return rich; +} + +/* + ShadowWidget class impl. + + Used to create a shadow like effect for a widget +*/ +ShadowWidget::ShadowWidget( QWidget * parent, const char * name ) + : QWidget( parent, name ), sWidth( 10 ), wMargin( 3 ), childWgt( 0 ) +{ +} + +ShadowWidget::ShadowWidget( QWidget * child, QWidget * parent, + const char * name ) + : QWidget( parent, name ), sWidth( 10 ), wMargin( 3 ), childWgt( 0 ) +{ + setWidget( child ); +} + +void ShadowWidget::setWidget( QWidget * child ) +{ + childWgt = child; + if ( childWgt && childWgt->parent() != this ) { + childWgt->reparent( this, QPoint( 0, 0 ), TRUE ); + } +} + +void ShadowWidget::resizeEvent( QResizeEvent * ) +{ + if( childWgt ) { + childWgt->move( wMargin, wMargin ); + childWgt->resize( width() - sWidth - wMargin, height() - sWidth - + wMargin ); + } +} + +void ShadowWidget::paintEvent( QPaintEvent * e ) +{ + QPainter p; + int w = width() - sWidth; + int h = height() - sWidth; + + + if ( !((w > 0) && (h > 0)) ) + return; + + if ( p.begin( this ) ) { + p.setPen( colorGroup().shadow() ); + + p.drawPoint( w + 5, 6 ); + p.drawLine( w + 3, 6, w + 5, 8 ); + p.drawLine( w + 1, 6, w + 5, 10 ); + int i; + for( i=7; i < h; i += 2 ) + p.drawLine( w, i, w + 5, i + 5 ); + for( i = w - i + h; i > 6; i -= 2 ) + p.drawLine( i, h, i + 5, h + 5 ); + for( ; i > 0 ; i -= 2 ) + p.drawLine( 6, h + 6 - i, i + 5, h + 5 ); + +// p.eraseRect( w, 0, sWidth, 45 ); // Cheap hack for the page curl.. + p.end(); + } + QWidget::paintEvent( e ); +} + +/* + EditorPage class impl. + + A frame that contains the source text, translated text and any + source code comments and hints. +*/ +EditorPage::EditorPage( QWidget * parent, const char * name ) + : QFrame( parent, name ) +{ + setLineWidth( 1 ); + setFrameStyle( QFrame::Box | QFrame::Plain ); + + // Use white explicitly as the background color for the editor page. + QPalette p = palette(); + p.setColor( QPalette::Active, QColorGroup::Base, QColor( white ) ); + p.setColor( QPalette::Inactive, QColorGroup::Base, QColor( white ) ); + p.setColor( QPalette::Disabled, QColorGroup::Base, QColor( white ) ); + p.setColor( QPalette::Active, QColorGroup::Background, + p.active().color( QColorGroup::Base ) ); + p.setColor( QPalette::Inactive, QColorGroup::Background, + p.inactive().color( QColorGroup::Base ) ); + p.setColor( QPalette::Disabled, QColorGroup::Background, + p.disabled().color( QColorGroup::Base ) ); + setPalette( p ); + + srcTextLbl = new QLabel( tr("Source text"), this, "source text label" ); + transLbl = new QLabel( tr("Translation"), this, "translation label" ); + + QFont fnt = font(); + fnt.setBold( TRUE ); + srcTextLbl->setFont( fnt ); + transLbl->setFont( fnt ); + + srcText = new QTextView( this, "source text view" ); + srcText->setFrameStyle( QFrame::NoFrame ); + srcText->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, + QSizePolicy::Minimum ) ); + srcText->setResizePolicy( QScrollView::AutoOne ); + srcText->setHScrollBarMode( QScrollView::AlwaysOff ); + srcText->setVScrollBarMode( QScrollView::AlwaysOff ); + p = srcText->palette(); + p.setColor( QPalette::Disabled, QColorGroup::Base, p.active().base() ); + srcText->setPalette( p ); + connect( srcText, SIGNAL(textChanged()), SLOT(handleSourceChanges()) ); + + cmtText = new QTextView( this, "comment/context view" ); + cmtText->setFrameStyle( QFrame::NoFrame ); + cmtText->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, + QSizePolicy::Minimum ) ); + cmtText->setResizePolicy( QScrollView::AutoOne ); + cmtText->setHScrollBarMode( QScrollView::AlwaysOff ); + cmtText->setVScrollBarMode( QScrollView::AlwaysOff ); + p = cmtText->palette(); + p.setColor( QPalette::Active, QColorGroup::Base, QColor( 236,245,255 ) ); + p.setColor( QPalette::Inactive, QColorGroup::Base, QColor( 236,245,255 ) ); + cmtText->setPalette( p ); + connect( cmtText, SIGNAL(textChanged()), SLOT(handleCommentChanges()) ); + + translationMed = new MED( this, "translation editor" ); + translationMed->setFrameStyle( QFrame::NoFrame ); + translationMed->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, + QSizePolicy::MinimumExpanding ) ); + translationMed->setHScrollBarMode( QScrollView::AlwaysOff ); + translationMed->setVScrollBarMode( QScrollView::AlwaysOff ); + translationMed->setResizePolicy( QScrollView::AutoOne ); + translationMed->setWrapPolicy( QTextView::AtWhiteSpace ); + translationMed->setWordWrap( QTextView::WidgetWidth ); + translationMed->setTextFormat( QTextView::PlainText ); + p = translationMed->palette(); + p.setColor( QPalette::Disabled, QColorGroup::Base, p.active().base() ); + translationMed->setPalette( p ); + connect( translationMed, SIGNAL(textChanged()), + SLOT(handleTranslationChanges()) ); + + pageCurl = new PageCurl( this, "page curl" ); + + // Focus + setFocusPolicy( StrongFocus ); + transLbl->setFocusProxy( translationMed ); + srcTextLbl->setFocusProxy( translationMed ); + cmtText->setFocusProxy( translationMed ); + srcText->setFocusProxy( translationMed ); + setFocusProxy( translationMed ); + + updateCommentField(); +} + +/* + Don't show the comment field if there are no comments. +*/ +void EditorPage::updateCommentField() +{ + if( cmtText->text().isEmpty() ) + cmtText->hide(); + else + cmtText->show(); + + layoutWidgets(); +} + +/* + Handle the widget layout manually +*/ +void EditorPage::layoutWidgets() + { + int margin = 6; + int space = 2; + int w = width(); + + pageCurl->move( width() - pageCurl->width(), 0 ); + + QFontMetrics fm( srcTextLbl->font() ); + srcTextLbl->move( margin, margin ); + srcTextLbl->resize( fm.width( srcTextLbl->text() ), srcTextLbl->height() ); + + srcText->move( margin, srcTextLbl->y() + srcTextLbl->height() + space ); + srcText->resize( w - margin*2, srcText->height() ); + + cmtText->move( margin, srcText->y() + srcText->height() + space ); + cmtText->resize( w - margin*2, cmtText->height() ); + + if( cmtText->isHidden() ) + transLbl->move( margin, srcText->y() + srcText->height() + space ); + else + transLbl->move( margin, cmtText->y() + cmtText->height() + space ); + transLbl->resize( w - margin*2, transLbl->height() ); + + translationMed->move( margin, transLbl->y() + transLbl->height() + space ); + translationMed->resize( w - margin*2, translationMed->height() ); + + // Calculate the total height for the editor page - emit a signal + // if the actual page size is larger/smaller + int totHeight = margin + srcTextLbl->height() + + srcText->height() + space + + transLbl->height() + space + + translationMed->height() + space + + frameWidth()*lineWidth()*2 + space * 3; + + if( !cmtText->isHidden() ) + totHeight += cmtText->height() + space; + + if( height() != totHeight ) + emit pageHeightUpdated( totHeight ); +} + +void EditorPage::resizeEvent( QResizeEvent * ) +{ + handleTranslationChanges(); + handleSourceChanges(); + handleCommentChanges(); + layoutWidgets(); +} + +void EditorPage::handleTranslationChanges() +{ + calculateFieldHeight( (QTextView *) translationMed ); +} + +void EditorPage::handleSourceChanges() +{ + calculateFieldHeight( srcText ); +} + +void EditorPage::handleCommentChanges() +{ + calculateFieldHeight( cmtText ); +} + +/* + Check if the translation text field is big enough to show all text + that has been entered. If it isn't, resize it. +*/ +void EditorPage::calculateFieldHeight( QTextView * field ) +{ + field->sync(); // make sure the text formatting is done! + int contentsHeight = field->contentsHeight(); + + if( contentsHeight != field->height() ) { + int oldHeight = field->height(); + if( contentsHeight < 30 ) + contentsHeight = 30; + field->resize( field->width(), contentsHeight ); + emit pageHeightUpdated( height() + (field->height() - oldHeight) ); + } +} + +void EditorPage::fontChange( const QFont & ) +{ + QFont fnt = font(); + + fnt.setBold( TRUE ); + QFontMetrics fm( fnt ); + srcTextLbl->setFont( fnt ); + srcTextLbl->resize( fm.width( srcTextLbl->text() ), srcTextLbl->height() ); + transLbl->setFont( fnt ); + transLbl->resize( fm.width( transLbl->text() ), transLbl->height() ); + update(); +} + +/* + MessageEditor class impl. + + Handle layout of dock windows and the editor page. +*/ +MessageEditor::MessageEditor( MetaTranslator * t, QWidget * parent, + const char * name ) + : QWidget( parent, name ), + tor( t ) +{ + doGuesses = TRUE; + v = new QVBoxLayout( this ); + topDock = new QDockArea( Qt::Horizontal, QDockArea::Normal, this, + "top dock area" ); + topDock->setMinimumHeight( 10 ); + topDock->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, + QSizePolicy::Minimum) ); + + topDockWnd = new QDockWindow( QDockWindow::InDock, topDock, + "top dock window" ); + QMainWindow *mw = (QMainWindow*)topLevelWidget(); + if ( mw ) { + mw->setDockEnabled( topDockWnd, Qt::DockTop, TRUE ); + mw->setDockEnabled( topDockWnd, Qt::DockLeft, TRUE ); + mw->setDockEnabled( topDockWnd, Qt::DockRight, TRUE ); + mw->setDockEnabled( topDockWnd, Qt::DockBottom, TRUE ); + } + + topDockWnd->setCaption( tr("Source text") ); + topDockWnd->setCloseMode( QDockWindow::Always ); + topDockWnd->setResizeEnabled( TRUE ); + topDockWnd->setFixedExtentHeight( 110 ); + + srcTextList = new QListView( topDockWnd, "source text list view" ); + srcTextList->setShowSortIndicator( TRUE ); + srcTextList->setAllColumnsShowFocus( TRUE ); + srcTextList->setSorting( 0 ); + QFontMetrics fm( font() ); + srcTextList->addColumn( tr("Done"), fm.width( tr("Done") ) + 10 ); + srcTextList->addColumn( tr("Source text") ); + srcTextList->addColumn( tr("Translation"), 300 ); + srcTextList->setColumnAlignment( 0, Qt::AlignCenter ); + srcTextList->setColumnWidthMode( 1, QListView::Manual ); + srcTextList->header()->setStretchEnabled( TRUE, 1 ); + srcTextList->setMinimumSize( QSize( 50, 50 ) ); + srcTextList->setHScrollBarMode( QScrollView::AlwaysOff ); + srcTextList->installEventFilter( this ); + topDockWnd->setWidget( srcTextList ); + + sv = new QScrollView( this, "scroll view" ); + sv->setHScrollBarMode( QScrollView::AlwaysOff ); + sv->viewport()->setBackgroundMode( PaletteBackground ); + + editorPage = new EditorPage( sv, "editor page" ); + connect( editorPage, SIGNAL(pageHeightUpdated(int)), + SLOT(updatePageHeight(int)) ); + + editorPage->translationMed->installEventFilter( this ); + + sw = new ShadowWidget( editorPage, sv, "editor page shadow" ); + sw->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, + QSizePolicy::Expanding) ); + sw->setMinimumSize( QSize( 100, 150 ) ); + sv->addChild( sw ); + + bottomDock = new QDockArea( Qt::Horizontal, QDockArea::Reverse, + this, "bottom dock area" ); + bottomDock->setMinimumHeight( 10 ); + bottomDock->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, + QSizePolicy::Minimum) ); + bottomDockWnd = new QDockWindow( QDockWindow::InDock, bottomDock, + "bottom dock window" ); + if ( mw ) { + mw->setDockEnabled( bottomDockWnd, Qt::DockTop, TRUE ); + mw->setDockEnabled( bottomDockWnd, Qt::DockLeft, TRUE ); + mw->setDockEnabled( bottomDockWnd, Qt::DockRight, TRUE ); + mw->setDockEnabled( bottomDockWnd, Qt::DockBottom, TRUE ); + } + bottomDockWnd->setCaption( tr("Phrases") ); + bottomDockWnd->setCloseMode( QDockWindow::Always ); + bottomDockWnd->setResizeEnabled( TRUE ); + + QWidget * w = new QWidget( bottomDockWnd ); + w->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, + QSizePolicy::Minimum ) ); + QHBoxLayout *hl = new QHBoxLayout( w, 6 ); + QVBoxLayout *vl = new QVBoxLayout( 6 ); + + phraseLbl = new QLabel( tr("Phrases and guesses:"), w ); + phraseLv = new PhraseLV( w, "phrase list view" ); + phraseLv->setSorting( PhraseLVI::DefinitionText ); + phraseLv->installEventFilter( this ); + hl->addLayout( vl ); + vl->addWidget( phraseLbl ); + vl->addWidget( phraseLv ); + + accel = new QAccel( this, "accel" ); + connect( accel, SIGNAL(activated(int)), this, SLOT(guessActivated(int)) ); + for ( int i = 0; i < 9; i++ ) + accel->insertItem( CTRL + (Key_1 + i), i + 1 ); + + bottomDockWnd->setWidget( w ); + + v->addWidget( topDock ); + v->addWidget( sv ); + v->addWidget( bottomDock ); + + // Signals + connect( editorPage->pageCurl, SIGNAL(nextPage()), + SIGNAL(nextUnfinished()) ); + connect( editorPage->pageCurl, SIGNAL(prevPage()), + SIGNAL(prevUnfinished()) ); + + connect( editorPage->translationMed, SIGNAL(textChanged()), + this, SLOT(emitTranslationChanged()) ); + connect( editorPage->translationMed, SIGNAL(textChanged()), + this, SLOT(updateButtons()) ); + connect( editorPage->translationMed, SIGNAL(undoAvailable(bool)), + this, SIGNAL(undoAvailable(bool)) ); + connect( editorPage->translationMed, SIGNAL(redoAvailable(bool)), + this, SIGNAL(redoAvailable(bool)) ); + connect( editorPage->translationMed, SIGNAL(copyAvailable(bool)), + this, SIGNAL(cutAvailable(bool)) ); + connect( editorPage->translationMed, SIGNAL(copyAvailable(bool)), + this, SIGNAL(copyAvailable(bool)) ); + connect( qApp->clipboard(), SIGNAL(dataChanged()), + this, SLOT(updateCanPaste()) ); + connect( phraseLv, SIGNAL(doubleClicked(QListViewItem *)), + this, SLOT(insertPhraseInTranslation(QListViewItem *)) ); + connect( phraseLv, SIGNAL(returnPressed(QListViewItem *)), + this, SLOT(insertPhraseInTranslationAndLeave(QListViewItem *)) ); + + // What's this + QWhatsThis::add( this, tr("This whole panel allows you to view and edit " + "the translation of some source text.") ); + QWhatsThis::add( editorPage->srcText, + tr("This area shows the source text.") ); + QWhatsThis::add( editorPage->cmtText, tr("This area shows a comment that" + " may guide you, and the context in which the text" + " occurs.") ); + QWhatsThis::add( editorPage->translationMed, + tr("This is where you can enter or modify" + " the translation of some source text.") ); +} + +void MessageEditor::toggleFinished() +{ + if ( itemFinished ) + itemFinished = FALSE; + else + itemFinished = TRUE; + emit finished( itemFinished ); +} + +bool MessageEditor::eventFilter( QObject *o, QEvent *e ) +{ + // Handle keypresses in the message editor - scroll the view if the current + // line is hidden. + if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { + QKeyEvent * ke = (QKeyEvent*)e; + const int k = ke->key(); + + if ( ::qt_cast(o) ) { + if ( e->type() == QEvent::KeyPress ) { + // Hardcode the Tab key to do focus changes when pressed + // inside the editor + if ( k == Key_BackTab ) { + emit focusSourceList(); + return TRUE; + } + } else if ( e->type() == QEvent::KeyRelease ) { + MED * ed = (MED *) o; + switch( k ) { + case Key_Up: + if (ed->cursorY() < 10) + sv->verticalScrollBar()->subtractLine(); + break; + + case Key_Down: + if (ed->cursorY() >= ed->height() - 20) + sv->verticalScrollBar()->addLine(); + break; + + case Key_PageUp: + if (ed->cursorY() < 10) + sv->verticalScrollBar()->subtractPage(); + break; + + case Key_PageDown: + if (ed->cursorY() >= ed->height() - 50) + sv->verticalScrollBar()->addPage(); + break; + default: + sv->ensureVisible( sw->margin() + ed->x() + ed->cursorX(), + sw->margin() + ed->y() + ed->cursorY() ); + break; + } + } + } else if ( ::qt_cast(o) ) { + // handle the ESC key in the list views + if ( e->type() == QEvent::KeyRelease && k == Key_Escape ) + editorPage->translationMed->setFocus(); + } + } + return QWidget::eventFilter( o, e ); +} + +void MessageEditor::updatePageHeight( int height ) +{ + sw->resize( sw->width(), height + sw->margin() + sw->shadowWidth() ); +} + +void MessageEditor::resizeEvent( QResizeEvent * ) +{ + sw->resize( sv->viewport()->width(), sw->height() ); +} + +QListView * MessageEditor::sourceTextList() const +{ + return srcTextList; +} + +QListView * MessageEditor::phraseList() const +{ + return phraseLv; +} + +void MessageEditor::showNothing() +{ + editorPage->srcText->setText( "" ); + showContext( QString(""), FALSE ); +} + +void MessageEditor::showContext( const QString& context, bool finished ) +{ + setEditionEnabled( FALSE ); + sourceText = QString::null; + guesses.clear(); + + if( context.isEmpty() ) + editorPage->cmtText->setText(""); + else + editorPage->cmtText->setText( richText(context.simplifyWhiteSpace()) ); + setTranslation( QString(""), FALSE ); + setFinished( finished ); + phraseLv->clear(); + editorPage->handleSourceChanges(); + editorPage->handleCommentChanges(); + editorPage->handleTranslationChanges(); + editorPage->updateCommentField(); +} + +void MessageEditor::showMessage( const QString& text, + const QString& comment, + const QString& fullContext, + const QString& translation, + MetaTranslatorMessage::Type type, + const QValueList& phrases ) +{ + bool obsolete = ( type == MetaTranslatorMessage::Obsolete ); + setEditionEnabled( !obsolete ); + sourceText = text; + guesses.clear(); + + editorPage->srcText->setText( QString("

    ") + richText( text ) + + QString("

    ") ); + + if ( !fullContext.isEmpty() && !comment.isEmpty() ) + editorPage->cmtText->setText( richText(fullContext.simplifyWhiteSpace()) + + "\n" + richText(comment.simplifyWhiteSpace()) ); + else if ( !fullContext.isEmpty() && comment.isEmpty() ) + editorPage->cmtText->setText(richText(fullContext.simplifyWhiteSpace() ) ); + else if ( fullContext.isEmpty() && !comment.isEmpty() ) + editorPage->cmtText->setText( richText(comment.simplifyWhiteSpace() ) ); + else + editorPage->cmtText->setText( "" ); + + setTranslation( translation, FALSE ); + setFinished( type != MetaTranslatorMessage::Unfinished ); + QValueList::ConstIterator p; + phraseLv->clear(); + for ( p = phrases.begin(); p != phrases.end(); ++p ) + (void) new PhraseLVI( phraseLv, *p ); + + if ( doGuesses && !sourceText.isEmpty() ) { + CandidateList cl = similarTextHeuristicCandidates( tor, + sourceText.latin1(), + MaxCandidates ); + int n = 0; + QValueList::Iterator it = cl.begin(); + while ( it != cl.end() ) { + QString def; + if ( n < 9 ) + def = tr( "Guess (%1)" ).arg( QString(QKeySequence(CTRL | (Key_0 + (n + 1)))) ); + else + def = tr( "Guess" ); + (void) new PhraseLVI( phraseLv, + Phrase((*it).source, (*it).target, def), + n + 1 ); + n++; + ++it; + } + } + editorPage->handleSourceChanges(); + editorPage->handleCommentChanges(); + editorPage->handleTranslationChanges(); + editorPage->updateCommentField(); +} + +void MessageEditor::setTranslation( const QString& translation, bool emitt ) +{ + // Block signals so that 'textChanged()' is not emitted when + // for example a new source text item is selected and *not* + // the actual translation. + editorPage->translationMed->blockSignals( !emitt ); + editorPage->translationMed->setText( translation ); + editorPage->translationMed->blockSignals( FALSE ); + if ( !emitt ) + updateButtons(); + emit cutAvailable( FALSE ); + emit copyAvailable( FALSE ); +} + +void MessageEditor::setEditionEnabled( bool enabled ) +{ + editorPage->transLbl->setEnabled( enabled ); + editorPage->translationMed->setReadOnly( !enabled ); + + phraseLbl->setEnabled( enabled ); + phraseLv->setEnabled( enabled ); + updateCanPaste(); +} + +void MessageEditor::undo() +{ + editorPage->translationMed->undo(); +} + +void MessageEditor::redo() +{ + editorPage->translationMed->redo(); +} + +void MessageEditor::cut() +{ + editorPage->translationMed->cut(); +} + +void MessageEditor::copy() +{ + editorPage->translationMed->copy(); +} + +void MessageEditor::paste() +{ + editorPage->translationMed->paste(); +} + +void MessageEditor::del() +{ + editorPage->translationMed->del(); +} + +void MessageEditor::selectAll() +{ + editorPage->translationMed->selectAll(); +} + +void MessageEditor::emitTranslationChanged() +{ + emit translationChanged( editorPage->translationMed->text() ); +} + +void MessageEditor::guessActivated( int accelKey ) +{ + QListViewItem *item = phraseLv->firstChild(); + while ( item != 0 && ((PhraseLVI *) item)->accelKey() != accelKey ) + item = item->nextSibling(); + if ( item != 0 ) + insertPhraseInTranslation( item ); +} + +void MessageEditor::insertPhraseInTranslation( QListViewItem *item ) +{ + editorPage->translationMed->insert(((PhraseLVI *) item)->phrase().target()); + emit translationChanged( editorPage->translationMed->text() ); +} + +void MessageEditor::insertPhraseInTranslationAndLeave( QListViewItem *item ) +{ + editorPage->translationMed->insert(((PhraseLVI *) item)->phrase().target()); + emit translationChanged( editorPage->translationMed->text() ); + editorPage->translationMed->setFocus(); +} + +void MessageEditor::updateButtons() +{ + bool overwrite = ( !editorPage->translationMed->isReadOnly() && + (editorPage->translationMed->text().stripWhiteSpace().isEmpty() || + mayOverwriteTranslation) ); + mayOverwriteTranslation = FALSE; + emit updateActions( overwrite ); +} + +void MessageEditor::beginFromSource() +{ + mayOverwriteTranslation = TRUE; + setTranslation( sourceText, TRUE ); + if ( !editorPage->hasFocus() ) + editorPage->setFocus(); +} + +void MessageEditor::finishAndNext() +{ + setFinished( TRUE ); + emit nextUnfinished(); + if ( !editorPage->hasFocus() ) + editorPage->setFocus(); +} + +void MessageEditor::updateCanPaste() +{ + bool oldCanPaste = canPaste; + canPaste = ( !editorPage->translationMed->isReadOnly() && + !qApp->clipboard()->text().isNull() ); + if ( canPaste != oldCanPaste ) + emit pasteAvailable( canPaste ); +} + +void MessageEditor::setFinished( bool finished ) +{ + if ( !finished != !itemFinished ) + toggleFinished(); +} + +void MessageEditor::toggleGuessing() +{ + doGuesses = !doGuesses; + if ( !doGuesses ) { + phraseLv->clear(); + } +} diff --git a/tools/linguist/linguist/msgedit.h b/tools/linguist/linguist/msgedit.h new file mode 100644 index 0000000..bf73483 --- /dev/null +++ b/tools/linguist/linguist/msgedit.h @@ -0,0 +1,244 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef MSGEDIT_H +#define MSGEDIT_H + +#include "trwindow.h" +#include "phrase.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +class QAccel; +class QDockArea; +class QDockWindow; +class QLabel; +class QListView; +class QListViewItem; +class QTextView; +class QVBoxLayout; + +class EditorPage; +class MED; +class PhraseLV; + +class PageCurl : public QWidget +{ + Q_OBJECT +public: + PageCurl( QWidget * parent = 0, const char * name = 0, + WFlags f = 0 ) + : QWidget( parent, name, f ) + { + QPixmap px = TrWindow::pageCurl(); + if ( px.mask() ) { + setMask( *px.mask() ); + } + setBackgroundPixmap( px ); + setFixedSize( px.size() ); + + QRect r( 34, 0, width()-34, 19 ); + QToolTip::add( this, r, tr("Next unfinished phrase") ); + r.setSize( QSize(width()-34, height()-20) ); + r.setX( 0 ); + r.setY( 20 ); + QToolTip::add( this, r, tr("Previous unfinished phrase") ); + } + +protected: + void mouseReleaseEvent( QMouseEvent * e ) + { + int x = e->pos().x() - 14; + int y = e->pos().y() - 8; + + if ( y <= x ) + emit nextPage(); + else + emit prevPage(); + } + +signals: + void prevPage(); + void nextPage(); +}; + +class ShadowWidget : public QWidget +{ +public: + ShadowWidget( QWidget * parent = 0, const char * name = 0 ); + ShadowWidget( QWidget * child, QWidget * parent = 0, const char * name = 0 ); + + void setShadowWidth( int width ) { sWidth = width; } + int shadowWidth() const { return sWidth; } + void setMargin( int margin ){ wMargin = margin; } + int margin() const { return wMargin; } + void setWidget( QWidget * child); + +protected: + void resizeEvent( QResizeEvent * e ); + void paintEvent( QPaintEvent * e ); + +private: + int sWidth; + int wMargin; + QWidget * childWgt; +}; + +class EditorPage : public QFrame +{ + Q_OBJECT +public: + EditorPage( QWidget * parent = 0, const char * name = 0 ); + +protected: + void resizeEvent( QResizeEvent * ); + void layoutWidgets(); + void updateCommentField(); + void calculateFieldHeight( QTextView * field ); + void fontChange( const QFont & ); + +private: + PageCurl * pageCurl; + QLabel * srcTextLbl; + QLabel * transLbl; + QTextView * srcText; + QTextView * cmtText; + MED * translationMed; + + friend class MessageEditor; + +private slots: + void handleTranslationChanges(); + void handleSourceChanges(); + void handleCommentChanges(); + +signals: + void pageHeightUpdated( int height ); +}; + +class MessageEditor : public QWidget +{ + Q_OBJECT +public: + MessageEditor( MetaTranslator * t, QWidget * parent = 0, + const char * name = 0 ); + QListView * sourceTextList() const; + QListView * phraseList() const; + + void showNothing(); + void showContext( const QString& context, bool finished ); + void showMessage( const QString& text, const QString& comment, + const QString& fullContext, const QString& translation, + MetaTranslatorMessage::Type type, + const QValueList& phrases ); + void setFinished( bool finished ); + bool eventFilter( QObject *, QEvent * ); + +signals: + void translationChanged( const QString& translation ); + void finished( bool finished ); + void prevUnfinished(); + void nextUnfinished(); + void updateActions( bool enable ); + + void undoAvailable( bool avail ); + void redoAvailable( bool avail ); + void cutAvailable( bool avail ); + void copyAvailable( bool avail ); + void pasteAvailable( bool avail ); + + void focusSourceList(); + void focusPhraseList(); + +public slots: + void undo(); + void redo(); + void cut(); + void copy(); + void paste(); + void del(); + void selectAll(); + void beginFromSource(); + void toggleGuessing(); + void finishAndNext(); + +private slots: + void emitTranslationChanged(); + void guessActivated( int accelKey ); + void insertPhraseInTranslation( QListViewItem *item ); + void insertPhraseInTranslationAndLeave( QListViewItem *item ); + void updateButtons(); + void updateCanPaste(); + void toggleFinished(); + + void updatePageHeight( int height ); + +protected: + void resizeEvent( QResizeEvent * ); + +private: + void setTranslation( const QString& translation, bool emitt ); + void setEditionEnabled( bool enabled ); + + QListView * srcTextList; + QDockArea * topDock, * bottomDock; + QDockWindow * topDockWnd, *bottomDockWnd; + EditorPage * editorPage; + QVBoxLayout * v; + + QLabel * phraseLbl; + PhraseLV * phraseLv; + QAccel * accel; + bool itemFinished; + + ShadowWidget * sw; + QScrollView * sv; + + MetaTranslator *tor; + QString sourceText; + QStringList guesses; + bool mayOverwriteTranslation; + bool canPaste; + bool doGuesses; +}; + +#endif diff --git a/tools/linguist/linguist/phrase.cpp b/tools/linguist/linguist/phrase.cpp new file mode 100644 index 0000000..da702a5 --- /dev/null +++ b/tools/linguist/linguist/phrase.cpp @@ -0,0 +1,189 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "phrase.h" + +#include +#include +#include +#include +#include +#include +#include + +static QString protect( const QString& str ) +{ + QString p = str; + p.replace( "&", "&" ); + p.replace( "\"", """ ); + p.replace( ">", ">" ); + p.replace( "<", "<" ); + p.replace( "'", "'" ); + return p; +} + +Phrase::Phrase( const QString& source, const QString& target, + const QString& definition ) + : s( source ), t( target ), d( definition ) +{ +} + +bool operator==( const Phrase& p, const Phrase& q ) +{ + return p.source() == q.source() && p.target() == q.target() && + p.definition() == q.definition(); +} + +class QphHandler : public QXmlDefaultHandler +{ +public: + QphHandler( PhraseBook *phraseBook ) + : pb( phraseBook ), ferrorCount( 0 ) { } + + virtual bool startElement( const QString& namespaceURI, + const QString& localName, const QString& qName, + const QXmlAttributes& atts ); + virtual bool endElement( const QString& namespaceURI, + const QString& localName, const QString& qName ); + virtual bool characters( const QString& ch ); + virtual bool fatalError( const QXmlParseException& exception ); + +private: + PhraseBook *pb; + QString source; + QString target; + QString definition; + + QString accum; + int ferrorCount; +}; + +bool QphHandler::startElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName, + const QXmlAttributes& /* atts */ ) +{ + if ( qName == QString("phrase") ) { + source.truncate( 0 ); + target.truncate( 0 ); + definition.truncate( 0 ); + } + accum.truncate( 0 ); + return TRUE; +} + +bool QphHandler::endElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName ) +{ + if ( qName == QString("source") ) + source = accum; + else if ( qName == QString("target") ) + target = accum; + else if ( qName == QString("definition") ) + definition = accum; + else if ( qName == QString("phrase") ) + pb->append( Phrase(source, target, definition) ); + return TRUE; +} + +bool QphHandler::characters( const QString& ch ) +{ + accum += ch; + return TRUE; +} + +bool QphHandler::fatalError( const QXmlParseException& exception ) +{ + if ( ferrorCount++ == 0 ) { + QString msg; + msg.sprintf( "Parse error at line %d, column %d (%s).", + exception.lineNumber(), exception.columnNumber(), + exception.message().latin1() ); + QMessageBox::information( qApp->mainWidget(), + QObject::tr("Qt Linguist"), msg ); + } + return FALSE; +} + +bool PhraseBook::load( const QString& filename ) +{ + QFile f( filename ); + if ( !f.open(IO_ReadOnly) ) + return FALSE; + + QTextStream t( &f ); + QXmlInputSource in( t ); + QXmlSimpleReader reader; + // don't click on these! + reader.setFeature( "http://xml.org/sax/features/namespaces", FALSE ); + reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", TRUE ); + reader.setFeature( "http://trolltech.com/xml/features/report-whitespace" + "-only-CharData", FALSE ); + QXmlDefaultHandler *hand = new QphHandler( this ); + reader.setContentHandler( hand ); + reader.setErrorHandler( hand ); + + bool ok = reader.parse( in ); + reader.setContentHandler( 0 ); + reader.setErrorHandler( 0 ); + delete hand; + f.close(); + if ( !ok ) + clear(); + return ok; +} + +bool PhraseBook::save( const QString& filename ) const +{ + QFile f( filename ); + if ( !f.open(IO_WriteOnly) ) + return FALSE; + + QTextStream t( &f ); + t.setEncoding(QTextStream::UnicodeUTF8); + t << "\n"; + ConstIterator p; + for ( p = begin(); p != end(); ++p ) { + t << "\n"; + t << " " << protect( (*p).source() ) << "\n"; + t << " " << protect( (*p).target() ) << "\n"; + if ( !(*p).definition().isEmpty() ) + t << " " << protect( (*p).definition() ) + << "\n"; + t << "\n"; + } + t << "\n"; + f.close(); + return TRUE; +} diff --git a/tools/linguist/linguist/phrase.h b/tools/linguist/linguist/phrase.h new file mode 100644 index 0000000..8b32a0c --- /dev/null +++ b/tools/linguist/linguist/phrase.h @@ -0,0 +1,74 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PHRASE_H +#define PHRASE_H + +#include +#include + +class Phrase +{ +public: + Phrase() { } + Phrase( const QString& source, const QString& target, + const QString& definition ); + + QString source() const { return s; } + void setSource( const QString& ns ) { s = ns; } + QString target() const { return t; } + void setTarget( const QString& nt ) { t = nt; } + QString definition() const { return d; } + void setDefinition ( const QString& nd ) { d = nd; } + +private: + QString s; + QString t; + QString d; +}; + +bool operator==( const Phrase& p, const Phrase& q ); +inline bool operator!=( const Phrase& p, const Phrase& q ) { + return !( p == q ); +} + +class PhraseBook : public QValueList +{ +public: + PhraseBook() { } + + bool load( const QString& filename ); + bool save( const QString& filename ) const; +}; + +#endif diff --git a/tools/linguist/linguist/phrasebookbox.cpp b/tools/linguist/linguist/phrasebookbox.cpp new file mode 100644 index 0000000..b8c6fab --- /dev/null +++ b/tools/linguist/linguist/phrasebookbox.cpp @@ -0,0 +1,244 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +/* TRANSLATOR PhraseBookBox + + Go to Phrase > Edit Phrase Book... The dialog that pops up is a + PhraseBookBox. +*/ + +#include "phrasebookbox.h" +#include "phraselv.h" + +#include +#include +#include +#include +#include +#include +#include + +PhraseBookBox::PhraseBookBox( const QString& filename, + const PhraseBook& phraseBook, QWidget *parent, + const char *name, bool modal ) + : QDialog( parent, name, modal ), fn( filename ), pb( phraseBook ) +{ + QGridLayout *gl = new QGridLayout( this, 4, 3, 11, 11, + "phrase book outer layout" ); + QVBoxLayout *bl = new QVBoxLayout( 6, "phrase book button layout" ); + + sourceLed = new QLineEdit( this, "source line edit" ); + QLabel *source = new QLabel( sourceLed, tr("S&ource phrase:"), this, + "source label" ); + targetLed = new QLineEdit( this, "target line edit" ); + QLabel *target = new QLabel( targetLed, tr("&Translation:"), this, + "target label" ); + definitionLed = new QLineEdit( this, "definition line edit" ); + QLabel *definition = new QLabel( definitionLed, tr("&Definition:"), this, + "target label" ); + lv = new PhraseLV( this, "phrase book list view" ); + + newBut = new QPushButton( tr("&New Phrase"), this ); + newBut->setDefault( TRUE ); + + removeBut = new QPushButton( tr("&Remove Phrase"), this ); + removeBut->setEnabled( FALSE ); + QPushButton *saveBut = new QPushButton( tr("&Save"), this ); + QPushButton *closeBut = new QPushButton( tr("Close"), this ); + + gl->addWidget( source, 0, 0 ); + gl->addWidget( sourceLed, 0, 1 ); + gl->addWidget( target, 1, 0 ); + gl->addWidget( targetLed, 1, 1 ); + gl->addWidget( definition, 2, 0 ); + gl->addWidget( definitionLed, 2, 1 ); + gl->addMultiCellWidget( lv, 3, 3, 0, 1 ); + gl->addMultiCell( bl, 0, 3, 2, 2 ); + + bl->addWidget( newBut ); + bl->addWidget( removeBut ); + bl->addWidget( saveBut ); + bl->addWidget( closeBut ); + bl->addStretch( 1 ); + + connect( sourceLed, SIGNAL(textChanged(const QString&)), + this, SLOT(sourceChanged(const QString&)) ); + connect( targetLed, SIGNAL(textChanged(const QString&)), + this, SLOT(targetChanged(const QString&)) ); + connect( definitionLed, SIGNAL(textChanged(const QString&)), + this, SLOT(definitionChanged(const QString&)) ); + connect( lv, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(selectionChanged(QListViewItem *)) ); + connect( newBut, SIGNAL(clicked()), this, SLOT(newPhrase()) ); + connect( removeBut, SIGNAL(clicked()), this, SLOT(removePhrase()) ); + connect( saveBut, SIGNAL(clicked()), this, SLOT(save()) ); + connect( closeBut, SIGNAL(clicked()), this, SLOT(accept()) ); + + PhraseBook::ConstIterator it; + for ( it = phraseBook.begin(); it != phraseBook.end(); ++it ) + (void) new PhraseLVI( lv, (*it) ); + enableDisable(); + + QWhatsThis::add( this, tr("This window allows you to add, modify, or delete" + " phrases in a phrase book.") ); + QWhatsThis::add( sourceLed, tr("This is the phrase in the source" + " language.") ); + QWhatsThis::add( targetLed, tr("This is the phrase in the target language" + " corresponding to the source phrase.") ); + QWhatsThis::add( definitionLed, tr("This is a definition for the source" + " phrase.") ); + QWhatsThis::add( newBut, tr("Click here to add the phrase to the phrase" + " book.") ); + QWhatsThis::add( removeBut, tr("Click here to remove the phrase from the" + " phrase book.") ); + QWhatsThis::add( saveBut, tr("Click here to save the changes made.") ); + QWhatsThis::add( closeBut, tr("Click here to close this window.") ); +} + +void PhraseBookBox::keyPressEvent( QKeyEvent *ev ) +{ + if ( ev->key() == Key_Down || ev->key() == Key_Up || + ev->key() == Key_Next || ev->key() == Key_Prior ) + QApplication::sendEvent( lv, + new QKeyEvent(ev->type(), ev->key(), ev->ascii(), ev->state(), + ev->text(), ev->isAutoRepeat(), ev->count()) ); + else + QDialog::keyPressEvent( ev ); +} + +void PhraseBookBox::newPhrase() +{ + Phrase ph; + ph.setSource( NewPhrase ); + QListViewItem *item = new PhraseLVI( lv, ph ); + selectItem( item ); +} + +void PhraseBookBox::removePhrase() +{ + QListViewItem *item = lv->currentItem(); + QListViewItem *next = item->itemBelow() != 0 ? item->itemBelow() + : item->itemAbove(); + delete item; + if ( next != 0 ) + selectItem( next ); + enableDisable(); +} + +void PhraseBookBox::save() +{ + pb.clear(); + QListViewItem *item = lv->firstChild(); + while ( item != 0 ) { + if ( !item->text(PhraseLVI::SourceTextShown).isEmpty() && + item->text(PhraseLVI::SourceTextShown) != NewPhrase ) + pb.append( Phrase(((PhraseLVI *) item)->phrase()) ); + item = item->nextSibling(); + } + if ( !pb.save( fn ) ) + QMessageBox::warning( this, tr("Qt Linguist"), + tr("Cannot save phrase book '%1'.").arg(fn) ); +} + +void PhraseBookBox::sourceChanged( const QString& source ) +{ + if ( lv->currentItem() != 0 ) { + lv->currentItem()->setText( PhraseLVI::SourceTextShown, + source.stripWhiteSpace() ); + lv->currentItem()->setText( PhraseLVI::SourceTextOriginal, source ); + lv->sort(); + lv->ensureItemVisible( lv->currentItem() ); + } +} + +void PhraseBookBox::targetChanged( const QString& target ) +{ + if ( lv->currentItem() != 0 ) { + lv->currentItem()->setText( PhraseLVI::TargetTextShown, + target.stripWhiteSpace() ); + lv->currentItem()->setText( PhraseLVI::TargetTextOriginal, target ); + lv->sort(); + lv->ensureItemVisible( lv->currentItem() ); + } +} + +void PhraseBookBox::definitionChanged( const QString& definition ) +{ + if ( lv->currentItem() != 0 ) { + lv->currentItem()->setText( PhraseLVI::DefinitionText, definition ); + lv->sort(); + lv->ensureItemVisible( lv->currentItem() ); + } +} + +void PhraseBookBox::selectionChanged( QListViewItem * /* item */ ) +{ + enableDisable(); +} + +void PhraseBookBox::selectItem( QListViewItem *item ) +{ + lv->setSelected( item, TRUE ); + lv->ensureItemVisible( item ); +} + +void PhraseBookBox::enableDisable() +{ + QListViewItem *item = lv->currentItem(); + + sourceLed->blockSignals( TRUE ); + targetLed->blockSignals( TRUE ); + definitionLed->blockSignals( TRUE ); + + if ( item == 0 ) { + sourceLed->setText( QString::null ); + targetLed->setText( QString::null ); + definitionLed->setText( QString::null ); + } else { + sourceLed->setText( item->text(0) ); + targetLed->setText( item->text(1) ); + definitionLed->setText( item->text(2) ); + } + sourceLed->setEnabled( item != 0 ); + targetLed->setEnabled( item != 0 ); + definitionLed->setEnabled( item != 0 ); + removeBut->setEnabled( item != 0 ); + + sourceLed->blockSignals( FALSE ); + targetLed->blockSignals( FALSE ); + definitionLed->blockSignals( FALSE ); + + QLineEdit *led = ( sourceLed->text() == NewPhrase ? sourceLed : targetLed ); + led->setFocus(); + led->selectAll(); +} diff --git a/tools/linguist/linguist/phrasebookbox.h b/tools/linguist/linguist/phrasebookbox.h new file mode 100644 index 0000000..0f922b1 --- /dev/null +++ b/tools/linguist/linguist/phrasebookbox.h @@ -0,0 +1,84 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PHRASEBOOKBOX_H +#define PHRASEBOOKBOX_H + +#include "phrase.h" + +#include +#include + +class QLineEdit; +class QPushButton; +class QListViewItem; + +class PhraseLV; + +class PhraseBookBox : public QDialog +{ + Q_OBJECT +public: + PhraseBookBox( const QString& filename, const PhraseBook& phraseBook, + QWidget *parent = 0, const char *name = 0, + bool modal = FALSE ); + + const PhraseBook& phraseBook() const { return pb; } + +protected: + virtual void keyPressEvent( QKeyEvent *ev ); + +private slots: + void newPhrase(); + void removePhrase(); + void save(); + void sourceChanged( const QString& source ); + void targetChanged( const QString& target ); + void definitionChanged( const QString& definition ); + void selectionChanged( QListViewItem *item ); + +private: + void selectItem( QListViewItem *item ); + void enableDisable(); + + QLineEdit *sourceLed; + QLineEdit *targetLed; + QLineEdit *definitionLed; + QPushButton *newBut; + QPushButton *removeBut; + PhraseLV *lv; + QString fn; + PhraseBook pb; +}; + +#endif diff --git a/tools/linguist/linguist/phraselv.cpp b/tools/linguist/linguist/phraselv.cpp new file mode 100644 index 0000000..fa454f8 --- /dev/null +++ b/tools/linguist/linguist/phraselv.cpp @@ -0,0 +1,171 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +/* TRANSLATOR PhraseLV + + The phrase list in the right panel of the main window (with Source phrase, + Target phrase, and Definition in its header) is a PhraseLV object. +*/ + +#include "phraselv.h" + +#include +#include +#include + +class WhatPhrase : public QWhatsThis +{ +public: + WhatPhrase( PhraseLV *w ); + + virtual QString text( const QPoint& p ); + +private: + PhraseLV *parent; +}; + +WhatPhrase::WhatPhrase( PhraseLV *w ) + : QWhatsThis( w ) +{ + parent = w; +} + +QString WhatPhrase::text( const QPoint& p ) +{ + QListViewItem *item = parent->itemAt( p ); + if ( item == 0 ) + return PhraseLV::tr( "This is a list of phrase entries relevant to the" + " source text. Each phrase is supplemented with a suggested" + " translation and a definition." ); + else + return QString( PhraseLV::tr("

    %1:  %2

    " + "

    %3:  %4

    " + "

    %5:  %6

    ") ) + .arg( parent->columnText(PhraseLVI::SourceTextShown) ) + .arg( item->text(PhraseLVI::SourceTextShown) ) + .arg( parent->columnText(PhraseLVI::TargetTextShown) ) + .arg( item->text(PhraseLVI::TargetTextShown) ) + .arg( parent->columnText(PhraseLVI::DefinitionText) ) + .arg( item->text(PhraseLVI::DefinitionText) ); +} + +PhraseLVI::PhraseLVI( PhraseLV *parent, const Phrase& phrase, int accelKey ) + : QListViewItem( parent ), + akey( accelKey ) +{ + setPhrase( phrase ); +} + +QString PhraseLVI::key( int column, bool ascending ) const +{ + if ( column == SourceTextShown ) { + if ( sourceTextKey.isEmpty() ) { + if ( ascending ) { + return ""; + } else { + return QString::null; + } + } else { + return sourceTextKey; + } + } else if ( column == TargetTextShown ) { + return targetTextKey; + } else { + return QChar( '0' + akey ) + text( column ); + } +} + +void PhraseLVI::setText( int column, const QString& text ) +{ + if ( column == SourceTextShown ) { + sourceTextKey = makeKey( text ); + } else if ( column == TargetTextShown ) { + targetTextKey = makeKey( text ); + } + QListViewItem::setText( column, text ); +} + +void PhraseLVI::setPhrase( const Phrase& phrase ) +{ + setText( SourceTextShown, phrase.source().simplifyWhiteSpace() ); + setText( TargetTextShown, phrase.target().simplifyWhiteSpace() ); + setText( DefinitionText, phrase.definition() ); + setText( SourceTextOriginal, phrase.source() ); + setText( TargetTextOriginal, phrase.target() ); +} + +Phrase PhraseLVI::phrase() const +{ + return Phrase( text(SourceTextOriginal), text(TargetTextOriginal), + text(DefinitionText) ); +} + +QString PhraseLVI::makeKey( const QString& text ) const +{ + if ( text == NewPhrase ) + return QString::null; + + QString key; + for ( int i = 0; i < (int) text.length(); i++ ) { + if ( text[i] != QChar('&') ) + key += text[i].lower(); + } + // see Section 5, Exercise 4 of The Art of Computer Programming + key += QChar::null; + key += text; + return key; +} + +PhraseLV::PhraseLV( QWidget *parent, const char *name ) + : QListView( parent, name ) +{ + setAllColumnsShowFocus( TRUE ); + setShowSortIndicator( TRUE ); + for ( int i = 0; i < 3; i++ ) + addColumn( QString::null, 120 ); + setColumnText( PhraseLVI::SourceTextShown, tr("Source phrase") ); + setColumnText( PhraseLVI::TargetTextShown, tr("Translation") ); + setColumnText( PhraseLVI::DefinitionText, tr("Definition") ); + header()->setStretchEnabled( TRUE, -1 ); + what = new WhatPhrase( this ); +} + +PhraseLV::~PhraseLV() +{ +// delete what; +} + +QSize PhraseLV::sizeHint() const +{ + return QSize( QListView::sizeHint().width(), 50 ); +} diff --git a/tools/linguist/linguist/phraselv.h b/tools/linguist/linguist/phraselv.h new file mode 100644 index 0000000..cb06090 --- /dev/null +++ b/tools/linguist/linguist/phraselv.h @@ -0,0 +1,83 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PHRASELV_H +#define PHRASELV_H + +#include "phrase.h" + +#include + +class QWhatsThis; + +class PhraseLV; + +#define NewPhrase PhraseLV::tr( "(New Phrase)" ) + +class PhraseLVI : public QListViewItem +{ +public: + enum { SourceTextShown, TargetTextShown, DefinitionText, SourceTextOriginal, + TargetTextOriginal }; + + PhraseLVI( PhraseLV *parent, const Phrase& phrase, int accelKey = 0 ); + + virtual void setText( int column, const QString& text ); + virtual QString key( int column, bool ascending ) const; + + void setPhrase( const Phrase& phrase ); + Phrase phrase() const; + int accelKey() const { return akey; } + +private: + QString makeKey( const QString& text ) const; + + int akey; + QString sourceTextKey; + QString targetTextKey; +}; + +class PhraseLV : public QListView +{ + Q_OBJECT +public: + PhraseLV( QWidget *parent, const char *name ); + ~PhraseLV(); + + virtual QSize sizeHint() const; + +private: + QWhatsThis *what; +}; + +#endif diff --git a/tools/linguist/linguist/printout.cpp b/tools/linguist/linguist/printout.cpp new file mode 100644 index 0000000..53d944a --- /dev/null +++ b/tools/linguist/linguist/printout.cpp @@ -0,0 +1,182 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "printout.h" + +#include +#include + +PrintOut::PrintOut( QPrinter *printer ) + : pr( printer ), pdmetrics( printer ), nextRule( NoRule ), page( 0 ) +{ + p.begin( pr ); + QFont f( "Arial" ); + f8 = f; + f8.setPointSize( 8 ); + f10 = f; + f10.setPointSize( 10 ); + p.setFont( f10 ); + fmetrics = new QFontMetrics( p.fontMetrics() ); + hmargin = 5 * pdmetrics.width() / pdmetrics.widthMM(); // 5 mm + vmargin = 5 * pdmetrics.height() / pdmetrics.heightMM(); // 5 mm + hsize = pdmetrics.width() - 2 * hmargin; + vsize = pdmetrics.height() - vmargin; + dateTime = QDateTime::currentDateTime(); + breakPage(); + vsize -= voffset; + cp = Paragraph( QPoint(hmargin, voffset) ); +} + +PrintOut::~PrintOut() +{ + flushLine(); + delete fmetrics; + p.end(); +} + +void PrintOut::setRule( Rule rule ) +{ + if ( (int) nextRule < (int) rule ) + nextRule = rule; +} + +void PrintOut::setGuide( const QString& guide ) +{ + g = guide; +} + +void PrintOut::vskip() +{ + if ( !firstParagraph ) + voffset += 14; +} + +void PrintOut::flushLine( bool /* mayBreak */ ) +{ + if ( voffset + cp.rect.height() > vsize ) + breakPage(); + else if ( !firstParagraph ) + drawRule( nextRule ); + + for ( int i = 0; i < (int) cp.boxes.count(); i++ ) { + Box b = cp.boxes[i]; + b.rect.moveBy( 0, voffset ); + QRect r = b.rect; + p.setFont( b.font ); + p.drawText( r, b.align, b.text ); + } + voffset += cp.rect.height(); + + nextRule = NoRule; + cp = Paragraph( QPoint(hmargin, voffset) ); + firstParagraph = FALSE; +} + +void PrintOut::addBox( int percent, const QString& text, Style style, + int halign ) +{ + int align = halign | Qt::AlignTop; + QFont f = f10; + if ( style == Strong ) + f.setBold( TRUE ); + else if ( style == Emphasis ) + f.setItalic( TRUE ); + int wd = hsize * percent / 100; + QRect r( cp.rect.x() + cp.rect.width(), 0, wd, vsize ); + int ht = p.boundingRect( r, align, text ).height(); + + Box b( r, text, f, align ); + cp.boxes.append( b ); + cp.rect.setSize( QSize(cp.rect.width() + wd, QMAX(cp.rect.height(), ht)) ); +} + +void PrintOut::breakPage() +{ + static const int LeftAlign = Qt::AlignLeft | Qt::AlignTop; + static const int RightAlign = Qt::AlignRight | Qt::AlignTop; + QRect r1, r2; + int h1 = 0; + int h2 = 0; + + if ( page++ > 0 ) + pr->newPage(); + voffset = 0; + + p.setFont( f10 ); + r1 = QRect( hmargin, voffset, 3 * hsize / 4, vsize ); + r2 = QRect( r1.x() + r1.width(), voffset, hsize - r1.width(), vsize ); + h1 = p.boundingRect( r1, LeftAlign, pr->docName() ).height(); + p.drawText( r1, LeftAlign, pr->docName() ); + h2 = p.boundingRect( r2, RightAlign, QString::number(page) ).height(); + p.drawText( r2, RightAlign, QString::number(page) ); + voffset += QMAX( h1, h2 ); + + r1 = QRect( hmargin, voffset, hsize / 2, LeftAlign ); + p.setFont( f8 ); + h1 = p.boundingRect( r1, LeftAlign, dateTime.toString() ).height(); + p.drawText( r1, LeftAlign, dateTime.toString() ); + p.setFont( f10 ); + voffset += QMAX( h1, h2 ); + + voffset += 4; + p.drawLine( QPoint(hmargin, voffset), QPoint(hmargin + hsize, voffset) ); + voffset += 14; + firstParagraph = TRUE; +} + +void PrintOut::drawRule( Rule rule ) +{ + QPen pen; + + switch ( rule ) { + case NoRule: + voffset += 5; + break; + case ThinRule: + pen.setColor( QColor(192, 192, 192) ); + pen.setStyle( QPen::DotLine ); + pen.setWidth( 0 ); + p.setPen( pen ); + voffset += 5; + p.drawLine( QPoint(hmargin, voffset), + QPoint(hmargin + hsize, voffset) ); + p.setPen( QPen() ); + voffset += 2; + break; + case ThickRule: + voffset += 7; + p.drawLine( QPoint(hmargin, voffset), + QPoint(hmargin + hsize, voffset) ); + voffset += 4; + } +} diff --git a/tools/linguist/linguist/printout.h b/tools/linguist/linguist/printout.h new file mode 100644 index 0000000..d67191c --- /dev/null +++ b/tools/linguist/linguist/printout.h @@ -0,0 +1,126 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PRINTOUT_H +#define PRINTOUT_H + +#include +#include +#include +#include +#include +#include + +class QPrinter; +class QFontMetrics; + +class PrintOut +{ +public: + enum Rule { NoRule, ThinRule, ThickRule }; + enum Style { Normal, Strong, Emphasis }; + + PrintOut( QPrinter *printer ); + ~PrintOut(); + + void setRule( Rule rule ); + void setGuide( const QString& guide ); + void vskip(); + void flushLine( bool mayBreak = FALSE ); + void addBox( int percent, const QString& text = QString::null, + Style style = Normal, + int halign = Qt::AlignLeft | Qt::WordBreak ); + + int pageNum() const { return page; } + + struct Box + { + QRect rect; + QString text; + QFont font; + int align; + + Box() : align( 0 ) { } + Box( const QRect& r, const QString& t, const QFont& f, int a ) + : rect( r ), text( t ), font( f ), align( a ) { } + Box( const Box& b ) + : rect( b.rect ), text( b.text ), font( b.font ), + align( b.align ) { } + + Box& operator=( const Box& b ) { + rect = b.rect; + text = b.text; + font = b.font; + align = b.align; + return *this; + } + + bool operator==( const Box& b ) const { + return rect == b.rect && text == b.text && font == b.font && + align == b.align; + } + }; + +private: + void breakPage(); + void drawRule( Rule rule ); + + struct Paragraph { + QRect rect; + QValueList boxes; + + Paragraph() { } + Paragraph( QPoint p ) : rect( p, QSize(0, 0) ) { } + }; + + QPrinter *pr; + QPainter p; + QFont f8; + QFont f10; + QFontMetrics *fmetrics; + QPaintDeviceMetrics pdmetrics; + Rule nextRule; + Paragraph cp; + int page; + bool firstParagraph; + QString g; + QDateTime dateTime; + + int hmargin; + int vmargin; + int voffset; + int hsize; + int vsize; +}; + +#endif diff --git a/tools/linguist/linguist/simtexth.cpp b/tools/linguist/linguist/simtexth.cpp new file mode 100644 index 0000000..8bed388 --- /dev/null +++ b/tools/linguist/linguist/simtexth.cpp @@ -0,0 +1,239 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "simtexth.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include + +typedef QValueList TML; + +/* + How similar are two texts? The approach used here relies on co-occurrence + matrices and is very efficient. + + Let's see with an example: how similar are "here" and "hither"? The + co-occurrence matrix M for "here" is M[h,e] = 1, M[e,r] = 1, M[r,e] = 1, and 0 + elsewhere; the matrix N for "hither" is N[h,i] = 1, N[i,t] = 1, ..., + N[h,e] = 1, N[e,r] = 1, and 0 elsewhere. The union U of both matrices is the + matrix U[i,j] = max { M[i,j], N[i,j] }, and the intersection V is + V[i,j] = min { M[i,j], N[i,j] }. The score for a pair of texts is + + score = (sum of V[i,j] over all i, j) / (sum of U[i,j] over all i, j), + + a formula suggested by Arnt Gulbrandsen. Here we have + + score = 2 / 6, + + or one third. + + The implementation differs from this in a few details. Most importantly, + repetitions are ignored; for input "xxx", M[x,x] equals 1, not 2. +*/ + +/* + Every character is assigned to one of 20 buckets so that the co-occurrence + matrix requires only 20 * 20 = 400 bits, not 256 * 256 = 65536 bits or even + more if we want the whole Unicode. Which character falls in which bucket is + arbitrary. + + The second half of the table is a replica of the first half, because of + laziness. +*/ +static const int indexOf[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// ! " # $ % & ' ( ) * + , - . / + 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0, +// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? + 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15, +// @ A B C D E F G H I J K L M N O + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14, +// P Q R S T U V W X Y Z [ \ ] ^ _ + 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0, +// ` a b c d e f g h i j k l m n o + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14, +// p q r s t u v w x y z { | } ~ + 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0, + 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14, + 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14, + 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0 +}; + +/* + The entry bitCount[i] (for i between 0 and 255) is the number of bits used to + represent i in binary. +*/ +static const int bitCount[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +struct CoMatrix +{ + /* + The matrix has 20 * 20 = 400 entries. This requires 50 bytes, or 13 + words. Some operations are performed on words for more efficiency. + */ + union { + Q_UINT8 b[52]; + Q_UINT32 w[13]; + }; + + CoMatrix() { memset( b, 0, 52 ); } + CoMatrix( const char *text ) { + char c = '\0', d; + memset( b, 0, 52 ); + /* + The Knuth books are not in the office only for show; they help make + loops 30% faster and 20% as readable. + */ + while ( (d = *text) != '\0' ) { + setCoocc( c, d ); + if ( (c = *++text) != '\0' ) { + setCoocc( d, c ); + text++; + } + } + } + + void setCoocc( char c, char d ) { + int k = indexOf[(uchar) c] + 20 * indexOf[(uchar) d]; + b[k >> 3] |= k & 0x7; + } + + int worth() const { + int w = 0; + for ( int i = 0; i < 50; i++ ) + w += bitCount[b[i]]; + return w; + } +}; + +static inline CoMatrix reunion( const CoMatrix& m, const CoMatrix& n ) +{ + CoMatrix p; + for ( int i = 0; i < 13; i++ ) + p.w[i] = m.w[i] | n.w[i]; + return p; +} + +static inline CoMatrix intersection( const CoMatrix& m, const CoMatrix& n ) +{ + CoMatrix p; + for ( int i = 0; i < 13; i++ ) + p.w[i] = m.w[i] & n.w[i]; + return p; +} + +CandidateList similarTextHeuristicCandidates( const MetaTranslator *tor, + const char *text, + int maxCandidates ) +{ + QValueList scores; + CandidateList candidates; + CoMatrix cmTarget( text ); + int targetLen = qstrlen( text ); + + TML all = tor->translatedMessages(); + TML::Iterator it; + + for ( it = all.begin(); it != all.end(); ++it ) { + if ( (*it).type() == MetaTranslatorMessage::Unfinished || + (*it).translation().isEmpty() ) + continue; + + QString s = tor->toUnicode( (*it).sourceText(), (*it).utf8() ); + CoMatrix cm( s.latin1() ); + int delta = QABS( (int) s.length() - targetLen ); + + /* + Here is the score formula. A comment above contains a + discussion on a similar (but simpler) formula. + */ + int score = ( (intersection(cm, cmTarget).worth() + 1) << 10 ) / + ( reunion(cm, cmTarget).worth() + (delta << 1) + 1 ); + + if ( (int) candidates.count() == maxCandidates && + score > scores[maxCandidates - 1] ) + candidates.remove( candidates.last() ); + if ( (int) candidates.count() < maxCandidates && score >= 190 ) { + Candidate cand( s, (*it).translation() ); + + int i; + for ( i = 0; i < (int) candidates.count(); i++ ) { + if ( score >= scores[i] ) { + if ( score == scores[i] ) { + if ( candidates[i] == cand ) + goto continue_outer_loop; + } else { + break; + } + } + } + scores.insert( scores.at(i), score ); + candidates.insert( candidates.at(i), cand ); + } + continue_outer_loop: + ; + } + return candidates; +} diff --git a/tools/linguist/linguist/simtexth.h b/tools/linguist/linguist/simtexth.h new file mode 100644 index 0000000..91d8cbd --- /dev/null +++ b/tools/linguist/linguist/simtexth.h @@ -0,0 +1,64 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SIMTEXTH_H +#define SIMTEXTH_H + +#include +#include + +class MetaTranslator; + +struct Candidate { + QString source; + QString target; + + Candidate() { } + Candidate( const QString& source0, const QString& target0 ) + : source( source0 ), target( target0 ) { } +}; + +inline bool operator==( const Candidate& c, const Candidate& d ) { + return c.target == d.target && c.source == d.source; +} +inline bool operator!=( const Candidate& c, const Candidate& d ) { + return !operator==( c, d ); +} + +typedef QValueList CandidateList; + +CandidateList similarTextHeuristicCandidates( const MetaTranslator *tor, + const char *text, + int maxCandidates ); + +#endif diff --git a/tools/linguist/linguist/statistics.ui b/tools/linguist/linguist/statistics.ui new file mode 100644 index 0000000..c897b78 --- /dev/null +++ b/tools/linguist/linguist/statistics.ui @@ -0,0 +1,259 @@ + +Statistics +********************************************************************* +** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + Statistics + + + + 0 + 0 + 336 + 164 + + + + Statistics + + + + unnamed + + + + layout2 + + + + unnamed + + + + spacer4_2 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + closeBtn + + + &Close + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + + + frame4 + + + GroupBoxPanel + + + Raised + + + + unnamed + + + + textLabel4 + + + Translation + + + AlignVCenter|AlignRight + + + + + textLabel5 + + + Source + + + AlignVCenter|AlignRight + + + + + untrWords + + + 0 + + + AlignVCenter|AlignRight + + + + + trWords + + + 0 + + + AlignVCenter|AlignRight + + + + + textLabel1 + + + Words: + + + + + trChars + + + 0 + + + AlignVCenter|AlignRight + + + + + untrChars + + + 0 + + + AlignVCenter|AlignRight + + + + + textLabel3 + + + Characters: + + + + + textLabel6 + + + Characters (with spaces): + + + + + trCharsSpc + + + 0 + + + AlignVCenter|AlignRight + + + + + untrCharsSpc + + + 0 + + + AlignVCenter|AlignRight + + + + + + + + + closeBtn + clicked() + Statistics + close() + + + + statistics.ui.h + + + closed() + + + updateStats( int w1, int c1, int cs1, int w2, int c2, int cs2 ) + closeEvent( QCloseEvent * e ) + + + init() + + + + diff --git a/tools/linguist/linguist/statistics.ui.h b/tools/linguist/linguist/statistics.ui.h new file mode 100644 index 0000000..fe9b448 --- /dev/null +++ b/tools/linguist/linguist/statistics.ui.h @@ -0,0 +1,53 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +void Statistics::init() +{ + setFixedHeight( sizeHint().height() ); +} + +void Statistics::updateStats( int w1, int c1, int cs1, int w2, int c2, int cs2 ) +{ + untrWords->setText( QString::number( w1 ) ); + untrChars->setText( QString::number( c1 ) ); + untrCharsSpc->setText( QString::number( cs1 ) ); + trWords->setText( QString::number( w2 ) ); + trChars->setText( QString::number( c2 ) ); + trCharsSpc->setText( QString::number( cs2 ) ); +} + +void Statistics::closeEvent( QCloseEvent * e ) +{ + emit closed(); + QDialog::closeEvent( e ); +} diff --git a/tools/linguist/linguist/trwindow.cpp b/tools/linguist/linguist/trwindow.cpp new file mode 100644 index 0000000..e8725e5 --- /dev/null +++ b/tools/linguist/linguist/trwindow.cpp @@ -0,0 +1,2071 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +/* TRANSLATOR TrWindow + + This is the application's main window. +*/ + +#include "trwindow.h" +#include "listviews.h" +#include "finddialog.h" +#include "msgedit.h" +#include "phrasebookbox.h" +#include "printout.h" +#include "about.h" +#include "phraselv.h" +#include "statistics.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define pagecurl_mask_width 53 +#define pagecurl_mask_height 51 +static const uchar pagecurl_mask_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0f, 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xfe, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0xff, + 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, + 0xfc, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x0f, + 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff, + 0xff, 0x0f, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xf0, + 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, + 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, + 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, + 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, + 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, + 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, + 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x00, 0xe0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, + 0x0f, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xfc, + 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 }; + +typedef QValueList TML; + +static const int ErrorMS = 600000; // for error messages +static const int MessageMS = 2500; + +QPixmap * TrWindow::pxOn = 0; +QPixmap * TrWindow::pxOff = 0; +QPixmap * TrWindow::pxObsolete = 0; +QPixmap * TrWindow::pxDanger = 0; + +enum Ending { End_None, End_FullStop, End_Interrobang, End_Colon, + End_Ellipsis }; + +static Ending ending( QString str ) +{ + str = str.simplifyWhiteSpace(); + int ch = 0; + if ( !str.isEmpty() ) + ch = str.right( 1 )[0].unicode(); + + switch ( ch ) { + case 0x002e: // full stop + if ( str.endsWith(QString("...")) ) + return End_Ellipsis; + else + return End_FullStop; + case 0x0589: // armenian full stop + case 0x06d4: // arabic full stop + case 0x3002: // ideographic full stop + return End_FullStop; + case 0x0021: // exclamation mark + case 0x003f: // question mark + case 0x00a1: // inverted exclamation mark + case 0x00bf: // inverted question mark + case 0x01c3: // latin letter retroflex click + case 0x037e: // greek question mark + case 0x061f: // arabic question mark + case 0x203c: // double exclamation mark + case 0x203d: // interrobang + case 0x2048: // question exclamation mark + case 0x2049: // exclamation question mark + case 0x2762: // heavy exclamation mark ornament + return End_Interrobang; + case 0x003a: // colon + return End_Colon; + case 0x2026: // horizontal ellipsis + return End_Ellipsis; + default: + return End_None; + } +} + +class Action : public QAction +{ +public: + Action( QPopupMenu *pop, const QString& menuText, QObject *receiver, + const char *member, const QString &imageName = QString::null, + int accel = 0, bool toggle = FALSE ); + Action( QPopupMenu *pop, const QString& menuText, int accel = 0, + bool toggle = FALSE ); + + virtual void setWhatsThis( const QString& whatsThis ); + + bool addToToolbar( QToolBar *tb, const QString& text ); +}; + +Action::Action( QPopupMenu *pop, const QString& menuText, QObject *receiver, + const char *member, const QString &imageName, int accel, + bool toggle ) + : QAction( pop->parent(), (const char *) 0, toggle ) +{ + setMenuText( menuText ); + setAccel( accel ); + + if ( !imageName.isEmpty() ) { + QPixmap enabledPix = QPixmap::fromMimeSource( imageName ); + QIconSet s( enabledPix ); + if ( imageName != "whatsthis.xpm" ) { + QPixmap disabledPix = QPixmap::fromMimeSource( "d_" + imageName ); + s.setPixmap( disabledPix, QIconSet::Small, QIconSet::Disabled ); + } + setIconSet( s ); + } + QAction::addTo( pop ); + connect( this, SIGNAL(activated()), receiver, member ); +} + +Action::Action( QPopupMenu *pop, const QString& menuText, int accel, + bool toggle ) + : QAction( pop->parent(), (const char *) 0, toggle ) +{ + QAction::addTo( pop ); + setMenuText( menuText ); + setAccel( accel ); +} + +void Action::setWhatsThis( const QString& whatsThis ) +{ + QAction::setWhatsThis( whatsThis ); + setStatusTip( whatsThis ); +} + +bool Action::addToToolbar( QToolBar *tb, const QString& text ) +{ + setText( text ); + return QAction::addTo( tb ); +} + +const QPixmap TrWindow::pageCurl() +{ + QPixmap pixmap; + pixmap = QPixmap::fromMimeSource( "pagecurl.png" ); + if ( !pixmap.isNull() ) { + QBitmap pageCurlMask( pagecurl_mask_width, pagecurl_mask_height, + pagecurl_mask_bits, TRUE ); + pixmap.setMask( pageCurlMask ); + } + + return pixmap; +} + +TrWindow::TrWindow() + : QMainWindow( 0, "translation window", WType_TopLevel | WDestructiveClose ) +{ + +#ifndef Q_WS_MACX + setIcon( QPixmap::fromMimeSource( "appicon.png" ) ); +#endif + + // Create the application global listview symbols + pxOn = new QPixmap( QPixmap::fromMimeSource( "s_check_on.png" ) ); + pxOff = new QPixmap( QPixmap::fromMimeSource( "s_check_off.png" ) ); + pxObsolete = new QPixmap( QPixmap::fromMimeSource( "d_s_check_obs.png" ) ); + pxDanger = new QPixmap( QPixmap::fromMimeSource( "s_check_danger.png" ) ); + + // Set up the Scope dock window + QDockWindow * dwScope = new QDockWindow( QDockWindow::InDock, this, + "context"); + dwScope->setResizeEnabled( TRUE ); + dwScope->setCloseMode( QDockWindow::Always ); + addDockWindow( dwScope, tr("Context"), Qt::DockLeft ); + dwScope->setCaption( tr("Context") ); + dwScope->setFixedExtentWidth( 200 ); + lv = new QListView( dwScope, "context list view" ); + lv->setShowSortIndicator( TRUE ); + lv->setAllColumnsShowFocus( TRUE ); + lv->header()->setStretchEnabled( TRUE, 1 ); + QFontMetrics fm( font() ); + lv->addColumn( tr("Done"), fm.width( tr("Done") ) + 10 ); + lv->addColumn( tr("Context") ); + lv->addColumn( tr("Items"), 55 ); + lv->setColumnAlignment( 0, Qt::AlignCenter ); + lv->setColumnAlignment( 2, Qt::AlignRight ); + lv->setSorting( 0 ); + lv->setHScrollBarMode( QScrollView::AlwaysOff ); + dwScope->setWidget( lv ); + + messageIsShown = FALSE; + me = new MessageEditor( &tor, this, "message editor" ); + setCentralWidget( me ); + slv = me->sourceTextList(); + plv = me->phraseList(); + + setupMenuBar(); + setupToolBars(); + + progress = new QLabel( statusBar(), "progress" ); + statusBar()->addWidget( progress, 0, TRUE ); + modified = new QLabel( QString(" %1 ").arg(tr("MOD")), statusBar(), + "modified?" ); + statusBar()->addWidget( modified, 0, TRUE ); + + dirtyItem = -1; + numFinished = 0; + numNonobsolete = 0; + numMessages = 0; + updateProgress(); + + dirty = FALSE; + updateCaption(); + + phraseBooks.setAutoDelete( TRUE ); + + f = new FindDialog( FALSE, this, "find", FALSE ); + f->setCaption( tr("Qt Linguist") ); + h = new FindDialog( TRUE, this, "replace", FALSE ); + h->setCaption( tr("Qt Linguist") ); + findMatchCase = FALSE; + findWhere = 0; + foundItem = 0; + foundScope = 0; + foundWhere = 0; + foundOffset = 0; + + connect( lv, SIGNAL(selectionChanged(QListViewItem *)), + this, SLOT(showNewScope(QListViewItem *)) ); + + connect( slv, SIGNAL(currentChanged(QListViewItem *)), + this, SLOT(showNewCurrent(QListViewItem *)) ); + + connect( slv, SIGNAL(clicked(QListViewItem *, const QPoint&, int)), + this, SLOT(showNewCurrent(QListViewItem *)) ); + + connect( slv, SIGNAL(clicked(QListViewItem *, const QPoint&, int)), + this, SLOT(toggleFinished(QListViewItem *, const QPoint&, int)) ); + + connect( me, SIGNAL(translationChanged(const QString&)), + this, SLOT(updateTranslation(const QString&)) ); + connect( me, SIGNAL(finished(bool)), this, SLOT(updateFinished(bool)) ); + connect( me, SIGNAL(prevUnfinished()), this, SLOT(prevUnfinished()) ); + connect( me, SIGNAL(nextUnfinished()), this, SLOT(nextUnfinished()) ); + connect( me, SIGNAL(focusSourceList()), this, SLOT(focusSourceList()) ); + connect( me, SIGNAL(focusPhraseList()), this, SLOT(focusPhraseList()) ); + connect( f, SIGNAL(findNext(const QString&, int, bool)), + this, SLOT(findNext(const QString&, int, bool)) ); + + QWhatsThis::add( lv, tr("This panel lists the source contexts.") ); + + QWhatsThis::add( slv, tr("This panel lists the source texts. " + "Items that violate validation rules " + "are marked with a warning.") ); + showNewCurrent( 0 ); + + QSize as( qApp->desktop()->size() ); + as -= QSize( 30, 30 ); + resize( QSize( 1000, 800 ).boundedTo( as ) ); + readConfig(); + stats = 0; + srcWords = 0; + srcChars = 0; + srcCharsSpc = 0; +} + +TrWindow::~TrWindow() +{ + writeConfig(); + delete stats; +} + +void TrWindow::openFile( const QString& name ) +{ + if ( !name.isEmpty() ) { + statusBar()->message( tr("Loading...") ); + qApp->processEvents(); + tor.clear(); + if ( tor.load(name) ) { + slv->clear(); + slv->repaint(); + slv->viewport()->repaint(); + slv->setUpdatesEnabled( FALSE ); + slv->viewport()->setUpdatesEnabled( FALSE ); + lv->clear(); + lv->repaint(); + lv->viewport()->repaint(); + lv->setUpdatesEnabled( FALSE ); + lv->viewport()->setUpdatesEnabled( FALSE ); + setEnabled( FALSE ); + numFinished = 0; + numNonobsolete = 0; + numMessages = 0; + foundScope = 0; + + TML all = tor.messages(); + TML::Iterator it; + QDict contexts( 1009 ); + + srcWords = 0; + srcChars = 0; + srcCharsSpc = 0; + for ( it = all.begin(); it != all.end(); ++it ) { + qApp->processEvents(); + ContextLVI *c = contexts.find( QString((*it).context()) ); + if ( c == 0 ) { + c = new ContextLVI( lv, tor.toUnicode((*it).context(), + (*it).utf8()) ); + contexts.insert( QString((*it).context()), c ); + } + if ( QCString((*it).sourceText()) == ContextComment ) { + c->appendToComment( tor.toUnicode((*it).comment(), + (*it).utf8()) ); + } else { + MessageLVI * tmp = new MessageLVI( slv, *it, + tor.toUnicode((*it).sourceText(), + (*it).utf8()), + tor.toUnicode((*it).comment(), + (*it).utf8()), c ); + tmp->setDanger( danger(tmp->sourceText(), + tmp->translation()) && + tmp->message().type() == + MetaTranslatorMessage::Finished ); + c->instantiateMessageItem( slv, tmp ); + if ( (*it).type() != MetaTranslatorMessage::Obsolete ) { + numNonobsolete++; + if ( (*it).type() == MetaTranslatorMessage::Finished ) + numFinished++; + doCharCounting( tmp->sourceText(), srcWords, srcChars, srcCharsSpc ); + } else { + c->incrementObsoleteCount(); + } + numMessages++; + } + c->updateStatus(); + } + slv->viewport()->setUpdatesEnabled( TRUE ); + slv->setUpdatesEnabled( TRUE ); + lv->viewport()->setUpdatesEnabled( TRUE ); + lv->setUpdatesEnabled( TRUE ); + setEnabled( TRUE ); + slv->repaint(); + slv->viewport()->repaint(); + lv->triggerUpdate(); + updateProgress(); + filename = name; + dirty = FALSE; + updateCaption(); + me->showNothing(); + doneAndNextAct->setEnabled( FALSE ); + doneAndNextAlt->setEnabled( FALSE ); + messageIsShown = FALSE; + statusBar()->message( + tr("%1 source phrase(s) loaded.").arg(numMessages), + MessageMS ); + + foundItem = 0; + foundWhere = 0; + foundOffset = 0; + if ( lv->childCount() > 0 ) { + findAct->setEnabled( TRUE ); + findAgainAct->setEnabled( FALSE ); +#ifdef notyet + replaceAct->setEnabled( TRUE ); +#endif + lv->setCurrentItem( lv->firstChild() ); + } + addRecentlyOpenedFile( name, recentFiles ); + updateStatistics(); + } else { + statusBar()->clear(); + QMessageBox::warning( this, tr("Qt Linguist"), + tr("Cannot open '%1'.").arg(name) ); + } + } +} + +void TrWindow::open() +{ + if ( maybeSave() ) { + QString newFilename = QFileDialog::getOpenFileName( filename, + tr("Qt translation source (*.ts)\n" + "All files (*)"), + this, "open" ); + openFile( newFilename ); + } +} + +void TrWindow::save() +{ + if ( filename.isEmpty() ) + return; + + if ( tor.save(filename) ) { + dirty = FALSE; + updateCaption(); + statusBar()->message( tr("File saved."), MessageMS ); + } else { + QMessageBox::warning( this, tr("Qt Linguist"), tr("Cannot save '%1'.") + .arg(filename) ); + } +} + +void TrWindow::saveAs() +{ + QString newFilename = QFileDialog::getSaveFileName( filename, + tr( "Qt translation source (*.ts)\n" + "All files (*)"), + this, "save_as" ); + if ( !newFilename.isEmpty() ) { + filename = newFilename; + save(); + updateCaption(); + } +} + +void TrWindow::release() +{ + QString newFilename = filename; + newFilename.replace( QRegExp(".ts$"), "" ); + newFilename += QString( ".qm" ); + + newFilename = QFileDialog::getSaveFileName( newFilename, + tr("Qt message files for released applications (*.qm)\n" + "All files (*)"), + this, "release", + tr("Release") ); + if ( !newFilename.isEmpty() ) { + if ( tor.release(newFilename) ) + statusBar()->message( tr("File created."), MessageMS ); + else + QMessageBox::warning( this, tr("Qt Linguist"), + tr("Cannot save '%1'.").arg(newFilename) ); + } +} + +void TrWindow::print() +{ + int pageNum = 0; + + if ( printer.setup(this) ) { + QApplication::setOverrideCursor( WaitCursor ); + printer.setDocName( filename ); + statusBar()->message( tr("Printing...") ); + PrintOut pout( &printer ); + ContextLVI *c = (ContextLVI *) lv->firstChild(); + while ( c != 0 ) { + setCurrentContextItem( c ); + pout.vskip(); + pout.setRule( PrintOut::ThickRule ); + pout.setGuide( c->context() ); + pout.addBox( 100, tr("Context: %1").arg(c->context()), + PrintOut::Strong ); + pout.flushLine(); + pout.addBox( 4 ); + pout.addBox( 92, c->comment(), PrintOut::Emphasis ); + pout.flushLine(); + pout.setRule( PrintOut::ThickRule ); + + MessageLVI *m = (MessageLVI *) slv->firstChild(); + while ( m != 0 ) { + pout.setRule( PrintOut::ThinRule ); + + QString type; + switch ( m->message().type() ) { + case MetaTranslatorMessage::Finished: + type = tr( "finished" ); + break; + case MetaTranslatorMessage::Unfinished: + type = m->danger() ? tr( "unresolved" ) : QString( "unfinished" ); + break; + case MetaTranslatorMessage::Obsolete: + type = tr( "obsolete" ); + break; + default: + type = QString( "" ); + } + pout.addBox( 40, m->sourceText() ); + pout.addBox( 4 ); + pout.addBox( 40, m->translation() ); + pout.addBox( 4 ); + pout.addBox( 12, type, PrintOut::Normal, Qt::AlignRight ); + if ( !m->comment().isEmpty() ) { + pout.flushLine(); + pout.addBox( 4 ); + pout.addBox( 92, m->comment(), PrintOut::Emphasis ); + } + pout.flushLine( TRUE ); + + if ( pout.pageNum() != pageNum ) { + pageNum = pout.pageNum(); + statusBar()->message( tr("Printing... (page %1)") + .arg(pageNum) ); + } + m = (MessageLVI *) m->nextSibling(); + } + c = (ContextLVI *) c->nextSibling(); + } + pout.flushLine( TRUE ); + QApplication::restoreOverrideCursor(); + statusBar()->message( tr("Printing completed"), MessageMS ); + } else { + statusBar()->message( tr("Printing aborted"), MessageMS ); + } +} + +void TrWindow::find() +{ + h->hide(); + f->show(); + f->setActiveWindow(); + f->raise(); +} + +void TrWindow::findAgain() +{ + int pass = 0; + int oldItemNo = itemToIndex( slv, slv->currentItem() ); + QString delayedMsg; + QListViewItem * j = foundScope; + QListViewItem * k = indexToItem( slv, foundItem ); + QListViewItem * oldScope = lv->currentItem(); + + if ( lv->childCount() == 0 ) + return; +#if 1 + /* + As long as we don't implement highlighting of the text in the QTextView, + we may have only one match per message. + */ + foundOffset = (int) 0x7fffffff; +#else + foundOffset++; +#endif + slv->setUpdatesEnabled( FALSE ); + do { + // Iterate through every item in all contexts + if ( j == 0 ) { + j = lv->firstChild(); + setCurrentContextItem( j ); + if ( foundScope != 0 ) + delayedMsg = tr("Search wrapped."); + } + if ( k == 0 ) + k = slv->firstChild(); + + while ( k ) { + MessageLVI * m = (MessageLVI *) k; + switch ( foundWhere ) { + case 0: + foundWhere = FindDialog::SourceText; + foundOffset = 0; + // fall-through + case FindDialog::SourceText: + if ( searchItem( m->sourceText(), j, k ) ) { + f->hide(); + if ( !delayedMsg.isEmpty() ) + statusBar()->message( delayedMsg, MessageMS ); + return; + } + foundWhere = FindDialog::Translations; + foundOffset = 0; + // fall-through + case FindDialog::Translations: + if ( searchItem( m->translation(), j, k ) ) { + f->hide(); + if ( !delayedMsg.isEmpty() ) + statusBar()->message( delayedMsg, MessageMS ); + return; + } + foundWhere = FindDialog::Comments; + foundOffset = 0; + // fall-through + case FindDialog::Comments: + if ( searchItem( ((ContextLVI *) j)->fullContext(), j, k) ) { + f->hide(); + if ( !delayedMsg.isEmpty() ) + statusBar()->message( delayedMsg, MessageMS ); + return; + } + foundWhere = 0; + foundOffset = 0; + } + k = k->nextSibling(); + } + + j = j->nextSibling(); + if ( j ) { + setCurrentContextItem( j ); + k = slv->firstChild(); + } + } while ( pass++ != lv->childCount() ); + + // This is just to keep the current scope and source text item + // selected after a search failed. + if ( oldScope ) { + setCurrentContextItem( oldScope ); + QListViewItem * tmp = indexToItem( slv, oldItemNo ); + if( tmp ) + setCurrentMessageItem( tmp ); + } else { + if( lv->firstChild() ) + setCurrentContextItem( lv->firstChild() ); + if( slv->firstChild() ) + setCurrentMessageItem( slv->firstChild() ); + } + + slv->setUpdatesEnabled( TRUE ); + slv->triggerUpdate(); + qApp->beep(); + QMessageBox::warning( this, tr("Qt Linguist"), + QString( tr("Cannot find the string '%1'.") ).arg(findText) ); + foundItem = 0; + foundWhere = 0; + foundOffset = 0; +} + +void TrWindow::replace() +{ + f->hide(); + h->show(); + h->setActiveWindow(); + h->raise(); +} + +int TrWindow::itemToIndex( QListView * view, QListViewItem * item ) +{ + int no = 0; + QListViewItem * tmp; + + if( view && item ){ + if( (tmp = view->firstChild()) != 0 ) + do { + no++; + tmp = tmp->nextSibling(); + } while( tmp && (tmp != item) ); + } + return no; +} + +QListViewItem * TrWindow::indexToItem( QListView * view, int index ) +{ + QListViewItem * item = 0; + + if ( view && index > 0 ) { + item = view->firstChild(); + while( item && index-- > 0 ) + item = item->nextSibling(); + } + return item; +} + +bool TrWindow::searchItem( const QString & searchWhat, QListViewItem * j, + QListViewItem * k ) +{ + if ( (findWhere & foundWhere) != 0 ) { + foundOffset = searchWhat.find( findText, foundOffset, findMatchCase ); + if ( foundOffset >= 0 ) { + foundItem = itemToIndex( slv, k ); + foundScope = j; + setCurrentMessageItem( k ); + slv->setUpdatesEnabled( TRUE ); + slv->triggerUpdate(); + return TRUE; + } + } + foundOffset = 0; + return FALSE; +} + +void TrWindow::newPhraseBook() +{ + QString name; + for (;;) { + name = QFileDialog::getSaveFileName( QString::null, + tr("Qt phrase books (*.qph)\n" + "All files (*)"), + this, "new_phrasebook", + tr("Create New Phrase Book") ); + if ( !QFile::exists(name) ) + break; + QMessageBox::warning( this, tr("Qt Linguist"), + tr("A file called '%1' already exists." + " Please choose another name.").arg(name) ); + } + if ( !name.isEmpty() ) { + PhraseBook pb; + if ( savePhraseBook(name, pb) ) { + if ( openPhraseBook(name) ) + statusBar()->message( tr("Phrase book created."), MessageMS ); + } + } +} + +void TrWindow::openPhraseBook() +{ + QString phrasebooks( qInstallPathData() ); + QString name = QFileDialog::getOpenFileName( phrasebooks + "/phrasebooks", + tr("Qt phrase books (*.qph)\n" + "All files (*)"), + this, "open_phrasebook", + tr("Open Phrase Book") ); + if ( !name.isEmpty() && !phraseBookNames.contains(name) ) { + if ( openPhraseBook(name) ) { + int n = (int)(phraseBooks.at( phraseBooks.count() - 1 )->count()); + statusBar()->message( tr("%1 phrase(s) loaded.").arg(n), + MessageMS ); + } + } +} + +void TrWindow::closePhraseBook( int id ) +{ + int index = closePhraseBookp->indexOf( id ); + phraseBooks.remove( index ); + phraseBookNames.remove( phraseBookNames.at(index) ); + updatePhraseDict(); + + dirtyItem = index; // remove the item next time the menu is opened + editPhraseBookp->removeItem( editPhraseBookp->idAt(index) ); + printPhraseBookp->removeItem( printPhraseBookp->idAt(index) ); +} + +void TrWindow::editPhraseBook( int id ) +{ + int index = editPhraseBookp->indexOf( id ); + PhraseBookBox box( phraseBookNames[index], *phraseBooks.at(index), this, + "phrase book box", TRUE ); + box.setCaption( tr("%1 - %2").arg(tr("Qt Linguist")) + .arg(friendlyPhraseBookName(index)) ); + box.resize( 500, 300 ); + box.exec(); + *phraseBooks.at( index ) = box.phraseBook(); + updatePhraseDict(); +} + +void TrWindow::printPhraseBook( int id ) +{ + int index = printPhraseBookp->indexOf( id ); + int pageNum = 0; + + if ( printer.setup(this) ) { + printer.setDocName( phraseBookNames[index] ); + statusBar()->message( tr("Printing...") ); + PrintOut pout( &printer ); + PhraseBook *phraseBook = phraseBooks.at( index ); + PhraseBook::Iterator p; + pout.setRule( PrintOut::ThinRule ); + for ( p = phraseBook->begin(); p != phraseBook->end(); ++p ) { + pout.setGuide( (*p).source() ); + pout.addBox( 29, (*p).source() ); + pout.addBox( 4 ); + pout.addBox( 29, (*p).target() ); + pout.addBox( 4 ); + pout.addBox( 34, (*p).definition(), PrintOut::Emphasis ); + + if ( pout.pageNum() != pageNum ) { + pageNum = pout.pageNum(); + statusBar()->message( tr("Printing... (page %1)") + .arg(pageNum) ); + } + pout.setRule( PrintOut::NoRule ); + pout.flushLine( TRUE ); + } + pout.flushLine( TRUE ); + statusBar()->message( tr("Printing completed"), MessageMS ); + } else { + statusBar()->message( tr("Printing aborted"), MessageMS ); + } +} + +void TrWindow::revertSorting() +{ + lv->setSorting( 0 ); + slv->setSorting( 0 ); +} + +void TrWindow::manual() +{ + QAssistantClient *ac = new QAssistantClient( qInstallPathBins(), this ); + ac->showPage( QString( qInstallPathDocs() ) + "/html/linguist-manual.html" ); +} + +void TrWindow::about() +{ + AboutDialog about( this, 0, TRUE ); + about.versionLabel->setText( tr("Version %1").arg(QT_VERSION_STR) ); + about.exec(); +} + +void TrWindow::aboutQt() +{ + QMessageBox::aboutQt( this, tr("Qt Linguist") ); +} + +void TrWindow::setupPhrase() +{ + bool enabled = !phraseBooks.isEmpty(); + phrasep->setItemEnabled( closePhraseBookId, enabled ); + phrasep->setItemEnabled( editPhraseBookId, enabled ); + phrasep->setItemEnabled( printPhraseBookId, enabled ); +} + +void TrWindow::closeEvent( QCloseEvent *e ) +{ + if ( maybeSave() ) + e->accept(); + else + e->ignore(); +} + +bool TrWindow::maybeSave() +{ + if ( dirty ) { + switch ( QMessageBox::information(this, tr("Qt Linguist"), + tr("Do you want to save '%1'?") + .arg(filename), + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::No, + QMessageBox::Cancel | QMessageBox::Escape ) ) + { + case QMessageBox::Cancel: + return FALSE; + case QMessageBox::Yes: + save(); + return !dirty; + case QMessageBox::No: + break; + } + } + return TRUE; +} + +void TrWindow::updateCaption() +{ + QString cap; + bool enable = !filename.isEmpty(); + saveAct->setEnabled( enable ); + saveAsAct->setEnabled( enable ); + releaseAct->setEnabled( enable ); + printAct->setEnabled( enable ); + acceleratorsAct->setEnabled( enable ); + endingPunctuationAct->setEnabled( enable ); + phraseMatchesAct->setEnabled( enable ); + revertSortingAct->setEnabled( enable ); + + if ( filename.isEmpty() ) + cap = tr( "Qt Linguist by Trolltech" ); + else + cap = tr( "%1 - %2" ).arg( tr("Qt Linguist by Trolltech") ) + .arg( filename ); + setCaption( cap ); + modified->setEnabled( dirty ); +} + +// +// New scope selected - build a new list of source text items +// for that scope. +// +void TrWindow::showNewScope( QListViewItem *item ) +{ + static ContextLVI * oldContext = 0; + + if( item != 0 ) { + ContextLVI * c = (ContextLVI *) item; + bool upe = slv->isUpdatesEnabled(); + slv->setUpdatesEnabled( FALSE ); + slv->viewport()->setUpdatesEnabled( FALSE ); + if ( oldContext != 0 ) { + MessageLVI * tmp; + slv->blockSignals( TRUE ); + while ( (tmp = (MessageLVI *) slv->firstChild()) != 0 ) + oldContext->appendMessageItem( slv, tmp ); + slv->blockSignals( FALSE ); + } + MessageLVI * tmp; + while ( c->messageItemsInList() ) { + tmp = c->takeMessageItem( c->messageItemsInList() - 1); + slv->insertItem( tmp ); + tmp->updateTranslationText(); + } + + // Make sure that we update the source text and translation text. Use the first message in the new scope. + setCurrentMessageItem(slv->firstChild()); + // This must be explicitly called since the signal is not emitted if the context only contains one item + showNewCurrent(slv->firstChild()); + slv->viewport()->setUpdatesEnabled( upe ); + slv->setUpdatesEnabled( upe ); + if( upe ) + slv->triggerUpdate(); + oldContext = (ContextLVI *) item; + statusBar()->clear(); + } +} + +void TrWindow::showNewCurrent( QListViewItem *item ) +{ + messageIsShown = (item != 0); + MessageLVI *m = (MessageLVI *) item; + ContextLVI *c = (ContextLVI *) m ? m->contextLVI() : 0; + + if ( messageIsShown ) { + me->showMessage( m->sourceText(), m->comment(), c->fullContext(), + m->translation(), m->message().type(), + getPhrases(m->sourceText()) ); + if ( (m->message().type() != MetaTranslatorMessage::Finished) && + m->danger() ) + danger( m->sourceText(), m->translation(), TRUE ); + else + statusBar()->clear(); + + doneAndNextAct->setEnabled( m->message().type() != + MetaTranslatorMessage::Obsolete ); + } else { + if ( item == 0 ) + me->showNothing(); + else + me->showContext( c->fullContext(), c->finished() ); + doneAndNextAct->setEnabled( FALSE ); + } + doneAndNextAlt->setEnabled( doneAndNextAct->isEnabled() ); + + selectAllAct->setEnabled( messageIsShown ); +} + +void TrWindow::updateTranslation( const QString& translation ) +{ + QListViewItem *item = slv->currentItem(); + if ( item != 0 ) { + MessageLVI *m = (MessageLVI *) item; + if ( translation != m->translation() ) { + bool dngr; + m->setTranslation( translation ); + if ( m->finished() && + (dngr = danger( m->sourceText(), m->translation(), TRUE )) ) { + numFinished -= 1; + m->setDanger( dngr ); + m->setFinished( FALSE ); + m->contextLVI()->updateStatus(); + updateProgress(); + } + tor.insert( m->message() ); + if ( !dirty ) { + dirty = TRUE; + updateCaption(); + } + m->updateTranslationText(); + } + } +} + +void TrWindow::updateFinished( bool finished ) +{ + QListViewItem *item = slv->currentItem(); + if ( item != 0 ) { + MessageLVI *m = (MessageLVI *) item; + if ( finished != m->finished() ) { + numFinished += finished ? +1 : -1; + updateProgress(); + m->setFinished( finished ); + bool oldDanger = m->danger(); + m->setDanger( /*m->finished() &&*/ + danger(m->sourceText(), m->translation(), + !oldDanger) ); + if ( !oldDanger && m->danger() ) + qApp->beep(); + tor.insert( m->message() ); + if ( !dirty ) { + dirty = TRUE; + updateCaption(); + } + } + } +} + +void TrWindow::doneAndNext() +{ + MessageLVI * m = (MessageLVI *) slv->currentItem(); + bool dngr = FALSE; + + if ( !m ) return; + dngr = danger( m->sourceText(), m->translation(), TRUE ); + if ( !dngr ) { + me->finishAndNext(); + m->contextLVI()->updateStatus(); + } else { + if ( m->danger() != dngr ) + m->setDanger( dngr ); + tor.insert( m->message() ); + if ( !dirty ) { + dirty = TRUE; + updateCaption(); + } + qApp->beep(); + } + updateStatistics(); +} + +void TrWindow::toggleFinished( QListViewItem *item, const QPoint& /* p */, + int column ) +{ + if ( item != 0 && column == 0 ) { + MessageLVI *m = (MessageLVI *) item; + bool dngr = FALSE; + + if ( m->message().type() == MetaTranslatorMessage::Unfinished ) { + dngr = danger( m->sourceText(), m->translation(), TRUE ); + } + if ( !dngr && m->message().type() != MetaTranslatorMessage::Obsolete) { + setCurrentMessageItem( m ); + me->setFinished( !m->finished() ); + m->contextLVI()->updateStatus(); + } else { + bool oldDanger = m->danger(); + m->setDanger( danger(m->sourceText(), m->translation(), + !oldDanger) ); + if ( !oldDanger && m->danger() ) + qApp->beep(); + tor.insert( m->message() ); + if ( !dirty ) { + dirty = TRUE; + updateCaption(); + } + } + updateStatistics(); + } +} + +void TrWindow::nextUnfinished() +{ + if ( nextUnfinishedAct->isEnabled() ) { + // Select a message to translate, grab the first available if + // there are no current selection. + QListViewItem * cItem = lv->currentItem(); // context item + QListViewItem * mItem = slv->currentItem(); // message item + + // Make sure an item is selected from both the context and the + // message list. + if( (mItem == 0) && !(mItem = slv->firstChild()) ) { + if( (cItem == 0) && !(cItem = lv->firstChild()) ) { + statusBar()->message( tr("No phrase to translate."), + MessageMS ); + qApp->beep(); + return; + } else { + showNewScope( cItem ); + while( cItem && !(mItem = slv->firstChild()) ) { + // no children in this node - try next one + cItem = cItem->nextSibling(); + showNewScope( cItem ); + } + setCurrentContextItem( cItem ); + if( mItem ) { + setCurrentMessageItem( mItem ); + } else { + statusBar()->message( tr("No phrase to translate."), + MessageMS ); + qApp->beep(); + return; + } + } + } else { + setCurrentMessageItem( mItem ); + } + + MessageLVI * m = (MessageLVI *) mItem; + MessageLVI * n; + ContextLVI * p = (ContextLVI *) cItem; + ContextLVI * q; + + // Find the next Unfinished sibling within the same context. + m = (MessageLVI *) mItem->nextSibling(); + n = m; + do { + if ( n == 0 ) + break; + if ( n && !n->finished() && n != mItem ) { + setCurrentMessageItem( n ); + return; + } + n = (MessageLVI *) n->nextSibling(); + } while ( n != m ); + + // If all siblings are Finished or Obsolete, look in the first + // Unfinished context. + p = (ContextLVI *) p->nextSibling(); + q = p; + do { + if ( q == 0 ) + q = (ContextLVI *) lv->firstChild(); + if ( q && !q->finished() ) { + showNewScope( q ); + setCurrentContextItem( q ); + n = (MessageLVI *) slv->firstChild(); + while ( n && n->finished() ) + n = (MessageLVI *) n->nextSibling(); + if ( n && q ) { + setCurrentMessageItem( n ); + showNewCurrent( n ); + return; + } + } + q = (ContextLVI *) q->nextSibling(); + } while ( q != p ); + } + + // If no Unfinished message is left, the user has finished the job. We + // congratulate on a job well done with this ringing bell. + statusBar()->message( tr("No untranslated phrases left."), MessageMS ); + qApp->beep(); +} + +static QListViewItem * lastChild( QListView * view ) +{ + if ( view ) { + QListViewItem * ret, * tmp; + ret = view->firstChild(); + while ( ret ) { + tmp = ret->nextSibling(); + if ( tmp == 0 ) + return ret; + ret = tmp; + } + } + return 0; +} + +void TrWindow::prevUnfinished() +{ + if ( prevUnfinishedAct->isEnabled() ) { + // Select a message to translate, grab the first available if + // there are no current selection. + QListViewItem * cItem = lv->currentItem(); // context item + QListViewItem * mItem = slv->currentItem(); // message item + + // Make sure an item is selected from both the context and the + // message list. + if( (mItem == 0) && !(mItem = slv->firstChild()) ) { + if( (cItem == 0) && !(cItem = lv->firstChild()) ) { + statusBar()->message( tr("No phrase to translate."), + MessageMS ); + qApp->beep(); + return; + } else { + showNewScope( cItem ); + while( cItem && !(mItem = slv->firstChild()) ) { + // no children in this node - try next one + cItem = cItem->nextSibling(); + showNewScope( cItem ); + } + setCurrentContextItem( cItem ); + if( mItem ) { + setCurrentMessageItem( cItem ); + } else { + statusBar()->message( tr("No phrase to translate."), + MessageMS ); + qApp->beep(); + return; + } + } + } else { + setCurrentMessageItem( mItem ); + } + + MessageLVI * m = (MessageLVI *) mItem; + MessageLVI * n; + ContextLVI * p = (ContextLVI *) cItem; + ContextLVI * q; + + // Find the next Unfinished sibling within the same context. + n = m; + do { + n = (MessageLVI * ) n->itemAbove(); + if ( n == 0 ) + break; + if ( n && !n->finished() ) { + setCurrentMessageItem( n ); + return; + } + } while ( !((ContextLVI *) cItem)->finished() && n != 0 ); + + // If all siblings are Finished or Obsolete, look in the prev + // Unfinished context. + q = p; + do { + q = (ContextLVI *) q->itemAbove(); + if ( q == 0 ) + q = (ContextLVI *) lastChild( lv ); + if ( q && !q->finished() ) { + showNewScope( q ); + setCurrentContextItem( q ); + n = (MessageLVI *) lastChild( slv ); + while ( n && n->finished() ) + n = (MessageLVI *) n->itemAbove(); + if ( n && q ) { + setCurrentMessageItem( n ); + return; + } + } + } while ( q != 0 ); + } + statusBar()->message( tr("No untranslated phrases left."), MessageMS ); + qApp->beep(); +} + +void TrWindow::prev() +{ + QListViewItem * cItem = lv->currentItem(); // context item + QListViewItem * mItem = slv->currentItem(); // message item + QListViewItem * tmp; + + if ( !cItem ) { + cItem = lv->firstChild(); + if ( !cItem ) return; + setCurrentContextItem( cItem ); + } + + if ( !mItem ) { + mItem = lastChild( slv ); + if ( !mItem ) return; + setCurrentMessageItem( mItem ); + } else { + if ( (tmp = mItem->itemAbove()) != 0 ) { + setCurrentMessageItem( tmp ); + return; + } else { + if ( (tmp = cItem->itemAbove()) == 0 ) { + tmp = lastChild( lv ); + } + if ( !tmp ) return; + setCurrentContextItem( tmp ); + setCurrentMessageItem( lastChild( slv ) ); + } + } +} + +void TrWindow::next() +{ + QListViewItem * cItem = lv->currentItem(); // context item + QListViewItem * mItem = slv->currentItem(); // message item + QListViewItem * tmp; + + if ( !cItem ) { + cItem = lv->firstChild(); + if ( !cItem ) return; + setCurrentContextItem( cItem ); + } + + if ( !mItem ) { + mItem = slv->firstChild(); + if ( !mItem ) return; + setCurrentMessageItem( mItem ); + } else { + if ( (tmp = mItem->nextSibling()) != 0 ) { + setCurrentMessageItem( tmp ); + return; + } else { + if ( (tmp = cItem->nextSibling()) == 0 ) { + tmp = lv->firstChild(); + } + if ( !tmp ) return; + setCurrentContextItem( tmp ); + setCurrentMessageItem( slv->firstChild() ); + } + } +} + + +void TrWindow::findNext( const QString& text, int where, bool matchCase ) +{ + findText = text; + if ( findText.isEmpty() ) + findText = QString( "magicwordthatyoushouldavoid" ); + findWhere = where; + findMatchCase = matchCase; + findAgainAct->setEnabled( TRUE ); + findAgain(); +} + +void TrWindow::revalidate() +{ + ContextLVI *c = (ContextLVI *) lv->firstChild(); + QListViewItem * oldScope = lv->currentItem(); + int oldItemNo = itemToIndex( slv, slv->currentItem() ); + slv->setUpdatesEnabled( FALSE ); + + while ( c != 0 ) { + showNewScope( c ); + MessageLVI *m = (MessageLVI *) slv->firstChild(); + while ( m != 0 ) { + m->setDanger( danger(m->sourceText(), m->translation()) && + m->message().type() == MetaTranslatorMessage::Finished ); + m = (MessageLVI *) m->nextSibling(); + } + c = (ContextLVI *) c->nextSibling(); + } + + if ( oldScope ){ + showNewScope( oldScope ); + QListViewItem * tmp = indexToItem( slv, oldItemNo ); + if( tmp ) + setCurrentMessageItem( tmp ); + } + slv->setUpdatesEnabled( TRUE ); + slv->triggerUpdate(); +} + +QString TrWindow::friendlyString( const QString& str ) +{ + QString f = str.lower(); + f.replace( QRegExp(QString("[.,:;!?()-]")), QString(" ") ); + f.replace( "&", QString("") ); + f = f.simplifyWhiteSpace(); + f = f.lower(); + return f; +} + +void TrWindow::setupMenuBar() +{ + QMenuBar * m = menuBar(); + QPopupMenu * filep = new QPopupMenu( this ); + QPopupMenu * editp = new QPopupMenu( this ); + QPopupMenu * translationp = new QPopupMenu( this ); + QPopupMenu * validationp = new QPopupMenu( this ); + validationp->setCheckable( TRUE ); + phrasep = new QPopupMenu( this ); + closePhraseBookp = new QPopupMenu( this ); + editPhraseBookp = new QPopupMenu( this ); + printPhraseBookp = new QPopupMenu( this ); + QPopupMenu * viewp = new QPopupMenu( this ); + viewp->setCheckable( TRUE ); + QPopupMenu * helpp = new QPopupMenu( this ); + + m->insertItem( tr("&File"), filep ); + m->insertItem( tr("&Edit"), editp ); + m->insertItem( tr("&Translation"), translationp ); + m->insertItem( tr("V&alidation"), validationp ); + m->insertItem( tr("&Phrases"), phrasep ); + m->insertItem( tr("&View"), viewp ); + m->insertSeparator(); + m->insertItem( tr("&Help"), helpp ); + + connect( closePhraseBookp, SIGNAL(activated(int)), + this, SLOT(closePhraseBook(int)) ); + connect( closePhraseBookp, SIGNAL(aboutToShow()), + this, SLOT(updateClosePhraseBook()) ); + connect( editPhraseBookp, SIGNAL(activated(int)), + this, SLOT(editPhraseBook(int)) ); + connect( printPhraseBookp, SIGNAL(activated(int)), + this, SLOT(printPhraseBook(int)) ); + // File menu + openAct = new Action( filep, tr("&Open..."), this, SLOT(open()), + "fileopen.png", QAccel::stringToKey(tr("Ctrl+O")) ); + + filep->insertSeparator(); + + saveAct = new Action( filep, tr("&Save"), this, SLOT(save()), + "filesave.png", QAccel::stringToKey(tr("Ctrl+S")) ); + saveAsAct = new Action( filep, tr("Save &As..."), this, SLOT(saveAs()) ); + releaseAct = new Action( filep, tr("&Release..."), this, SLOT(release()) ); + filep->insertSeparator(); + printAct = new Action( filep, tr("&Print..."), this, SLOT(print()), + "print.png", QAccel::stringToKey(tr("Ctrl+P")) ); + + filep->insertSeparator(); + + recentFilesMenu = new QPopupMenu( this ); + filep->insertItem( tr("Re¢ly opened files"), recentFilesMenu ); + connect( recentFilesMenu, SIGNAL(aboutToShow()), this, + SLOT(setupRecentFilesMenu()) ); + connect( recentFilesMenu, SIGNAL(activated( int )), this, + SLOT(recentFileActivated( int )) ); + + filep->insertSeparator(); + + exitAct = new Action( filep, tr("E&xit"), this, SLOT(close()), + QString::null, QAccel::stringToKey(tr("Ctrl+Q")) ); + // Edit menu + undoAct = new Action( editp, tr("&Undo"), me, SLOT(undo()), + "undo.png", QAccel::stringToKey(tr("Ctrl+Z")) ); + undoAct->setEnabled( FALSE ); + connect( me, SIGNAL(undoAvailable(bool)), undoAct, SLOT(setEnabled(bool)) ); + redoAct = new Action( editp, tr("&Redo"), me, SLOT(redo()), + "redo.png", QAccel::stringToKey(tr("Ctrl+Y")) ); + redoAct->setEnabled( FALSE ); + connect( me, SIGNAL(redoAvailable(bool)), redoAct, SLOT(setEnabled(bool)) ); + editp->insertSeparator(); + cutAct = new Action( editp, tr("Cu&t"), me, SLOT(cut()), + "editcut.png", QAccel::stringToKey(tr("Ctrl+X")) ); + cutAct->setEnabled( FALSE ); + connect( me, SIGNAL(cutAvailable(bool)), cutAct, SLOT(setEnabled(bool)) ); + copyAct = new Action( editp, tr("&Copy"), me, SLOT(copy()), + "editcopy.png", QAccel::stringToKey(tr("Ctrl+C")) ); + copyAct->setEnabled( FALSE ); + connect( me, SIGNAL(copyAvailable(bool)), copyAct, SLOT(setEnabled(bool)) ); + pasteAct = new Action( editp, tr("&Paste"), me, SLOT(paste()), + "editpaste.png", QAccel::stringToKey(tr("Ctrl+V")) ); + pasteAct->setEnabled( FALSE ); + connect( me, SIGNAL(pasteAvailable(bool)), + pasteAct, SLOT(setEnabled(bool)) ); + selectAllAct = new Action( editp, tr("Select &All"), me, SLOT(selectAll()), + QString::null, QAccel::stringToKey(tr("Ctrl+A")) ); + selectAllAct->setEnabled( FALSE ); + editp->insertSeparator(); + findAct = new Action( editp, tr("&Find..."), this, SLOT(find()), + "searchfind.png", QAccel::stringToKey(tr("Ctrl+F")) ); + findAct->setEnabled( FALSE ); + findAgainAct = new Action( editp, tr("Find &Next"), + this, SLOT(findAgain()), QString::null, Key_F3 ); + findAgainAct->setEnabled( FALSE ); +#ifdef notyet + replaceAct = new Action( editp, tr("&Replace..."), this, SLOT(replace()), + QAccel::stringToKey(tr("Ctrl+H")) ); + replaceAct->setEnabled( FALSE ); +#endif + + // Translation menu + // when updating the accelerators, remember the status bar + prevUnfinishedAct = new Action( translationp, tr("&Prev Unfinished"), + this, SLOT(prevUnfinished()), + "prevunfinished.png", QAccel::stringToKey(tr("Ctrl+K")) ); + nextUnfinishedAct = new Action( translationp, tr("&Next Unfinished"), + this, SLOT(nextUnfinished()), + "nextunfinished.png", QAccel::stringToKey(tr("Ctrl+L")) ); + + prevAct = new Action( translationp, tr("P&rev"), + this, SLOT(prev()), "prev.png", + QAccel::stringToKey(tr("Ctrl+Shift+K")) ); + nextAct = new Action( translationp, tr("Ne&xt"), + this, SLOT(next()), "next.png", + QAccel::stringToKey(tr("Ctrl+Shift+L")) ); + doneAndNextAct = new Action( translationp, tr("Done and &Next"), + this, SLOT(doneAndNext()), "doneandnext.png", + QAccel::stringToKey(tr("Ctrl+Enter")) ); + doneAndNextAlt = new QAction( this ); + doneAndNextAlt->setAccel( QAccel::stringToKey(tr("Ctrl+Return")) ); + connect( doneAndNextAlt, SIGNAL(activated()), this, SLOT(doneAndNext()) ); + beginFromSourceAct = new Action( translationp, tr("&Begin from Source"), + me, SLOT(beginFromSource()), + QString::null, QAccel::stringToKey(tr("Ctrl+B")) ); + connect( me, SIGNAL(updateActions(bool)), beginFromSourceAct, + SLOT(setEnabled(bool)) ); + + // Phrasebook menu + newPhraseBookAct = new Action( phrasep, tr("&New Phrase Book..."), + this, SLOT(newPhraseBook()), + QString::null, QAccel::stringToKey(tr("Ctrl+N")) ); + openPhraseBookAct = new Action( phrasep, tr("&Open Phrase Book..."), + this, SLOT(openPhraseBook()), + "book.png", QAccel::stringToKey(tr("Ctrl+H")) ); + closePhraseBookId = phrasep->insertItem( tr("&Close Phrase Book"), + closePhraseBookp ); + phrasep->insertSeparator(); + editPhraseBookId = phrasep->insertItem( tr("&Edit Phrase Book..."), + editPhraseBookp ); + printPhraseBookId = phrasep->insertItem( tr("&Print Phrase Book..."), + printPhraseBookp ); + connect( phrasep, SIGNAL(aboutToShow()), this, SLOT(setupPhrase()) ); + + // Validation menu + acceleratorsAct = new Action( validationp, tr("&Accelerators"), + this, SLOT(revalidate()), "accelerator.png", 0, TRUE ); + acceleratorsAct->setOn( TRUE ); + endingPunctuationAct = new Action( validationp, tr("&Ending Punctuation"), + this, SLOT(revalidate()), "punctuation.png", 0, TRUE ); + endingPunctuationAct->setOn( TRUE ); + phraseMatchesAct = new Action( validationp, tr("&Phrase Matches"), + this, SLOT(revalidate()), "phrase.png", 0, TRUE ); + phraseMatchesAct->setOn( TRUE ); + + // View menu + revertSortingAct = new Action( viewp, tr("&Revert Sorting"), + this, SLOT(revertSorting()) ); + doGuessesAct = new Action( viewp, tr("&Display guesses"), + this, SLOT(toggleGuessing()) ); + doGuessesAct->setToggleAction( TRUE ); + doGuessesAct->setOn( TRUE ); + toggleStats = new Action( viewp, tr("&Statistics"), this, SLOT(toggleStatistics()) ); + toggleStats->setToggleAction( TRUE ); + viewp->insertSeparator(); + viewp->insertItem( tr("Vie&ws"), createDockWindowMenu( NoToolBars ) ); + viewp->insertItem( tr("&Toolbars"), createDockWindowMenu( OnlyToolBars ) ); + + // Help + manualAct = new Action( helpp, tr("&Manual"), this, SLOT(manual()), 0, + Key_F1 ); + helpp->insertSeparator(); + aboutAct = new Action( helpp, tr("&About"), this, SLOT(about()) ); + aboutQtAct = new Action( helpp, tr("About &Qt"), this, SLOT(aboutQt()) ); + helpp->insertSeparator(); + whatsThisAct = new Action( helpp, tr("&What's This?"), + this, SLOT(whatsThis()), "whatsthis.xpm", SHIFT + Key_F1 ); + + openAct->setWhatsThis( tr("Open a Qt translation source file (TS file) for" + " editing.") ); + saveAct->setWhatsThis( tr("Save changes made to this Qt translation " + "source file.") ); + saveAsAct->setWhatsThis( tr("Save changes made to this Qt translation" + "source file into a new file.") ); + releaseAct->setWhatsThis( tr("Create a Qt message file suitable for" + " released applications" + " from the current message file.") ); + printAct->setWhatsThis( tr("Print a list of all the phrases in the current" + " Qt translation source file.") ); + exitAct->setWhatsThis( tr("Close this window and exit.") ); + + undoAct->setWhatsThis( tr("Undo the last editing operation performed on the" + " translation.") ); + redoAct->setWhatsThis( tr("Redo an undone editing operation performed on" + " the translation.") ); + cutAct->setWhatsThis( tr("Copy the selected translation text to the" + " clipboard and deletes it.") ); + copyAct->setWhatsThis( tr("Copy the selected translation text to the" + " clipboard.") ); + pasteAct->setWhatsThis( tr("Paste the clipboard text into the" + " translation.") ); + selectAllAct->setWhatsThis( tr("Select the whole translation text.") ); + findAct->setWhatsThis( tr("Search for some text in the translation " + "source file.") ); + findAgainAct->setWhatsThis( tr("Continue the search where it was left.") ); +#ifdef notyet + replaceAct->setWhatsThis( tr("Search for some text in the translation" + " source file and replace it by another" + " text.") ); +#endif + + newPhraseBookAct->setWhatsThis( tr("Create a new phrase book.") ); + openPhraseBookAct->setWhatsThis( tr("Open a phrase book to assist" + " translation.") ); + acceleratorsAct->setWhatsThis( tr("Toggle validity checks of" + " accelerators.") ); + endingPunctuationAct->setWhatsThis( tr("Toggle validity checks" + " of ending punctuation.") ); + phraseMatchesAct->setWhatsThis( tr("Toggle checking that phrase" + " suggestions are used.") ); + + revertSortingAct->setWhatsThis( tr("Sort the items back in the same order" + " as in the message file.") ); + + doGuessesAct->setWhatsThis( tr("Set whether or not to display translation guesses.") ); + manualAct->setWhatsThis( tr("Display the manual for %1.") + .arg(tr("Qt Linguist")) ); + aboutAct->setWhatsThis( tr("Display information about %1.") + .arg(tr("Qt Linguist")) ); + aboutQtAct->setWhatsThis( tr("Display information about the Qt toolkit by" + " Trolltech.") ); + whatsThisAct->setWhatsThis( tr("Enter What's This? mode.") ); + + beginFromSourceAct->setWhatsThis( tr("Copies the source text into" + " the translation field.") ); + nextAct->setWhatsThis( tr("Moves to the next item.") ); + prevAct->setWhatsThis( tr("Moves to the previous item.") ); + nextUnfinishedAct->setWhatsThis( tr("Moves to the next unfinished item.") ); + prevUnfinishedAct->setWhatsThis( tr("Moves to the previous unfinished item.") ); + doneAndNextAct->setWhatsThis( tr("Marks this item as done and moves to the" + " next unfinished item.") ); + doneAndNextAlt->setWhatsThis( doneAndNextAct->whatsThis() ); +} + +void TrWindow::setupToolBars() +{ + QToolBar *filet = new QToolBar( tr("File"), this ); + QToolBar *editt = new QToolBar( tr("Edit"), this ); + QToolBar *translationst = new QToolBar( tr("Translation"), this ); + QToolBar *validationt = new QToolBar( tr("Validation"), this ); + QToolBar *helpt = new QToolBar( tr("Help"), this ); + + openAct->addToToolbar( filet, tr("Open") ); + saveAct->addToToolbar( filet, tr("Save") ); + printAct->addToToolbar( filet, tr("Print") ); + filet->addSeparator(); + openPhraseBookAct->addToToolbar( filet, tr("Open Phrase Book") ); + + undoAct->addToToolbar( editt, tr("Undo") ); + redoAct->addToToolbar( editt, tr("Redo") ); + editt->addSeparator(); + cutAct->addToToolbar( editt, tr("Cut") ); + copyAct->addToToolbar( editt, tr("Copy") ); + pasteAct->addToToolbar( editt, tr("Paste") ); + editt->addSeparator(); + findAct->addToToolbar( editt, tr("Find") ); +#ifdef notyet + replaceAct->addToToolbar( editt, tr("Replace") ); +#endif + + // beginFromSourceAct->addToToolbar( translationst, + // tr("Begin from Source"), "searchfind" ); + prevAct->addToToolbar( translationst, tr("Prev") ); + nextAct->addToToolbar( translationst, tr("Next") ); + prevUnfinishedAct->addToToolbar( translationst, tr("Prev Unfinished") ); + nextUnfinishedAct->addToToolbar( translationst, tr("Next Unfinished") ); + doneAndNextAct->addToToolbar( translationst, tr("Done and Next") ); + + acceleratorsAct->addToToolbar( validationt, tr("Accelerators") ); + endingPunctuationAct->addToToolbar( validationt, tr("Punctuation") ); + phraseMatchesAct->addToToolbar( validationt, tr("Phrases") ); + + whatsThisAct->addToToolbar( helpt, tr("What's This?") ); +} + +void TrWindow::setCurrentContextItem( QListViewItem *item ) +{ + lv->ensureItemVisible( item ); + lv->setSelected( item, TRUE ); +} + +void TrWindow::setCurrentMessageItem( QListViewItem *item ) +{ + slv->ensureItemVisible( item ); + slv->setSelected( item, TRUE ); +} + +QString TrWindow::friendlyPhraseBookName( int k ) +{ + return QFileInfo( phraseBookNames[k] ).fileName(); +} + +bool TrWindow::openPhraseBook( const QString& name ) +{ + PhraseBook *pb = new PhraseBook; + if ( !pb->load(name) ) { + QMessageBox::warning( this, tr("Qt Linguist"), + tr("Cannot read from phrase book '%1'.") + .arg(name) ); + return FALSE; + } + + int index = (int) phraseBooks.count(); + phraseBooks.append( pb ); + phraseBookNames.append( name ); + int id = closePhraseBookp->insertItem( friendlyPhraseBookName(index) ); + closePhraseBookp->setWhatsThis( id, tr("Close this phrase book.") ); + id = editPhraseBookp->insertItem( friendlyPhraseBookName(index) ); + editPhraseBookp->setWhatsThis( id, tr("Allow you to add, modify, or delete" + " phrases of this phrase book.") ); + id = printPhraseBookp->insertItem( friendlyPhraseBookName(index) ); + printPhraseBookp->setWhatsThis( id, tr("Print the entries of the phrase" + " book.") ); + updatePhraseDict(); + return TRUE; +} + +bool TrWindow::savePhraseBook( QString& name, const PhraseBook& pb ) +{ + if ( !name.contains( ".qph" ) && !name.contains(".") ) + name += ".qph"; + + if ( !pb.save(name) ) { + QMessageBox::warning( this, tr("Qt Linguist"), + tr("Cannot create phrase book '%1'.") + .arg(name) ); + return FALSE; + } + return TRUE; +} + +void TrWindow::updateProgress() +{ + if ( numNonobsolete == 0 ) + progress->setText( QString(" " " ") ); + else + progress->setText( QString(" %1/%2 ").arg(numFinished) + .arg(numNonobsolete) ); + prevUnfinishedAct->setEnabled( numFinished != numNonobsolete ); + nextUnfinishedAct->setEnabled( numFinished != numNonobsolete ); + prevAct->setEnabled( lv->firstChild() != 0 ); + nextAct->setEnabled( lv->firstChild() != 0 ); +} + +void TrWindow::updatePhraseDict() +{ + QPtrListIterator pb = phraseBooks; + PhraseBook::Iterator p; + PhraseBook *ent; + phraseDict.clear(); + while ( pb.current() != 0 ) { + for ( p = (*pb)->begin(); p != (*pb)->end(); ++p ) { + QString f = friendlyString( (*p).source() ); + if ( f.length() > 0 ) { + f = QStringList::split( QChar(' '), f ).first(); + ent = phraseDict.find( f ); + if ( ent == 0 ) { + ent = new PhraseBook; + phraseDict.insert( f, ent ); + } + ent->append( *p ); + } + } + ++pb; + } + revalidate(); +} + +PhraseBook TrWindow::getPhrases( const QString& source ) +{ + PhraseBook phrases; + QString f = friendlyString( source ); + QStringList lookupWords = QStringList::split( QChar(' '), f ); + QStringList::Iterator w; + PhraseBook::Iterator p; + + for ( w = lookupWords.begin(); w != lookupWords.end(); ++w ) { + PhraseBook *ent = phraseDict.find( *w ); + if ( ent != 0 ) { + for ( p = ent->begin(); p != ent->end(); ++p ) { + if ( f.find(friendlyString((*p).source())) >= 0 ) + phrases.append( *p ); + } + } + } + return phrases; +} + +bool TrWindow::danger( const QString& source, const QString& translation, + bool verbose ) +{ + if ( acceleratorsAct->isOn() ) { + int sk = QAccel::shortcutKey( source ); + int tk = QAccel::shortcutKey( translation ); + if ( sk == 0 && tk != 0 ) { + if ( verbose ) + statusBar()->message( tr("Accelerator possibly superfluous in" + " translation."), ErrorMS ); + return TRUE; + } else if ( sk != 0 && tk == 0 ) { + if ( verbose ) + statusBar()->message( tr("Accelerator possibly missing in" + " translation."), ErrorMS ); + return TRUE; + } + } + if ( endingPunctuationAct->isOn() ) { + if ( ending(source) != ending(translation) ) { + if ( verbose ) + statusBar()->message( tr("Translation does not end with the" + " same punctuation as the source" + " text."), ErrorMS ); + return TRUE; + } + } + if ( phraseMatchesAct->isOn() ) { + QString fsource = friendlyString( source ); + QString ftranslation = friendlyString( translation ); + QStringList lookupWords = QStringList::split( QChar(' '), fsource ); + QStringList::Iterator w; + PhraseBook::Iterator p; + + for ( w = lookupWords.begin(); w != lookupWords.end(); ++w ) { + PhraseBook *ent = phraseDict.find( *w ); + if ( ent != 0 ) { + for ( p = ent->begin(); p != ent->end(); ++p ) { + if ( fsource.find(friendlyString((*p).source())) < 0 || + ftranslation.find(friendlyString((*p).target())) >= 0 ) + break; + } + if ( p == ent->end() ) { + if ( verbose ) + statusBar()->message( tr("A phrase book suggestion for" + " '%1' was ignored.") + .arg(*w), ErrorMS ); + return TRUE; + } + } + } + } + if ( verbose ) + statusBar()->clear(); + + return FALSE; +} + +void TrWindow::readConfig() +{ + QString keybase( "/Qt Linguist/" + + QString::number( (QT_VERSION >> 16) & 0xff ) + + "." + QString::number( (QT_VERSION >> 8) & 0xff ) + "/" ); + QSettings config; + + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + + QRect r( pos(), size() ); + recentFiles = config.readListEntry( keybase + "RecentlyOpenedFiles" ); + if ( !config.readBoolEntry( keybase + "Geometry/MainwindowMaximized", FALSE ) ) { + r.setX( config.readNumEntry( keybase + "Geometry/MainwindowX", r.x() ) ); + r.setY( config.readNumEntry( keybase + "Geometry/MainwindowY", r.y() ) ); + r.setWidth( config.readNumEntry( keybase + "Geometry/MainwindowWidth", r.width() ) ); + r.setHeight( config.readNumEntry( keybase + "Geometry/MainwindowHeight", r.height() ) ); + + QRect desk = QApplication::desktop()->geometry(); + QRect inter = desk.intersect( r ); + resize( r.size() ); + if ( inter.width() * inter.height() > ( r.width() * r.height() / 20 ) ) { + move( r.topLeft() ); + } + } + + QDockWindow * dw; + dw = (QDockWindow *) lv->parent(); + int place; + place = config.readNumEntry( keybase + "Geometry/ContextwindowInDock" ); + r.setX( config.readNumEntry( keybase + "Geometry/ContextwindowX" ) ); + r.setY( config.readNumEntry( keybase + "Geometry/ContextwindowY" ) ); + r.setWidth( config.readNumEntry( keybase + + "Geometry/ContextwindowWidth" ) ); + r.setHeight( config.readNumEntry( keybase + + "Geometry/ContextwindowHeight" ) ); + if ( place == QDockWindow::OutsideDock ) { + dw->undock(); + dw->show(); + } + dw->setGeometry( r ); + + dw = (QDockWindow *) slv->parent(); + place = config.readNumEntry( keybase + "Geometry/SourcewindowInDock" ); + r.setX( config.readNumEntry( keybase + "Geometry/SourcewindowX" ) ); + r.setY( config.readNumEntry( keybase + "Geometry/SourcewindowY" ) ); + r.setWidth( config.readNumEntry( keybase + + "Geometry/SourcewindowWidth" ) ); + r.setHeight( config.readNumEntry( keybase + + "Geometry/SourcewindowHeight" ) ); + if ( place == QDockWindow::OutsideDock ) { + dw->undock(); + dw->show(); + } + dw->setGeometry( r ); + + dw = (QDockWindow *) plv->parent()->parent(); + place = config.readNumEntry( keybase + "Geometry/PhrasewindowInDock" ); + r.setX( config.readNumEntry( keybase + "Geometry/PhrasewindowX" ) ); + r.setY( config.readNumEntry( keybase + "Geometry/PhrasewindowY" ) ); + r.setWidth( config.readNumEntry( keybase + + "Geometry/PhrasewindowWidth" ) ); + r.setHeight( config.readNumEntry( keybase + + "Geometry/PhrasewindowHeight" ) ); + if ( place == QDockWindow::OutsideDock ) { + dw->undock(); + dw->show(); + } + dw->setGeometry( r ); + QApplication::sendPostedEvents(); +} + +void TrWindow::writeConfig() +{ + QString keybase( "/Qt Linguist/" + + QString::number( (QT_VERSION >> 16) & 0xff ) + + "." + QString::number( (QT_VERSION >> 8) & 0xff ) + "/" ); + QSettings config; + + config.insertSearchPath( QSettings::Windows, "/Trolltech" ); + config.writeEntry( keybase + "RecentlyOpenedFiles", recentFiles ); + config.writeEntry( keybase + "Geometry/MainwindowMaximized", isMaximized() ); + config.writeEntry( keybase + "Geometry/MainwindowX", x() ); + config.writeEntry( keybase + "Geometry/MainwindowY", y() ); + config.writeEntry( keybase + "Geometry/MainwindowWidth", width() ); + config.writeEntry( keybase + "Geometry/MainwindowHeight", height() ); + + QDockWindow * dw =(QDockWindow *) lv->parent(); + config.writeEntry( keybase + "Geometry/ContextwindowInDock", dw->place() ); + config.writeEntry( keybase + "Geometry/ContextwindowX", dw->x() ); + config.writeEntry( keybase + "Geometry/ContextwindowY", dw->y() ); + config.writeEntry( keybase + "Geometry/ContextwindowWidth", dw->width() ); + config.writeEntry( keybase + "Geometry/ContextwindowHeight", dw->height() ); + + dw =(QDockWindow *) slv->parent(); + config.writeEntry( keybase + "Geometry/SourcewindowInDock", + dw->place() ); + config.writeEntry( keybase + "Geometry/SourcewindowX", dw->geometry().x() ); + config.writeEntry( keybase + "Geometry/SourcewindowY", dw->geometry().y() ); + config.writeEntry( keybase + "Geometry/SourcewindowWidth", dw->width() ); + config.writeEntry( keybase + "Geometry/SourcewindowHeight", dw->height() ); + + dw =(QDockWindow *) plv->parent()->parent(); + config.writeEntry( keybase + "Geometry/PhrasewindowInDock", + dw->place() ); + config.writeEntry( keybase + "Geometry/PhrasewindowX", dw->geometry().x() ); + config.writeEntry( keybase + "Geometry/PhrasewindowY", dw->geometry().y() ); + config.writeEntry( keybase + "Geometry/PhrasewindowWidth", dw->width() ); + config.writeEntry( keybase + "Geometry/PhrasewindowHeight", dw->height() ); +} + +void TrWindow::setupRecentFilesMenu() +{ + recentFilesMenu->clear(); + int id = 0; + QStringList::Iterator it = recentFiles.begin(); + for ( ; it != recentFiles.end(); ++it ) + { + recentFilesMenu->insertItem( *it, id ); + id++; + } +} + +void TrWindow::recentFileActivated( int id ) +{ + if ( id != -1 ) { + if ( maybeSave() ) + openFile( *recentFiles.at( id ) ); + } +} + +void TrWindow::addRecentlyOpenedFile( const QString &fn, QStringList &lst ) +{ + if ( lst.find( fn ) != lst.end() ) + return; + if ( lst.count() >= 10 ) + lst.remove( lst.begin() ); + lst << fn; +} + +void TrWindow::toggleGuessing() +{ + me->toggleGuessing(); +} + +void TrWindow::focusSourceList() +{ + slv->setFocus(); +} + +void TrWindow::focusPhraseList() +{ + plv->setFocus(); +} + +void TrWindow::updateClosePhraseBook() +{ + if ( dirtyItem != -1 ) { + closePhraseBookp->removeItem( closePhraseBookp->idAt(dirtyItem) ); + dirtyItem = -1; + } +} + +void TrWindow::toggleStatistics() +{ + if ( toggleStats->isOn() ) { + if ( !stats ) { + stats = new Statistics( this, "linguist_stats" ); + connect( this, SIGNAL(statsChanged(int,int,int,int,int,int)), stats, + SLOT(updateStats(int,int,int,int,int,int)) ); + connect( stats, SIGNAL(closed()), toggleStats, SLOT(toggle()) ); + } + updateStatistics(); + stats->show(); + } else if ( stats ) { + stats->close(); + } +} + +void TrWindow::updateStatistics() +{ + QListViewItem * ci = lv->firstChild(); + int trW = 0; + int trC = 0; + int trCS = 0; + while ( ci ) { + countStats( ci, ((ContextLVI *)ci)->firstMessageItem(), trW, trC, trCS ); + ci = ci->nextSibling(); + } + // ..and the items in the source list + countStats( 0, slv->firstChild(), trW, trC, trCS ); + emit statsChanged( srcWords, srcChars, srcCharsSpc, trW, trC, trCS ); +} + + +void TrWindow::countStats( QListViewItem* ci, QListViewItem* mi, int& trW, int& trC, int& trCS ) +{ + MessageLVI * m; + while ( mi ) { + m = (MessageLVI *) mi; + if ( m->finished() && !(m->message().type() == MetaTranslatorMessage::Obsolete) ) + doCharCounting( m->translation(), trW, trC, trCS ); + if ( ci ) + mi = ((ContextLVI *)ci)->nextMessageItem(); + else + mi = mi->nextSibling(); + } +} + +void TrWindow::doCharCounting( const QString& text, int& trW, int& trC, int& trCS ) +{ + trCS += text.length(); + bool inWord = FALSE; + for ( int i = 0; i < (int) text.length(); i++ ) { + if ( text[i].isLetterOrNumber() || text[i] == QChar('_') ) { + if ( !inWord ) { + trW++; + inWord = TRUE; + } + } else { + inWord = FALSE; + } + if ( !text[i].isSpace() ) + trC++; + } +} diff --git a/tools/linguist/linguist/trwindow.h b/tools/linguist/linguist/trwindow.h new file mode 100644 index 0000000..38cba25 --- /dev/null +++ b/tools/linguist/linguist/trwindow.h @@ -0,0 +1,237 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef TRWINDOW_H +#define TRWINDOW_H + +#include "phrase.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +class QAction; +class QDialog; +class QLabel; +class QListView; +class QListViewItem; +class QPrinter; + +class Action; +class FindDialog; +class MessageEditor; + +class PhraseLV; +class ContextLVI; +class Statistics; + +class TrWindow : public QMainWindow +{ + Q_OBJECT +public: + static QPixmap * pxOn; + static QPixmap * pxOff; + static QPixmap * pxObsolete; + static QPixmap * pxDanger; + static const QPixmap pageCurl(); + + TrWindow(); + ~TrWindow(); + + void openFile( const QString& name ); + +protected: + void readConfig(); + void writeConfig(); + void closeEvent( QCloseEvent * ); + +signals: + void statsChanged( int w, int c, int cs, int w2, int c2, int cs2 ); + +private slots: + void doneAndNext(); + void prev(); + void next(); + void recentFileActivated( int ); + void setupRecentFilesMenu(); + void open(); + void save(); + void saveAs(); + void release(); + void print(); + void find(); + void findAgain(); + void replace(); + void newPhraseBook(); + void openPhraseBook(); + void closePhraseBook( int id ); + void editPhraseBook( int id ); + void printPhraseBook( int id ); + void manual(); + void revertSorting(); + void about(); + void aboutQt(); + + void setupPhrase(); + bool maybeSave(); + void updateCaption(); + void showNewScope( QListViewItem *item ); + void showNewCurrent( QListViewItem *item ); + void updateTranslation( const QString& translation ); + void updateFinished( bool finished ); + void toggleFinished( QListViewItem *item, const QPoint& p, int column ); + void prevUnfinished(); + void nextUnfinished(); + void findNext( const QString& text, int where, bool matchCase ); + void revalidate(); + void toggleGuessing(); + void focusSourceList(); + void focusPhraseList(); + void updateClosePhraseBook(); + void toggleStatistics(); + void updateStatistics(); + +private: + typedef QPtrList PBL; + typedef QDict PBD; + + static QString friendlyString( const QString& str ); + + void addRecentlyOpenedFile( const QString & fn, QStringList & lst ); + void setupMenuBar(); + void setupToolBars(); + void setCurrentContextItem( QListViewItem *item ); + void setCurrentMessageItem( QListViewItem *item ); + QString friendlyPhraseBookName( int k ); + bool openPhraseBook( const QString& name ); + bool savePhraseBook( QString& name, const PhraseBook& pb ); + void updateProgress(); + void updatePhraseDict(); + PhraseBook getPhrases( const QString& source ); + bool danger( const QString& source, const QString& translation, + bool verbose = FALSE ); + + int itemToIndex( QListView * view, QListViewItem * item ); + QListViewItem * indexToItem( QListView * view, int index ); + bool searchItem( const QString & searchWhat, QListViewItem * j, + QListViewItem * k ); + void countStats( QListViewItem * ci, QListViewItem * mi, int& trW, int& trC, int& trCS ); + void doCharCounting( const QString& text, int& trW, int& trC, int& trCS ); + + QListView * plv; + QListView * lv; + QListView * slv; + MessageEditor * me; + QLabel * progress; + QLabel * modified; + MetaTranslator tor; + bool dirty; + bool messageIsShown; + int numFinished; + int numNonobsolete; + int numMessages; + int dirtyItem; + QStringList recentFiles; + QString filename; + + PBD phraseDict; + PBL phraseBooks; + QStringList phraseBookNames; + + QPrinter printer; + + FindDialog *f; + FindDialog *h; + QString findText; + int findWhere; + bool findMatchCase; + int foundItem; + QListViewItem *foundScope; + int foundWhere; + int foundOffset; + + QPopupMenu * phrasep; + QPopupMenu * closePhraseBookp; + QPopupMenu * editPhraseBookp; + QPopupMenu * printPhraseBookp; + QPopupMenu * recentFilesMenu; + int closePhraseBookId; + int editPhraseBookId; + int printPhraseBookId; + Action *openAct; + Action *saveAct; + Action *saveAsAct; + Action *releaseAct; + Action *printAct; + Action *exitAct; + Action *undoAct; + Action *redoAct; + Action *cutAct; + Action *copyAct; + Action *pasteAct; + Action *selectAllAct; + Action *findAct; + Action *findAgainAct; + Action *replaceAct; + Action *newPhraseBookAct; + Action *openPhraseBookAct; + Action *acceleratorsAct; + Action *endingPunctuationAct; + Action *phraseMatchesAct; + Action *revertSortingAct; + Action *aboutAct; + Action *aboutQtAct; + Action *manualAct; + Action *whatsThisAct; + Action *beginFromSourceAct; + Action *prevAct; + Action *nextAct; + Action *prevUnfinishedAct; + Action *nextUnfinishedAct; + Action *doneAndNextAct; + QAction *doneAndNextAlt; + Action *doGuessesAct; + Action *toggleStats; + Statistics * stats; + int srcWords; + int srcChars; + int srcCharsSpc; +}; + +#endif diff --git a/tools/linguist/lrelease/lrelease.pro b/tools/linguist/lrelease/lrelease.pro new file mode 100644 index 0000000..755ea46 --- /dev/null +++ b/tools/linguist/lrelease/lrelease.pro @@ -0,0 +1,17 @@ +TEMPLATE = app +CONFIG += qt warn_on console +HEADERS = ../shared/metatranslator.h \ + ../shared/proparser.h +SOURCES = main.cpp \ + ../shared/metatranslator.cpp \ + ../shared/proparser.cpp + +DEFINES += QT_INTERNAL_XML +include( ../../../src/qt_professional.pri ) + +TARGET = lrelease +INCLUDEPATH += ../shared +DESTDIR = ../../../bin + +target.path=$$bins.path +INSTALLS += target diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp new file mode 100644 index 0000000..c76a034 --- /dev/null +++ b/tools/linguist/lrelease/main.cpp @@ -0,0 +1,203 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef QValueList TML; + +static void printUsage() +{ + fprintf( stderr, "Usage:\n" + " lrelease [options] project-file\n" + " lrelease [options] ts-files [-qm qm-file]\n" + "Options:\n" + " -help Display this information and exit\n" + " -nocompress\n" + " Do not compress the .qm files\n" + " -verbose\n" + " Explain what is being done\n" + " -version\n" + " Display the version of lrelease and exit\n" ); +} + +static bool loadTsFile( MetaTranslator& tor, const QString& tsFileName, + bool /* verbose */ ) +{ + QString qmFileName = tsFileName; + qmFileName.replace( QRegExp("\\.ts$"), "" ); + qmFileName += ".qm"; + + bool ok = tor.load( tsFileName ); + if ( !ok ) + fprintf( stderr, + "lrelease warning: For some reason, I cannot load '%s'\n", + tsFileName.latin1() ); + return ok; +} + +static void releaseMetaTranslator( const MetaTranslator& tor, + const QString& qmFileName, bool verbose, + bool stripped ) +{ + if ( verbose ) + fprintf( stderr, "Updating '%s'...\n", qmFileName.latin1() ); + if ( !tor.release(qmFileName, verbose, + stripped ? QTranslator::Stripped + : QTranslator::Everything) ) + fprintf( stderr, + "lrelease warning: For some reason, I cannot save '%s'\n", + qmFileName.latin1() ); +} + +static void releaseTsFile( const QString& tsFileName, bool verbose, + bool stripped ) +{ + MetaTranslator tor; + if ( loadTsFile(tor, tsFileName, verbose) ) { + QString qmFileName = tsFileName; + qmFileName.replace( QRegExp("\\.ts$"), "" ); + qmFileName += ".qm"; + releaseMetaTranslator( tor, qmFileName, verbose, stripped ); + } +} + +int main( int argc, char **argv ) +{ + bool verbose = FALSE; + bool stripped = TRUE; + bool metTranslations = FALSE; + MetaTranslator tor; + QString outputFile; + int numFiles = 0; + int i; + + for ( i = 1; i < argc; i++ ) { + if ( qstrcmp(argv[i], "-nocompress") == 0 ) { + stripped = FALSE; + continue; + } else if ( qstrcmp(argv[i], "-verbose") == 0 ) { + verbose = TRUE; + continue; + } else if ( qstrcmp(argv[i], "-version") == 0 ) { + fprintf( stderr, "lrelease version %s\n", QT_VERSION_STR ); + return 0; + } else if ( qstrcmp(argv[i], "-qm") == 0 ) { + if ( i == argc - 1 ) { + printUsage(); + return 1; + } else { + i++; + outputFile = argv[i]; + argv[i][0] = '-'; + } + } else if ( qstrcmp(argv[i], "-help") == 0 ) { + printUsage(); + return 0; + } else if ( argv[i][0] == '-' ) { + printUsage(); + return 1; + } else { + numFiles++; + } + } + + if ( numFiles == 0 ) { + printUsage(); + return 1; + } + + for ( i = 1; i < argc; i++ ) { + if ( argv[i][0] == '-' ) + continue; + + QFile f( argv[i] ); + if ( !f.open(IO_ReadOnly) ) { + fprintf( stderr, + "lrelease error: Cannot open file '%s': %s\n", argv[i], + strerror(errno) ); + return 1; + } + + QTextStream t( &f ); + QString fullText = t.read(); + f.close(); + + if ( fullText.find(QString("")) >= 0 ) { + if ( outputFile.isEmpty() ) { + releaseTsFile( argv[i], verbose, stripped ); + } else { + loadTsFile( tor, argv[i], verbose ); + } + } else { + QString oldDir = QDir::currentDirPath(); + QDir::setCurrent( QFileInfo(argv[i]).dirPath() ); + + QMap tagMap = proFileTagMap( fullText ); + QMap::Iterator it; + + for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { + QStringList toks = QStringList::split( ' ', it.data() ); + QStringList::Iterator t; + + for ( t = toks.begin(); t != toks.end(); ++t ) { + if ( it.key() == QString("TRANSLATIONS") ) { + metTranslations = TRUE; + releaseTsFile( *t, verbose, stripped ); + } + } + } + if ( !metTranslations ) + fprintf( stderr, + "lrelease warning: Met no 'TRANSLATIONS' entry in" + " project file '%s'\n", + argv[i] ); + QDir::setCurrent( oldDir ); + } + } + + if ( !outputFile.isEmpty() ) + releaseMetaTranslator( tor, outputFile, verbose, stripped ); + + return 0; +} diff --git a/tools/linguist/lupdate/fetchtr.cpp b/tools/linguist/lupdate/fetchtr.cpp new file mode 100644 index 0000000..ce8fb98 --- /dev/null +++ b/tools/linguist/lupdate/fetchtr.cpp @@ -0,0 +1,824 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* qmake ignore Q_OBJECT */ + +static const char MagicComment[] = "TRANSLATOR "; + +static QMap needs_Q_OBJECT; +static QMap lacks_Q_OBJECT; + +/* + The first part of this source file is the C++ tokenizer. We skip + most of C++; the only tokens that interest us are defined here. + Thus, the code fragment + + int main() + { + printf( "Hello, world!\n" ); + return 0; + } + + is broken down into the following tokens (Tok_ omitted): + + Ident Ident LeftParen RightParen + LeftBrace + Ident LeftParen String RightParen Semicolon + return Semicolon + RightBrace. + + The 0 doesn't produce any token. +*/ + +enum { Tok_Eof, Tok_class, Tok_namespace, Tok_return, Tok_tr, + Tok_trUtf8, Tok_translate, Tok_Q_OBJECT, Tok_Ident, + Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, + Tok_Gulbrandsen, Tok_LeftBrace, Tok_RightBrace, Tok_LeftParen, + Tok_RightParen, Tok_Comma, Tok_Semicolon }; + +/* + The tokenizer maintains the following global variables. The names + should be self-explanatory. +*/ +static QCString yyFileName; +static int yyCh; +static char yyIdent[128]; +static size_t yyIdentLen; +static char yyComment[65536]; +static size_t yyCommentLen; +static char yyString[65536]; +static size_t yyStringLen; +static QValueStack yySavedBraceDepth; +static QValueStack yySavedParenDepth; +static int yyBraceDepth; +static int yyParenDepth; +static int yyLineNo; +static int yyCurLineNo; +static int yyBraceLineNo; +static int yyParenLineNo; + +// the file to read from (if reading from a file) +static FILE *yyInFile; + +// the string to read from and current position in the string (otherwise) +static QString yyInStr; +static int yyInPos; + +static int (*getChar)(); + +static int getCharFromFile() +{ + int c = getc( yyInFile ); + if ( c == '\n' ) + yyCurLineNo++; + return c; +} + +static int getCharFromString() +{ + if ( yyInPos == (int) yyInStr.length() ) { + return EOF; + } else { + return yyInStr[yyInPos++].latin1(); + } +} + +static void startTokenizer( const char *fileName, int (*getCharFunc)() ) +{ + yyInPos = 0; + getChar = getCharFunc; + + yyFileName = fileName; + yyCh = getChar(); + yySavedBraceDepth.clear(); + yySavedParenDepth.clear(); + yyBraceDepth = 0; + yyParenDepth = 0; + yyCurLineNo = 1; + yyBraceLineNo = 1; + yyParenLineNo = 1; +} + +static int getToken() +{ + const char tab[] = "abfnrtv"; + const char backTab[] = "\a\b\f\n\r\t\v"; + uint n; + + yyIdentLen = 0; + yyCommentLen = 0; + yyStringLen = 0; + + while ( yyCh != EOF ) { + yyLineNo = yyCurLineNo; + + if ( isalpha(yyCh) || yyCh == '_' ) { + do { + if ( yyIdentLen < sizeof(yyIdent) - 1 ) + yyIdent[yyIdentLen++] = (char) yyCh; + yyCh = getChar(); + } while ( isalnum(yyCh) || yyCh == '_' ); + yyIdent[yyIdentLen] = '\0'; + + switch ( yyIdent[0] ) { + case 'Q': + if ( strcmp(yyIdent + 1, "_OBJECT") == 0 ) { + return Tok_Q_OBJECT; + } else if ( strcmp(yyIdent + 1, "T_TR_NOOP") == 0 ) { + return Tok_tr; + } else if ( strcmp(yyIdent + 1, "T_TRANSLATE_NOOP") == 0 ) { + return Tok_translate; + } + break; + case 'T': + // TR() for when all else fails + if ( qstricmp(yyIdent + 1, "R") == 0 ) + return Tok_tr; + break; + case 'c': + if ( strcmp(yyIdent + 1, "lass") == 0 ) + return Tok_class; + break; + case 'f': + /* + QTranslator::findMessage() has the same parameters as + QApplication::translate(). + */ + if ( strcmp(yyIdent + 1, "indMessage") == 0 ) + return Tok_translate; + break; + case 'n': + if ( strcmp(yyIdent + 1, "amespace") == 0 ) + return Tok_namespace; + break; + case 'r': + if ( strcmp(yyIdent + 1, "eturn") == 0 ) + return Tok_return; + break; + case 's': + if ( strcmp(yyIdent + 1, "truct") == 0 ) + return Tok_class; + break; + case 't': + if ( strcmp(yyIdent + 1, "r") == 0 ) { + return Tok_tr; + } else if ( qstrcmp(yyIdent + 1, "rUtf8") == 0 ) { + return Tok_trUtf8; + } else if ( qstrcmp(yyIdent + 1, "ranslate") == 0 ) { + return Tok_translate; + } + } + return Tok_Ident; + } else { + switch ( yyCh ) { + case '#': + /* + Early versions of lupdate complained about + unbalanced braces in the following code: + + #ifdef ALPHA + while ( beta ) { + #else + while ( gamma ) { + #endif + delta; + } + + The code contains, indeed, two opening braces for + one closing brace; yet there's no reason to panic. + + The solution is to remember yyBraceDepth as it was + when #if, #ifdef or #ifndef was met, and to set + yyBraceDepth to that value when meeting #elif or + #else. + */ + do { + yyCh = getChar(); + } while ( isspace(yyCh) && yyCh != '\n' ); + + switch ( yyCh ) { + case 'i': + yyCh = getChar(); + if ( yyCh == 'f' ) { + // if, ifdef, ifndef + yySavedBraceDepth.push( yyBraceDepth ); + yySavedParenDepth.push( yyParenDepth ); + } + break; + case 'e': + yyCh = getChar(); + if ( yyCh == 'l' ) { + // elif, else + if ( !yySavedBraceDepth.isEmpty() ) { + yyBraceDepth = yySavedBraceDepth.top(); + yyParenDepth = yySavedParenDepth.top(); + } + } else if ( yyCh == 'n' ) { + // endif + if ( !yySavedBraceDepth.isEmpty() ) { + yySavedBraceDepth.pop(); + yySavedParenDepth.pop(); + } + } + } + while ( isalnum(yyCh) || yyCh == '_' ) + yyCh = getChar(); + break; + case '/': + yyCh = getChar(); + if ( yyCh == '/' ) { + do { + yyCh = getChar(); + } while ( yyCh != EOF && yyCh != '\n' ); + } else if ( yyCh == '*' ) { + bool metAster = FALSE; + bool metAsterSlash = FALSE; + + while ( !metAsterSlash ) { + yyCh = getChar(); + if ( yyCh == EOF ) { + fprintf( stderr, + "%s: Unterminated C++ comment starting at" + " line %d\n", + (const char *) yyFileName, yyLineNo ); + yyComment[yyCommentLen] = '\0'; + return Tok_Comment; + } + if ( yyCommentLen < sizeof(yyComment) - 1 ) + yyComment[yyCommentLen++] = (char) yyCh; + + if ( yyCh == '*' ) + metAster = TRUE; + else if ( metAster && yyCh == '/' ) + metAsterSlash = TRUE; + else + metAster = FALSE; + } + yyCh = getChar(); + yyCommentLen -= 2; + yyComment[yyCommentLen] = '\0'; + return Tok_Comment; + } + break; + case '"': + yyCh = getChar(); + + while ( yyCh != EOF && yyCh != '\n' && yyCh != '"' ) { + if ( yyCh == '\\' ) { + yyCh = getChar(); + + if ( yyCh == '\n' ) { + yyCh = getChar(); + } else if ( yyCh == 'x' ) { + QCString hex = "0"; + + yyCh = getChar(); + while ( isxdigit(yyCh) ) { + hex += (char) yyCh; + yyCh = getChar(); + } + sscanf( hex, "%x", &n ); + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = (char) n; + } else if ( yyCh >= '0' && yyCh < '8' ) { + QCString oct = ""; + + do { + oct += (char) yyCh; + yyCh = getChar(); + } while ( yyCh >= '0' && yyCh < '8' ); + sscanf( oct, "%o", &n ); + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = (char) n; + } else { + const char *p = strchr( tab, yyCh ); + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = ( p == 0 ) ? + (char) yyCh : backTab[p - tab]; + yyCh = getChar(); + } + } else { + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = (char) yyCh; + yyCh = getChar(); + } + } + yyString[yyStringLen] = '\0'; + + if ( yyCh != '"' ) + qWarning( "%s:%d: Unterminated C++ string", + (const char *) yyFileName, yyLineNo ); + + if ( yyCh == EOF ) { + return Tok_Eof; + } else { + yyCh = getChar(); + return Tok_String; + } + break; + case '-': + yyCh = getChar(); + if ( yyCh == '>' ) { + yyCh = getChar(); + return Tok_Arrow; + } + break; + case ':': + yyCh = getChar(); + if ( yyCh == ':' ) { + yyCh = getChar(); + return Tok_Gulbrandsen; + } + return Tok_Colon; + case '\'': + yyCh = getChar(); + if ( yyCh == '\\' ) + yyCh = getChar(); + + do { + yyCh = getChar(); + } while ( yyCh != EOF && yyCh != '\'' ); + yyCh = getChar(); + break; + case '{': + if (yyBraceDepth == 0) + yyBraceLineNo = yyCurLineNo; + yyBraceDepth++; + yyCh = getChar(); + return Tok_LeftBrace; + case '}': + if (yyBraceDepth == 0) + yyBraceLineNo = yyCurLineNo; + yyBraceDepth--; + yyCh = getChar(); + return Tok_RightBrace; + case '(': + if (yyParenDepth == 0) + yyParenLineNo = yyCurLineNo; + yyParenDepth++; + yyCh = getChar(); + return Tok_LeftParen; + case ')': + if (yyParenDepth == 0) + yyParenLineNo = yyCurLineNo; + yyParenDepth--; + yyCh = getChar(); + return Tok_RightParen; + case ',': + yyCh = getChar(); + return Tok_Comma; + case ';': + yyCh = getChar(); + return Tok_Semicolon; + default: + yyCh = getChar(); + } + } + } + return Tok_Eof; +} + +/* + The second part of this source file is the parser. It accomplishes + a very easy task: It finds all strings inside a tr() or translate() + call, and possibly finds out the context of the call. It supports + three cases: (1) the context is specified, as in + FunnyDialog::tr("Hello") or translate("FunnyDialog", "Hello"); + (2) the call appears within an inlined function; (3) the call + appears within a function defined outside the class definition. +*/ + +static int yyTok; + +static bool match( int t ) +{ + bool matches = ( yyTok == t ); + if ( matches ) + yyTok = getToken(); + return matches; +} + +static bool matchString( QCString *s ) +{ + bool matches = ( yyTok == Tok_String ); + *s = ""; + while ( yyTok == Tok_String ) { + *s += yyString; + yyTok = getToken(); + } + return matches; +} + +static bool matchEncoding( bool *utf8 ) +{ + if ( yyTok == Tok_Ident ) { + if ( strcmp(yyIdent, "QApplication") == 0 ) { + yyTok = getToken(); + if ( yyTok == Tok_Gulbrandsen ) + yyTok = getToken(); + } + *utf8 = QString( yyIdent ).endsWith( QString("UTF8") ); + yyTok = getToken(); + return TRUE; + } else { + return FALSE; + } +} + +static void parse( MetaTranslator *tor, const char *initialContext, + const char *defaultContext ) +{ + QMap qualifiedContexts; + QStringList namespaces; + QCString context; + QCString text; + QCString com; + QCString functionContext = initialContext; + QCString prefix; + bool utf8 = FALSE; + bool missing_Q_OBJECT = FALSE; + + yyTok = getToken(); + while ( yyTok != Tok_Eof ) { + switch ( yyTok ) { + case Tok_class: + /* + Partial support for inlined functions. + */ + yyTok = getToken(); + if ( yyBraceDepth == (int) namespaces.count() && + yyParenDepth == 0 ) { + do { + /* + This code should execute only once, but we play + safe with impure definitions such as + 'class Q_EXPORT QMessageBox', in which case + 'QMessageBox' is the class name, not 'Q_EXPORT'. + */ + functionContext = yyIdent; + yyTok = getToken(); + } while ( yyTok == Tok_Ident ); + + while ( yyTok == Tok_Gulbrandsen ) { + yyTok = getToken(); + functionContext += "::"; + functionContext += yyIdent; + yyTok = getToken(); + } + + if ( yyTok == Tok_Colon ) { + missing_Q_OBJECT = TRUE; + } else { + functionContext = defaultContext; + } + } + break; + case Tok_namespace: + yyTok = getToken(); + if ( yyTok == Tok_Ident ) { + QCString ns = yyIdent; + yyTok = getToken(); + if ( yyTok == Tok_LeftBrace && + yyBraceDepth == (int) namespaces.count() + 1 ) + namespaces.append( QString(ns) ); + } + break; + case Tok_tr: + case Tok_trUtf8: + utf8 = ( yyTok == Tok_trUtf8 ); + yyTok = getToken(); + if ( match(Tok_LeftParen) && matchString(&text) ) { + com = ""; + if ( match(Tok_RightParen) || (match(Tok_Comma) && + matchString(&com) && match(Tok_RightParen)) ) { + if ( prefix.isNull() ) { + context = functionContext; + if ( !namespaces.isEmpty() ) + context.prepend( (namespaces.join(QString("::")) + + QString("::")).latin1() ); + } else { + context = prefix; + } + prefix = (const char *) 0; + + if ( qualifiedContexts.contains(context) ) + context = qualifiedContexts[context]; + tor->insert( MetaTranslatorMessage(context, text, com, + QString::null, utf8) ); + + if ( lacks_Q_OBJECT.contains(context) ) { + qWarning( "%s:%d: Class '%s' lacks Q_OBJECT macro", + (const char *) yyFileName, yyLineNo, + (const char *) context ); + lacks_Q_OBJECT.remove( context ); + } else { + needs_Q_OBJECT.insert( context, 0 ); + } + } + } + break; + case Tok_translate: + utf8 = FALSE; + yyTok = getToken(); + if ( match(Tok_LeftParen) && + matchString(&context) && + match(Tok_Comma) && + matchString(&text) ) { + com = ""; + if ( match(Tok_RightParen) || + (match(Tok_Comma) && + matchString(&com) && + (match(Tok_RightParen) || + match(Tok_Comma) && + matchEncoding(&utf8) && + match(Tok_RightParen))) ) + tor->insert( MetaTranslatorMessage(context, text, com, + QString::null, utf8) ); + } + break; + case Tok_Q_OBJECT: + missing_Q_OBJECT = FALSE; + yyTok = getToken(); + break; + case Tok_Ident: + if ( !prefix.isNull() ) + prefix += "::"; + prefix += yyIdent; + yyTok = getToken(); + if ( yyTok != Tok_Gulbrandsen ) + prefix = (const char *) 0; + break; + case Tok_Comment: + com = yyComment; + com = com.simplifyWhiteSpace(); + if ( com.left(sizeof(MagicComment) - 1) == MagicComment ) { + com.remove( 0, sizeof(MagicComment) - 1 ); + int k = com.find( ' ' ); + if ( k == -1 ) { + context = com; + } else { + context = com.left( k ); + com.remove( 0, k + 1 ); + tor->insert( MetaTranslatorMessage(context, "", com, + QString::null, FALSE) ); + } + + /* + Provide a backdoor for people using "using + namespace". See the manual for details. + */ + k = 0; + while ( (k = context.find("::", k)) != -1 ) { + qualifiedContexts.insert( context.mid(k + 2), context ); + k++; + } + } + yyTok = getToken(); + break; + case Tok_Arrow: + yyTok = getToken(); + if ( yyTok == Tok_tr || yyTok == Tok_trUtf8 ) + qWarning( "%s:%d: Cannot invoke tr() like this", + (const char *) yyFileName, yyLineNo ); + break; + case Tok_Gulbrandsen: + // at top level? + if ( yyBraceDepth == (int) namespaces.count() && yyParenDepth == 0 ) + functionContext = prefix; + yyTok = getToken(); + break; + case Tok_RightBrace: + case Tok_Semicolon: + if ( yyBraceDepth >= 0 && + yyBraceDepth + 1 == (int) namespaces.count() ) + namespaces.remove( namespaces.fromLast() ); + if ( yyBraceDepth == (int) namespaces.count() ) { + if ( missing_Q_OBJECT ) { + if ( needs_Q_OBJECT.contains(functionContext) ) { + qWarning( "%s:%d: Class '%s' lacks Q_OBJECT macro", + (const char *) yyFileName, yyLineNo, + (const char *) functionContext ); + } else { + lacks_Q_OBJECT.insert( functionContext, 0 ); + } + } + functionContext = defaultContext; + missing_Q_OBJECT = FALSE; + } + yyTok = getToken(); + break; + default: + yyTok = getToken(); + } + } + + if ( yyBraceDepth != 0 ) + fprintf( stderr, + "%s:%d: Unbalanced braces in C++ code (or abuse of the C++" + " preprocessor)\n", + (const char *)yyFileName, yyBraceLineNo ); + else if ( yyParenDepth != 0 ) + fprintf( stderr, + "%s:%d: Unbalanced parentheses in C++ code (or abuse of the C++" + " preprocessor)\n", + (const char *)yyFileName, yyParenLineNo ); +} + +void fetchtr_cpp( const char *fileName, MetaTranslator *tor, + const char *defaultContext, bool mustExist ) +{ + yyInFile = fopen( fileName, "r" ); + if ( yyInFile == 0 ) { + if ( mustExist ) + fprintf( stderr, + "lupdate error: Cannot open C++ source file '%s': %s\n", + fileName, strerror(errno) ); + return; + } + + startTokenizer( fileName, getCharFromFile ); + parse( tor, 0, defaultContext ); + fclose( yyInFile ); +} + +/* + In addition to C++, we support Qt Designer UI files. +*/ + +/* + Fetches tr() calls in C++ code in UI files (inside "" + tag). This mechanism is obsolete. +*/ +void fetchtr_inlined_cpp( const char *fileName, const QString& in, + MetaTranslator *tor, const char *context ) +{ + yyInStr = in; + startTokenizer( fileName, getCharFromString ); + parse( tor, context, 0 ); + yyInStr = QString::null; +} + +class UiHandler : public QXmlDefaultHandler +{ +public: + UiHandler( MetaTranslator *translator, const char *fileName ) + : tor( translator ), fname( fileName ), comment( "" ) { } + + virtual bool startElement( const QString& namespaceURI, + const QString& localName, const QString& qName, + const QXmlAttributes& atts ); + virtual bool endElement( const QString& namespaceURI, + const QString& localName, const QString& qName ); + virtual bool characters( const QString& ch ); + virtual bool fatalError( const QXmlParseException& exception ); + +private: + void flush(); + + MetaTranslator *tor; + QCString fname; + QString context; + QString source; + QString comment; + + QString accum; +}; + +bool UiHandler::startElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName, + const QXmlAttributes& atts ) +{ + if ( qName == QString("item") ) { + flush(); + if ( !atts.value(QString("text")).isEmpty() ) + source = atts.value( QString("text") ); + } else if ( qName == QString("string") ) { + flush(); + } + accum.truncate( 0 ); + return TRUE; +} + +bool UiHandler::endElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName ) +{ + accum.replace( QRegExp(QString("\r\n")), "\n" ); + + if ( qName == QString("class") ) { + if ( context.isEmpty() ) + context = accum; + } else if ( qName == QString("string") ) { + source = accum; + } else if ( qName == QString("comment") ) { + comment = accum; + flush(); + } else if ( qName == QString("function") ) { + fetchtr_inlined_cpp( (const char *) fname, accum, tor, + context.latin1() ); + } else { + flush(); + } + return TRUE; +} + +bool UiHandler::characters( const QString& ch ) +{ + accum += ch; + return TRUE; +} + +bool UiHandler::fatalError( const QXmlParseException& exception ) +{ + QString msg; + msg.sprintf( "Parse error at line %d, column %d (%s).", + exception.lineNumber(), exception.columnNumber(), + exception.message().latin1() ); + fprintf( stderr, "XML error: %s\n", msg.latin1() ); + return FALSE; +} + +void UiHandler::flush() +{ + if ( !context.isEmpty() && !source.isEmpty() ) + tor->insert( MetaTranslatorMessage(context.utf8(), source.utf8(), + comment.utf8(), QString::null, + TRUE) ); + source.truncate( 0 ); + comment.truncate( 0 ); +} + +void fetchtr_ui( const char *fileName, MetaTranslator *tor, + const char * /* defaultContext */, bool mustExist ) +{ + QFile f( fileName ); + if ( !f.open(IO_ReadOnly) ) { + if ( mustExist ) + fprintf( stderr, "lupdate error: cannot open UI file '%s': %s\n", + fileName, strerror(errno) ); + return; + } + + QTextStream t( &f ); + QXmlInputSource in( t ); + QXmlSimpleReader reader; + reader.setFeature( "http://xml.org/sax/features/namespaces", FALSE ); + reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", TRUE ); + reader.setFeature( "http://trolltech.com/xml/features/report-whitespace" + "-only-CharData", FALSE ); + QXmlDefaultHandler *hand = new UiHandler( tor, fileName ); + reader.setContentHandler( hand ); + reader.setErrorHandler( hand ); + + if ( !reader.parse(in) ) + fprintf( stderr, "%s: Parse error in UI file\n", fileName ); + reader.setContentHandler( 0 ); + reader.setErrorHandler( 0 ); + delete hand; + f.close(); +} diff --git a/tools/linguist/lupdate/lupdate.pro b/tools/linguist/lupdate/lupdate.pro new file mode 100644 index 0000000..1dad999 --- /dev/null +++ b/tools/linguist/lupdate/lupdate.pro @@ -0,0 +1,21 @@ +TEMPLATE = app +CONFIG += qt warn_on console +HEADERS = ../shared/metatranslator.h \ + ../shared/proparser.h +SOURCES = fetchtr.cpp \ + main.cpp \ + merge.cpp \ + numberh.cpp \ + sametexth.cpp \ + ../shared/metatranslator.cpp \ + ../shared/proparser.cpp + +DEFINES += QT_INTERNAL_XML +include( ../../../src/qt_professional.pri ) + +TARGET = lupdate +INCLUDEPATH += ../shared +DESTDIR = ../../../bin + +target.path=$$bins.path +INSTALLS += target diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp new file mode 100644 index 0000000..73c23aa --- /dev/null +++ b/tools/linguist/lupdate/main.cpp @@ -0,0 +1,241 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +// defined in fetchtr.cpp +extern void fetchtr_cpp( const char *fileName, MetaTranslator *tor, + const char *defaultContext, bool mustExist ); +extern void fetchtr_ui( const char *fileName, MetaTranslator *tor, + const char *defaultContext, bool mustExist ); + +// defined in merge.cpp +extern void merge( MetaTranslator *tor, const MetaTranslator *virginTor, + bool verbose ); + +typedef QValueList TML; + +static void printUsage() +{ + fprintf( stderr, "Usage:\n" + " lupdate [options] project-file\n" + " lupdate [options] source-files -ts ts-files\n" + "Options:\n" + " -help Display this information and exit\n" + " -noobsolete\n" + " Drop all obsolete strings\n" + " -verbose\n" + " Explain what is being done\n" + " -version\n" + " Display the version of lupdate and exit\n" ); +} + +static void updateTsFiles( const MetaTranslator& fetchedTor, + const QStringList& tsFileNames, const QString& codec, + bool noObsolete, bool verbose ) +{ + QStringList::ConstIterator t = tsFileNames.begin(); + while ( t != tsFileNames.end() ) { + MetaTranslator tor; + tor.load( *t ); + if ( !codec.isEmpty() ) + tor.setCodec( codec ); + if ( verbose ) + fprintf( stderr, "Updating '%s'...\n", (*t).latin1() ); + merge( &tor, &fetchedTor, verbose ); + if ( noObsolete ) + tor.stripObsoleteMessages(); + tor.stripEmptyContexts(); + if ( !tor.save(*t) ) + fprintf( stderr, "lupdate error: Cannot save '%s': %s\n", + (*t).latin1(), strerror(errno) ); + ++t; + } +} + +int main( int argc, char **argv ) +{ + QString defaultContext = "@default"; + MetaTranslator fetchedTor; + QCString codec; + QStringList tsFileNames; + + bool verbose = FALSE; + bool noObsolete = FALSE; + bool metSomething = FALSE; + int numFiles = 0; + bool standardSyntax = TRUE; + bool metTsFlag = FALSE; + + int i; + + for ( i = 1; i < argc; i++ ) { + if ( qstrcmp(argv[i], "-ts") == 0 ) + standardSyntax = FALSE; + } + + for ( i = 1; i < argc; i++ ) { + if ( qstrcmp(argv[i], "-help") == 0 ) { + printUsage(); + return 0; + } else if ( qstrcmp(argv[i], "-noobsolete") == 0 ) { + noObsolete = TRUE; + continue; + } else if ( qstrcmp(argv[i], "-verbose") == 0 ) { + verbose = TRUE; + continue; + } else if ( qstrcmp(argv[i], "-version") == 0 ) { + fprintf( stderr, "lupdate version %s\n", QT_VERSION_STR ); + return 0; + } else if ( qstrcmp(argv[i], "-ts") == 0 ) { + metTsFlag = TRUE; + continue; + } + + numFiles++; + + QString fullText; + + if ( !metTsFlag ) { + QFile f( argv[i] ); + if ( !f.open(IO_ReadOnly) ) { + fprintf( stderr, "lupdate error: Cannot open file '%s': %s\n", + argv[i], strerror(errno) ); + return 1; + } + + QTextStream t( &f ); + fullText = t.read(); + f.close(); + } + + QString oldDir = QDir::currentDirPath(); + QDir::setCurrent( QFileInfo(argv[i]).dirPath() ); + + if ( standardSyntax ) { + fetchedTor = MetaTranslator(); + codec.truncate( 0 ); + tsFileNames.clear(); + + QMap tagMap = proFileTagMap( fullText ); + QMap::Iterator it; + + for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { + QStringList toks = QStringList::split( ' ', it.data() ); + QStringList::Iterator t; + + for ( t = toks.begin(); t != toks.end(); ++t ) { + if ( it.key() == "HEADERS" || it.key() == "SOURCES" ) { + fetchtr_cpp( *t, &fetchedTor, defaultContext, TRUE ); + metSomething = TRUE; + } else if ( it.key() == "INTERFACES" || + it.key() == "FORMS" ) { + fetchtr_ui( *t, &fetchedTor, defaultContext, TRUE ); + fetchtr_cpp( *t + ".h", &fetchedTor, defaultContext, + FALSE ); + metSomething = TRUE; + } else if ( it.key() == "TRANSLATIONS" ) { + tsFileNames.append( *t ); + metSomething = TRUE; + } else if ( it.key() == "CODEC" || + it.key() == "DEFAULTCODEC" ) { + codec = (*t).latin1(); + } + } + } + + updateTsFiles( fetchedTor, tsFileNames, codec, noObsolete, + verbose ); + + if ( !metSomething ) { + fprintf( stderr, + "lupdate warning: File '%s' does not look like a" + " project file\n", + argv[i] ); + } else if ( tsFileNames.isEmpty() ) { + fprintf( stderr, + "lupdate warning: Met no 'TRANSLATIONS' entry in" + " project file '%s'\n", + argv[i] ); + } + } else { + if ( metTsFlag ) { + if ( QString(argv[i]).lower().endsWith(".ts") ) { + QFileInfo fi( argv[i] ); + if ( !fi.exists() || fi.isWritable() ) { + tsFileNames.append( argv[i] ); + } else { + fprintf( stderr, + "lupdate warning: For some reason, I cannot" + " save '%s'\n", + argv[i] ); + } + } else { + fprintf( stderr, + "lupdate error: File '%s' lacks .ts extension\n", + argv[i] ); + } + } else { + QFileInfo fi(argv[i]); + if ( QString(argv[i]).lower().endsWith(".ui") ) { + fetchtr_ui( fi.fileName(), &fetchedTor, defaultContext, TRUE ); + fetchtr_cpp( QString(fi.fileName()) + ".h", &fetchedTor, + defaultContext, FALSE ); + } else { + fetchtr_cpp( fi.fileName(), &fetchedTor, defaultContext, TRUE ); + } + } + } + QDir::setCurrent( oldDir ); + } + + if ( !standardSyntax ) + updateTsFiles( fetchedTor, tsFileNames, codec, noObsolete, verbose ); + + if ( numFiles == 0 ) { + printUsage(); + return 1; + } + return 0; +} diff --git a/tools/linguist/lupdate/merge.cpp b/tools/linguist/lupdate/merge.cpp new file mode 100644 index 0000000..831a2fe --- /dev/null +++ b/tools/linguist/lupdate/merge.cpp @@ -0,0 +1,129 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +// defined in numberh.cpp +extern void applyNumberHeuristic( MetaTranslator *tor, bool verbose ); +// defined in sametexth.cpp +extern void applySameTextHeuristic( MetaTranslator *tor, bool verbose ); + +typedef QValueList TML; + +/* + Merges two MetaTranslator objects into the first one. The first one + is a set of source texts and translations for a previous version of + the internationalized program; the second one is a set of fresh + source texts newly extracted from the source code, without any + translation yet. +*/ + +void merge( MetaTranslator *tor, const MetaTranslator *virginTor, bool verbose ) +{ + int known = 0; + int neww = 0; + int obsoleted = 0; + TML all = tor->messages(); + TML::Iterator it; + + /* + The types of all the messages from the vernacular translator + are updated according to the virgin translator. + */ + for ( it = all.begin(); it != all.end(); ++it ) { + MetaTranslatorMessage::Type newType; + MetaTranslatorMessage m = *it; + + // skip context comment + if ( !QCString((*it).sourceText()).isEmpty() ) { + if ( !virginTor->contains((*it).context(), (*it).sourceText(), + (*it).comment()) ) { + newType = MetaTranslatorMessage::Obsolete; + if ( m.type() != MetaTranslatorMessage::Obsolete ) + obsoleted++; + } else { + switch ( m.type() ) { + case MetaTranslatorMessage::Finished: + newType = MetaTranslatorMessage::Finished; + known++; + break; + case MetaTranslatorMessage::Unfinished: + default: + newType = MetaTranslatorMessage::Unfinished; + known++; + break; + case MetaTranslatorMessage::Obsolete: + newType = MetaTranslatorMessage::Unfinished; + neww++; + } + } + + if ( newType != m.type() ) { + m.setType( newType ); + tor->insert( m ); + } + } + } + + /* + Messages found only in the virgin translator are added to the + vernacular translator. Among these are all the context comments. + */ + all = virginTor->messages(); + + for ( it = all.begin(); it != all.end(); ++it ) { + if ( !tor->contains((*it).context(), (*it).sourceText(), + (*it).comment()) ) { + tor->insert( *it ); + if ( !QCString((*it).sourceText()).isEmpty() ) + neww++; + } + } + + /* + The same-text heuristic handles cases where a message has an + obsolete counterpart with a different context or comment. + */ + applySameTextHeuristic( tor, verbose ); + + /* + The number heuristic handles cases where a message has an + obsolete counterpart with mostly numbers differing in the + source text. + */ + applyNumberHeuristic( tor, verbose ); + + if ( verbose ) + fprintf( stderr, " %d known, %d new and %d obsoleted messages\n", known, + neww, obsoleted ); +} diff --git a/tools/linguist/lupdate/numberh.cpp b/tools/linguist/lupdate/numberh.cpp new file mode 100644 index 0000000..b10477a --- /dev/null +++ b/tools/linguist/lupdate/numberh.cpp @@ -0,0 +1,248 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +typedef QMap TMM; +typedef QValueList TML; + +static bool isDigitFriendly( int c ) +{ + return ispunct((uchar)c) || isspace((uchar)c); +} + +static int numberLength( const char *s ) +{ + int i = 0; + + if ( isdigit((uchar)s[0]) ) { + do { + i++; + } while (isdigit((uchar)s[i]) || + (isDigitFriendly(s[i]) && + (isdigit((uchar)s[i + 1]) || + (isDigitFriendly(s[i + 1]) && isdigit((uchar)s[i + 2]))))); + } + return i; +} + +/* + Returns a version of 'key' where all numbers have been replaced by zeroes. If + there were none, returns "". +*/ +static QCString zeroKey( const char *key ) +{ + QCString zeroed( (int)strlen(key) + 1 ); + char *z = zeroed.data(); + int i = 0, j = 0; + int len; + bool metSomething = FALSE; + + while ( key[i] != '\0' ) { + len = numberLength( key + i ); + if ( len > 0 ) { + i += len; + z[j++] = '0'; + metSomething = TRUE; + } else { + z[j++] = key[i++]; + } + } + z[j] = '\0'; + + if ( metSomething ) + return zeroed; + else + return ""; +} + +static QString translationAttempt( const QString& oldTranslation, + const char *oldSource, + const char *newSource ) +{ + int p = zeroKey( oldSource ).contains( '0' ); + int oldSourceLen = qstrlen( oldSource ); + QString attempt; + QStringList oldNumbers; + QStringList newNumbers; + QMemArray met( p ); + QMemArray matchedYet( p ); + int i, j; + int k = 0, ell, best; + int m, n; + int pass; + + /* + This algorithm is hard to follow, so we'll consider an example + all along: oldTranslation is "XeT 3.0", oldSource is "TeX 3.0" + and newSource is "XeT 3.1". + + First, we set up two tables: oldNumbers and newNumbers. In our + example, oldNumber[0] is "3.0" and newNumber[0] is "3.1". + */ + for ( i = 0, j = 0; i < oldSourceLen; i++, j++ ) { + m = numberLength( oldSource + i ); + n = numberLength( newSource + j ); + if ( m > 0 ) { + oldNumbers.append( QCString(oldSource + i, m + 1) ); + newNumbers.append( QCString(newSource + j, n + 1) ); + i += m; + j += n; + met[k] = FALSE; + matchedYet[k] = 0; + k++; + } + } + + /* + We now go over the old translation, "XeT 3.0", one letter at a + time, looking for numbers found in oldNumbers. Whenever such a + number is met, it is replaced with its newNumber equivalent. In + our example, the "3.0" of "XeT 3.0" becomes "3.1". + */ + for ( i = 0; i < (int) oldTranslation.length(); i++ ) { + attempt += oldTranslation[i]; + for ( k = 0; k < p; k++ ) { + if ( oldTranslation[i] == oldNumbers[k][matchedYet[k]] ) + matchedYet[k]++; + else + matchedYet[k] = 0; + } + + /* + Let's find out if the last character ended a match. We make + two passes over the data. In the first pass, we try to + match only numbers that weren't matched yet; if that fails, + the second pass does the trick. This is useful in some + suspicious cases, flagged below. + */ + for ( pass = 0; pass < 2; pass++ ) { + best = p; // an impossible value + for ( k = 0; k < p; k++ ) { + if ( (!met[k] || pass > 0) && + matchedYet[k] == (int) oldNumbers[k].length() && + numberLength(oldTranslation.latin1() + (i + 1) - + matchedYet[k]) == matchedYet[k] ) { + // the longer the better + if ( best == p || matchedYet[k] > matchedYet[best] ) + best = k; + } + } + if ( best != p ) { + attempt.truncate( attempt.length() - matchedYet[best] ); + attempt += newNumbers[best]; + met[best] = TRUE; + for ( k = 0; k < p; k++ ) + matchedYet[k] = 0; + break; + } + } + } + + /* + We flag two kinds of suspicious cases. They are identified as + such with comments such as "{2000?}" at the end. + + Example of the first kind: old source text "TeX 3.0" translated + as "XeT 2.0" is flagged "TeX 2.0 {3.0?}", no matter what the + new text is. + */ + for ( k = 0; k < p; k++ ) { + if ( !met[k] ) + attempt += QString( " {" ) + newNumbers[k] + QString( "?}" ); + } + + /* + Example of the second kind: "1 of 1" translated as "1 af 1", + with new source text "1 of 2", generates "1 af 2 {1 or 2?}" + because it's not clear which of "1 af 2" and "2 af 1" is right. + */ + for ( k = 0; k < p; k++ ) { + for ( ell = 0; ell < p; ell++ ) { + if ( k != ell && oldNumbers[k] == oldNumbers[ell] && + newNumbers[k] < newNumbers[ell] ) + attempt += QString( " {" ) + newNumbers[k] + QString( " or " ) + + newNumbers[ell] + QString( "?}" ); + } + } + return attempt; +} + +/* + Augments a MetaTranslator with translations easily derived from + similar existing (probably obsolete) translations. + + For example, if "TeX 3.0" is translated as "XeT 3.0" and "TeX 3.1" + has no translation, "XeT 3.1" is added to the translator and is + marked Unfinished. +*/ +void applyNumberHeuristic( MetaTranslator *tor, bool verbose ) +{ + TMM translated, untranslated; + TMM::Iterator t, u; + TML all = tor->messages(); + TML::Iterator it; + int inserted = 0; + + for ( it = all.begin(); it != all.end(); ++it ) { + if ( (*it).type() == MetaTranslatorMessage::Unfinished ) { + if ( (*it).translation().isEmpty() ) + untranslated.insert(QCString((*it).context()) + "\n" + (*it).sourceText() + "\n" + + (*it).comment(), *it); + } else if ( !(*it).translation().isEmpty() ) { + translated.insert( zeroKey((*it).sourceText()), *it ); + } + } + + for ( u = untranslated.begin(); u != untranslated.end(); ++u ) { + t = translated.find( zeroKey((*u).sourceText()) ); + if ( t != translated.end() && !t.key().isEmpty() && + qstrcmp((*t).sourceText(), (*u).sourceText()) != 0 ) { + MetaTranslatorMessage m( *u ); + m.setTranslation(translationAttempt((*t).translation(), (*t).sourceText(), + (*u).sourceText())); + tor->insert( m ); + inserted++; + } + } + if ( verbose && inserted != 0 ) + fprintf( stderr, " number heuristic provided %d translation%s\n", + inserted, inserted == 1 ? "" : "s" ); +} diff --git a/tools/linguist/lupdate/sametexth.cpp b/tools/linguist/lupdate/sametexth.cpp new file mode 100644 index 0000000..8059f1c --- /dev/null +++ b/tools/linguist/lupdate/sametexth.cpp @@ -0,0 +1,97 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +#include +#include + +typedef QMap TMM; +typedef QValueList TML; + +/* + Augments a MetaTranslator with trivially derived translations. + + For example, if "Enabled:" is consistendly translated as "Eingeschaltet:" no + matter the context or the comment, "Eingeschaltet:" is added as the + translation of any untranslated "Enabled:" text and is marked Unfinished. +*/ + +void applySameTextHeuristic( MetaTranslator *tor, bool verbose ) +{ + TMM translated; + TMM avoid; + TMM::Iterator t; + TML untranslated; + TML::Iterator u; + TML all = tor->messages(); + TML::Iterator it; + int inserted = 0; + + for ( it = all.begin(); it != all.end(); ++it ) { + if ( (*it).type() == MetaTranslatorMessage::Unfinished ) { + if ( (*it).translation().isEmpty() ) + untranslated.append( *it ); + } else { + QCString key = (*it).sourceText(); + t = translated.find( key ); + if ( t != translated.end() ) { + /* + The same source text is translated at least two + different ways. Do nothing then. + */ + if ( (*t).translation() != (*it).translation() ) { + translated.remove( key ); + avoid.insert( key, *it ); + } + } else if ( !avoid.contains(key) && + !(*it).translation().isEmpty() ) { + translated.insert( key, *it ); + } + } + } + + for ( u = untranslated.begin(); u != untranslated.end(); ++u ) { + QCString key = (*u).sourceText(); + t = translated.find( key ); + if ( t != translated.end() ) { + MetaTranslatorMessage m( *u ); + m.setTranslation( (*t).translation() ); + tor->insert( m ); + inserted++; + } + } + if ( verbose && inserted != 0 ) + fprintf( stderr, " same-text heuristic provided %d translation%s\n", + inserted, inserted == 1 ? "" : "s" ); +} diff --git a/tools/linguist/phrasebooks/danish.qph b/tools/linguist/phrasebooks/danish.qph new file mode 100644 index 0000000..c4926bd --- /dev/null +++ b/tools/linguist/phrasebooks/danish.qph @@ -0,0 +1,1018 @@ + + + About + Om + + + access key + hurtigtast + + + accessibility + brugervenlighed + + + action handle + genvejshåndtag + + + active + aktiv + + + active end + markeringsafslutning + + + active object + aktivt objekt + + + active window + aktivt vindue + + + adornment + værktøjselement + + + Always on Top + Altid øverst + + + anchor point + forankringspunkt + + + Apply + Anvend + + + auto-exit + tekstboks med automatisk udgang + + + auto-repeat + automatisk gentagelse + + + automatic link + automatisk kæde + + + automatic scrolling + automatisk rulning + + + autoscroll + automatisk rulning + + + Back + Tilbage + + + Browse + Gennemse + + + Cancel + Annuller + + + cascading menu + undermenu + + + check box + afkrydsningsfelt + + + check mark + afkrydsning + + + child window + underordnet vindue + + + choose + vælge + + + click + klikke + + + Clipboard + Udklipsholder + + + Close + Luk + + + Close button + lukknap + + + collapse + skjule + outline/disposition + + + column heading + kolonneoverskrift + control/kontrolelement + + + combo box + kombinationsboks + + + command button + kommandoknap + + + container + objektbeholder + + + context-sensitive Help + kontekstafhængig hjælp + + + contextual + kontekstafhængig + + + control + kontrolelement + + + Copy + Kopier + + + Copy here + Kopier hertil + + + Create Shortcut + Opret genvej + + + Create Shortcut Here + Opret genvej her + + + Cut + Klip + + + default + standard + + + default button + standardknap + + + Delete + Slet + + + desktop + skrivebord + + + destination + destination + + + dialog box + dialogboks + + + disability + handicap + + + disjoint selection + usammenhængende markering + + + dock + forankre + + + document + dokument + + + double-click + dobbeltklikke + + + drag + trække + + + drag-and-drop + trække og slippe + + + drop-down combo box + kombinationsboks med rullepil + + + drop-down list box + rulleliste + + + drop-down menu + rullemenu + + + Edit + Rediger + + + Edit menu + Menuen Rediger + + + ellipsis + ellipse + + + embedded object + integreret objekt + + + Exit + Afslut + + + expand + udvide + an outline/en disposition + + + Explore + Stifinder + + + extended selection + udvidet markering + + + extended selection list box + liste + der tillader udvidet markering + + + file + fil + + + File menu + Menuen Filer + + + Find + Søg + + + Find Next + Find næste + + + Find What + Søg efter + + + folder + mappe + + + font + skrifttype + + + font size + skriftstørrelse + + + font style + typografi + + + function key + funktionstast + + + group box + gruppeboks + + + handle + håndtag + + + Help + Hjælp + + + Help menu + Menuen Hjælp + + + Hide + Skjul + + + hierarchical selection + hierarkisk markering + + + hold + holde nede + + + hot spot + aktivt punkt + + + hot zone + aktiv zone + + + icon + ikon + + + inactive + ikke-aktiv + + + inactive window + ikke-aktivt vindue + + + input focus + inputfokus + + + Insert + Menuen Indsæt + + + Insert Object + Indsæt objekt + + + insertion point + indsætningspunkt + + + italic + kursiv + + + label + etiket + + + landscape + liggende + + + link + sammenkæde + verb + + + link + kæde + noun + + + Link Here + Indsæt kæde her + + + list box + liste + + + list view + listevisningsboks + control/kontrolelement + + + manual link + manuel kæde + + + Maximize + Maksimer + + + maximize button + maksimeringsknap + + + MDI + MDI + + + menu + menu + + + menu bar + menulinje + + + menu button + menuknap + + + menu item + menupunkt + + + menu title + menutitel + + + message box + meddelelsesboks + + + Minimize + Minimer + + + minimize button + minimeringsknap + + + mixed-value + blandet værdi + + + modal + modal + + + mode + tilstand + + + modeless + ikke-modal + + + modifier key + ændringstast + + + mouse + mus + + + Move + Flyt + + + Move Here + Flyt hertil + + + Multiple Document Interface + multiple document interface + MDI + + + multiple selection list box + liste + der tillader flere markeringer + + + My Computer + Denne computer + icon/ikon + + + Network Neighborhood + Andre computere + icon/ikon + + + New + Ny + + + Next + Næste + + + object + objekt + + + OK + OK + + + OLE + OLE + + + OLE drag and drop + OLE-træk og slip + + + OLE embedded object + integreret OLE-objekt + + + OLE linked object + sammenkædet OLE-objekt + + + OLE nondefault drag and drop + interaktiv OLE-træk og slip + + + Open + Åbn + + + Open With + Åbn med + + + option button + alternativknap + + + option-set + aktiveret indstilling + + + package + objektpakke + + + Page Setup + Sideopsætning + + + palette window + paletvindue + + + pane + rude + + + parent window + overordnet vindue + + + password + adgangskode + + + Paste + Sæt ind + + + Paste Link + Indsæt kæde + + + Paste Shortcut + Indsæt genvej + + + Paste Special + Indsæt speciel + + + path + sti + + + Pause + Pause + + + Play + Afspil + + + Plug and Play + Plug and Play + + + point + punkt + noun + + + point + pege + verb + + + pointer + markør + + + pop-up menu + pop-up-menu + + + pop-up window + pop-up-vindue + + + portrait + stående + + + press + trykke på + and hold a mouse button/og holde en museknap nede + + + press + trykke på + a key/en tast + + + primary container + primært destinationsobjekt + + + primary window + primært vindue + + + Print + Udskriv + + + printer + printer + + + progress indicator + statusindikator + control/kontrolelement + + + project + projekt + + + Properties + Egenskaber + + + property inspector + egenskabsfremviser + + + property page + egenskabsside + + + property sheet + egenskabsark + + + property sheet control + kontrolelement på egenskabsark + + + Quick View + Hurtig visning + + + read-only + skrivebeskyttet + + + Recycle Bin + Papirkurv + Icon/ikon + + + Redo + Annuller Fortryd + + + region selection + områdemarkering + + + registry + registreringsdatabase + + + Repeat + Gentag + + + Replace + Erstat + + + Restore + Gendan + + + Restore button + gendannelsesknap + + + Resume + Fortsæt + + + Retry + Forsøg igen + + + rich-text box + tekstboks til formateret tekst + + + Run + Kør + + + Save + Gem + + + Save as + Gem som + + + scroll + rulle + + + scroll arrow + rullepil + + + scroll bar + rullepanel + + + scroll box + rulleboks + + + secondary window + sekundært vindue + + + select + markere + + + select + vælge + + + Select All + Marker alt + + + selection + det markerede + + + selection handle + markeringshåndtag + + + Send To + Overfør til + + + separator + separator + + + Settings + Indstillinger + + + Setup + Indstillinger + + + Setup + Installation + + + shortcut + genvej + + + shortcut button + genvejsknap + + + shortcut icon + genvejsikon + + + shortcut key + genvejstast + + + shortcut key control + kontrolelement til genvejstast + + + Show + Vis + + + Shutdown + Luk computeren + + + single selection list box + liste + der kun tillader en enkelt markering + + + Size + Tilpas størrelse + + + size grip + størrelseshåndtag + + + slider + skala + + + spin box + rotationsboks + + + Split + Opdel + + + split bar + delelinje + + + split box + deleboks + + + Start button + startknap + + + StartUp folder + Startmappe + + + status bar + statuslinje + + + Stop + Stop + + + tab control + fane + + + task bar + proceslinje + + + task-oriented Help + opgaveafhængig Hjælp + + + template + skabelon + + + text box + tekstboks + + + title bar + titellinje + + + title text + titeltekst + + + toggle key + til/fra-tast + + + toolbar + verktøjslinje + + + tooltip + verktøjstip + + + tree view control + træstruktur + + + type + skrive + verb + + + type + type + noun + + + unavailable + ikke tilgængelig + + + Undo + Fortryd + + + Uninstall + Fjern installationen + + + View + Menuen Vis + + + visual editing + lokal redigering + + + well control + grafikpalet + + + What's This? + Hvad er det? + + + Window + Menuen Vindue + + + window + vindue + + + Windows Explorer + Windows Stifinder + + + wizard + guide + + + workbook + projektmappe + + + workgroup + arbejdsgruppe + + + workspace + arbejdsområde + + + Yes + Ja + + diff --git a/tools/linguist/phrasebooks/dutch.qph b/tools/linguist/phrasebooks/dutch.qph new file mode 100644 index 0000000..0e9b5d6 --- /dev/null +++ b/tools/linguist/phrasebooks/dutch.qph @@ -0,0 +1,1044 @@ + + + About + Info + + + access key + toegangstoets + + + accessibility + toegankelijkheid + + + action handle + bewerkingsgreep + + + active + actief + + + active end + selecie-einde + + + active object + actief object + + + active window + actief venster + + + adornment + grafisch hulpmiddel + + + Always on Top + Altijd op voorgrond + + + anchor point + fixeerpunt + + + Apply + Toepassen + + + auto-exit + automatisch verlaten + + + auto-repeat + zich automatisch herhalen + + + auto-repeat + automatisch herhalen + + + automatic link + automatische koppeling + + + automatic scrolling + automatisch schuiven + + + autoscroll + automatisch schuiven + + + Back + Vorige + wanneer het een logisch paar vormt met Volgende + + + Browse + Bladeren + + + Cancel + Annuleren + + + cascading menu + vervolgmenu + + + check box + selectievakje + + + check mark + vinkje + + + child window + subvenster + + + choose + kiezen + + + click + klikken + + + Clipboard + Klembord + + + Close + Sluiten + + + Close button + knop Sluiten + + + collapse + samenvouwen + outline + + + column heading + kolomnaam + control + + + combo box + keuzelijst met invoervak + + + command button + opdrachtknop + + + container + hoofdobject + + + context-sensitive Help + contextafhankelijke Help + + + contextual + contextafhankelijk + + + control + besturingselement + + + Copy + Kopiëren + + + Copy here + Hierheen kopiëren + + + Create Shortcut + Snelkoppeling maken + + + Create Shortcut Here + Hier snelkoppeling maken + + + Cut + Knippen + + + default + standaard + + + default button + standaardknop + + + Delete + Verwijderen + + + desktop + bureaublad + + + destination + doel + + + dialog box + dialoogvenster + + + disability + handicap + voorzichtig in context, maar handicap niet verbloemen:VB: persoon met een handicap (beter dan gehandicapte) + + + disjoint selection + niet-aaneengesloten selectie + + + dock + in werkbalkdok plaatsen + + + document + document + + + double-click + dubbelklikken + + + drag + slepen + + + drag-and-drop + slepen en neerzetten + + + drop-down combo box + vervolgkeuzelijst met invoervak + + + drop-down list box + vervolgkeuzelijst + + + drop-down menu + menu + + + Edit + Bewerken + + + Edit menu + menu Bewerken + + + ellipsis + puntjes + (...) + + + embedded object + ingesloten object + + + Exit + Afsluiten + + + expand + uitvouwen + an outline + + + Explore + Verkennen + + + extended selection + uitgebreide selectie + + + extended selection list box + keuzelijst met uitgebreide selectie + + + file + bestand + + + File menu + menu Bestand + + + Find + Zoeken + + + Find Next + Volgende zoeken + + + Find What + Zoeken naar + + + folder + map + + + font + lettertype + + + font size + tekengrootte + + + font style + tekenstijl + + + function key + functietoets + + + group box + groepsvak + + + handle + greep + + + Help + Help + + + Help menu + menu Help + + + Hide + Verbergen + + + hierarchical selection + hiërarchische selectie + + + hold + ingedrukt houden + + + hot spot + selectiepunt + + + hot zone + selectiegebied + + + icon + pictogram + + + inactive + niet-actief + + + inactive window + niet-actief venster + + + input focus + invoerfocus + + + Insert + menu Invoegen + + + Insert Object + Object Invoegen + + + insertion point + invoegpositie + + + italic + cursief + + + label + label + gender, Masc.: de + + + landscape + liggend + + + link + koppeling + noun + + + link + koppelen + verb + + + Link Here + Hier koppeling maken + + + list box + keuzelijst + + + list view + weergaveknoppen + control + + + manual link + handmatige koppeling + + + Maximize + Maximaliseren + + + maximize button + knop Maximaliseren + + + MDI + MDI + + + menu + menu + + + menu bar + menubalk + + + menu button + menuknop + + + menu item + opdracht + + + menu title + menunaam + + + message box + berichtvak + + + Minimize + Minimaliseren + + + minimize button + knop Minimaliseren + + + mixed-value + met gemengde waarden + + + modal + modusgebonden + + + mode + modi + plural + + + mode + modus + singular + + + modeless + niet-modusgebonden + + + modifier key + modificatietoets + + + mouse + muis + + + Move + Verplaatsen + + + Move Here + Hierheen verplaatsen + + + Multiple Document Interface + interface voor meerdere documenten + + + multiple selection list box + keuzelijst met meervoudige selectie + + + My Computer + Deze computer + icon/pictogram + + + Network Neighborhood + Netwerkomgeving + icon/pictogram + + + New + Nieuw + + + Next + Volgende + + + object + object + + + OK + OK + + + OLE + OLE + OLE (objecten koppelen en insluiten): voluit alleen in doc en Help + + + OLE drag and drop + slepen en neerzetten + + + OLE drag and drop + slepen en neerzetten via OLE + + + OLE embedded object + ingesloten OLE-object + + + OLE linked object + gekoppeld OLE-object + + + OLE nondefault drag and drop + Aangepast slepen en neerzetten + + + OLE nondefault drag and drop + Aangepast slepen en neerzetten via OLE + + + Open + Openen + + + Open With + Openen met + + + option button + keuzerondje + + + option-set + opties + + + package + OLE-pakket + + + Page Setup + Pagina-instelling + + + palette window + paletvenster + + + pane + deelvenster + + + parent window + hoofdvenster + + + password + wachtwoord + + + Paste + Plakken + + + Paste Link + Koppeling plakken + + + Paste Shortcut + Snelkoppeling plakken + + + Paste Special + Plakken speciaal + + + path + pad + + + Pause + Pauze + + + Play + Afspelen + + + Plug and Play + Plug en Play + + + point + aanwijzen + + + pointer + aanwijzer + + + pop-up menu + pop-up-menu + + + pop-up window + pop-up-venster + + + portrait + staand + + + press + drukken op + a key/een toets + + + press + ingedrukt houden + and hold a mouse button/een muisknop + + + press + een muisknop ingedrukt houden + and hold a mouse button + + + press a mouse botton + een muisknop indrukken + + + primary container + primair hoofdobject + + + primary window + primair venster + + + Print + Afdrukken + + + printer + printer + + + progress indicator + voortgangsindicator + control + + + project + project + + + Properties + Eigenschappen + + + property inspector + eigenschappenweergave + + + property page + eigenschappenpagina + + + property sheet + eigenschappenblad + + + property sheet control + besturingselement op een eigenschappenblad + + + Quick View + Snel weergeven + + + read-only + alleen-lezen + + + Recycle Bin + Prullenbak + Icon/pictogram + + + Redo + Opnieuw + + + region selection + gebiedsselectie + + + registry + het Register + + + Repeat + Herhalen + + + Replace + Vervangen + + + Restore + Vorig formaat + + + Restore button + knop Vorig formaat + + + Resume + Doorgaan + + + Retry + Nogmaals + + + rich-text box + RTF-vak + + + Run + Uitvoeren + Maar: macro starten + + + Save + Opslaan + + + Save as + Opslaan als + + + scroll + schuiven door + + + scroll arrow + schuifpijl + + + scroll bar + schuifbalk + + + scroll box + schuifblok + + + secondary window + secundair venster + + + select + selecteren + + + Select All + Alles selecteren + + + selection + selectie + + + selection handle + selectiegreep + + + Send To + Kopiëren naar + + + separator + scheidingsteken + + + Settings + Instellingen + + + Setup + Instellen + + + Setup + Setup + als het programma Setup wordt bedoeld + + + shortcut + snelkoppeling + + + shortcut button + snelkoppelingsknop + + + shortcut icon + snelkoppelingspictogram + + + shortcut key + sneltoets + + + shortcut key control + sneltoetsvak + + + Show + Weergeven + + + Shutdown + Afsluiten + + + single selection list box + keuzelijst met enkelvoudige selectie + + + Size + Formaat wijzigen + + + size grip + formaatgreep + + + slider + schuifregelaar + + + spin box + kringveld + + + Split + Splitsen + + + split bar + splitsbalk + + + split box + splitsblokje + + + Start button + knop Start + + + StartUp folder + map Opstarten + + + status bar + statusbalk + + + Stop + Stoppen + + + tab control + tab + + + task bar + taakbalk + + + task-oriented Help + taakgeoriënteerde Help + + + template + sjabloon + de + + + text box + tekstvak + + + title bar + titelbalk + + + title text + venstertitel + + + toggle key + wisseltoets + + + toolbar + werkbalk + + + tooltip + knopinfo + + + tree view control + besturingselement voor structuurweergave + + + tree view control + structuurweergave + + + type + typen + verb + + + type + type + noun + + + unavailable + niet beschikbaar + + + Undo + Ongedaan maken + + + Uninstall + Installatie ongedaan maken + + + View + menu Beeld + + + visual editing + direct bewerken + + + well control + keuzelijst met grafische opties + + + What's This? + Wat is dit? + + + Window + menu Venster + + + window + venster + + + Windows Explorer + Windows Verkenner + + + wizard + wizard + geen hoofdletter meer in lopende tekst + + + workbook + werkmap + + + workgroup + werkgroep + + + workspace + werkruimte + + + Yes + Ja + + diff --git a/tools/linguist/phrasebooks/finnish.qph b/tools/linguist/phrasebooks/finnish.qph new file mode 100644 index 0000000..0612c82 --- /dev/null +++ b/tools/linguist/phrasebooks/finnish.qph @@ -0,0 +1,1033 @@ + + + About + Tietoja + + + access key + valintanäppäin + + + accessibility + helppokäyttötoiminto + + + action handle + toimintokahva + + + active + aktiivinen + + + active end + valinnan aktiivinen päätöskohta + + + active object + aktiivinen objekti + + + active window + aktiivinen ikkuna + + + adornment + graafinen lisäke + + + Always on Top + Aina päällimmäisenä + + + anchor point + ankkurikohta + + + Apply + Käytä + + + auto-exit + automaattinen siirtyminen + + + auto-repeat + automaattinen toisto + + + automatic link + automaattinen linkki + + + automatic scrolling + automaattinen vieritys + + + autoscroll + automaattinen vieritys + + + Back + Takaisin + + + Browse + Selaa + + + Cancel + Peruuta + + + cascading menu + alivalikko + + + check box + valintaruutu + + + check mark + valintamerkki + + + child window + ali-ikkuna + + + choose + valita + + + click + napsautta + + + Clipboard + Leikepöytä + + + Close + Sulje + + + Close button + sulkemispainike + + + collapse + tiivistää + outline/jäsennys + + + collapse + kutistaa + outline/jäsennys + + + column heading + saraketunnus + control/ohjausobjekti + + + column heading + sarakeotsikko + control/ohjausobjekti + + + combo box + yhdistelmäruutu + + + command button + painike + + + command button + komento painike + + + container + säilö + + + context-sensitive Help + tilannekohtainen ohje + + + contextual + tilannekohtainen + + + control + ohjausobjekti + + + Copy + Kopioi + + + Copy here + Kopioi tähän + + + Create Shortcut + Luo pikakuvake + + + Create Shortcut Here + Luo pikakuvake tähän + + + Cut + Leikkaa + + + default + oletus + + + default button + oletuspainike + + + Delete + Poista + + + desktop + työpöytä + + + destination + kohde + + + dialog box + valintaikkuna + + + disability + invaliditeetti + + + disjoint selection + hajavalinta + + + dock + telakoida + + + document + tiedosto + + + document + asiakirja + + + double-click + kaksoisnapsauttaa + + + drag + vetää + + + drag-and-drop + vetää ja pudottaa + + + drop-down combo box + avattava yhdistelmäruutu + + + drop-down list box + avattava luetteloruutu + + + drop-down menu + avattava valikko + + + Edit + Muokkaa + + + Edit menu + Muokkaa-valikko + + + ellipsis + kolme pistettä + + + embedded object + upotettu objekti + + + Exit + Lopeta + + + expand + laajentaa + an outline/jäsennys + + + Explore + Selaa + + + extended selection + laajennettu valinta + + + extended selection list box + laajennettu valinta-luetteloruutu + + + file + tiedosto + + + File menu + Tiedosto-valikko + + + Find + Etsi + + + Find Next + Etsi seuraava + + + Find What + Etsittävä + + + folder + kansio + + + font + fontti + + + font size + fonttikoko + + + font style + fonttityyli + + + function key + funktionäppäin + + + group box + ryhmän kehys + + + handle + kahva + + + Help + Ohje + + + Help menu + Ohje-valikko + + + Hide + Piilota + + + hierarchical selection + hierarkkinen valinta + + + hold + pitää painettuna + + + hot spot + kohdepiste + + + hot zone + kohdealue + + + icon + kuvake + + + inactive + passiivinen + + + inactive window + passiivinen ikkuna + + + input focus + syöttöalue + + + Insert + Lisää-valikko + + + Insert Object + Lisää objekti + + + insertion point + lisäyskohta + + + italic + kursivoitu + + + label + otsikko + + + label + nimi + + + landscape + vaaka + + + link + linkki + noun + + + link + linkittää + verb + + + Link Here + Linkitä tähän + + + list box + luetteloruutu + + + list view + luettelonäyttö + control/ohjausobjekti + + + manual link + manuaalinen linkki + + + Maximize + Suurenna + + + maximize button + suurennuspainike + + + MDI + MDI + + + menu + valikko + + + menu bar + valikkorivi + + + menu button + valikkopainike + + + menu item + valikon vaihtoehto + + + menu title + valikon otsikko + + + message box + sanomaruutu + + + Minimize + Pienennä + + + minimize button + pienennyspainike + + + mixed-value + monitila + + + modal + modaalinen + + + mode + tila + + + modeless + ei-modaalinen + + + modifier key + yhdistelmänäppäin + + + mouse + hiiri + + + Move + Siirrä + + + Move Here + Siirrä tähän + + + Multiple Document Interface + MDI-liittymä + + + multiple selection list box + monivalintainen luetteloruutu + + + My Computer + Oma tietokone + icon/kuvake + + + Network Neighborhood + Verkkoympäristö + icon/kuvake + + + New + Uusi + + + Next + Seuraava + + + object + objekti + + + OK + OK + + + OLE + OLE + + + OLE drag and drop + vedä ja pudota-OLE-toiminto + + + OLE embedded object + upotettu OLE-objekti + + + OLE linked object + linkitetty OLE-objekti + + + OLE nondefault drag and drop + käyttäjän määrittämä vedä ja pudota-OLE-toiminto + + + Open + Avaa + + + Open With + Avaa sovelluksessa + + + option button + valintanappi + + + option-set + valitsimen tila + + + package + pakkaus + + + Page Setup + Sivun asetukset + + + palette window + valikoimaikkuna + + + pane + ruutu + + + parent window + ylemmän tason ikkuna + + + password + salasana + + + Paste + Liitä + + + Paste Link + Liitä linkki + + + Paste Shortcut + Liitä pikakuvake + + + Paste Special + Liitä määräten + + + path + polku + + + Pause + Tauko + + + Play + Soita + + + Plug and Play + Plug and Play + + + point + piste + + + point + osoittaa + + + pointer + osoitin + + + pop-up menu + pikavalikko + + + pop-up window + ponnahdusikkuna + + + portrait + pysty + + + press + painaa + and hold a mouse button/ja pitää painettuna hiiripainiketta + + + press + painaa + a key/näppäintä + + + primary container + ensisijainen säilö + + + primary window + ensisijainen ikkuna + + + Print + Tulosta + + + printer + kirjoitin + + + progress indicator + tilanneilmaisin + control/ohjausobjekti + + + project + projekti + + + Properties + Ominaisuudet + + + property inspector + ominaisuuksien tarkastelu + + + property page + ominaisuusryhmä + + + property sheet + ominaisuusikkuna + + + property sheet control + ominaisuusikkuna-ohjausobjekti + + + Quick View + Pikanäyttö + + + read-only + vain luku + + + Recycle Bin + Roskakori + Icon/kuvake + + + Redo + Tee uudelleen + + + region selection + aluevalinta + + + registry + rekisteri + + + Repeat + Toista + + + Replace + Korvaa + + + Restore + Palauta + + + Restore button + palautuspainike + + + Resume + Jatka + + + Retry + Yritä uudelleen + + + rich-text box + monimuotoruutu + + + Run + Suorita + + + Save + Tallenna + + + Save as + Tallenna nimellä + + + scroll + vierittää + + + scroll arrow + vieritysnuoli + + + scroll bar + vierityspalkki + + + scroll box + vieritysruutu + + + secondary window + toissijainen ikkuna + + + select + valita + + + Select All + Valitse kaikki + + + selection + valinta + + + selection handle + valintakahva + + + Send To + Lähetä tiedosto + + + separator + erotin + + + Settings + Asetukset + + + Setup + Asennus + + + shortcut + pika- + + + shortcut button + pikapainike + + + shortcut icon + pikakuvake + + + shortcut key + pikanäppäin + + + shortcut key control + pikanäppäin-ohjausobjekti + + + Show + Näytä + + + Shutdown + Sammuta + + + single selection list box + yksivalintainen luetteloruutu + + + Size + Muuta kokoa + + + size grip + koonmuuttokahva + + + slider + liukusäädin + + + spin box + askellusruutu + + + Split + Jaa + + + split bar + jakopalkki + + + split box + jakoruutu + + + Start button + Käynnistä-painike + + + StartUp folder + Käynnistys-kansio + + + status bar + tilarivi + + + Stop + Pysäytä + + + tab control + välilehti + ohjausobjekti + + + task bar + tehtäväpalkki + + + task-oriented Help + tehtäväohje + + + template + malli + + + text box + muokkausruutu + + + title bar + otsikkorivi + + + title text + otsikkoteksti + + + toggle key + tilanvaihtonäppäin + + + toolbar + työkalurivi + + + tooltip + työkaluvihje + + + tree view control + puunäyttö + ohjausobjekti + + + type + tyyppi + noun + + + type + laji + noun + + + type + kirjoittaa + verb + + + unavailable + ei käytettävissä + + + Undo + Kumoa + + + Uninstall + Pura asennus + + + View + Näytä-valikko + + + visual editing + visuaalinen muokkaus + + + well control + graafisen valinnan ohjausobjekti + + + What's This? + Lisätietoja + + + Window + Ikkuna-valikko + + + window + ikkuna + + + Windows Explorer + Resurssienhallinta + + + wizard + ohjattu toiminto + + + workbook + työkirja + + + workgroup + työryhmä + + + workspace + työtila + + + Yes + Kyllä + + diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph new file mode 100644 index 0000000..569f7ba --- /dev/null +++ b/tools/linguist/phrasebooks/french.qph @@ -0,0 +1,1104 @@ + + + About + A propos + + + access key + touche d'accès rapide + + + accessibility + accessibilité + + + action handle + handle d'action + + + active + actif + + + active + active + + + active end + point de fin de sélecion + + + active object + objet actif + + + active window + fenêtre activ + + + adornment + barre + + + Always on Top + Toujours visible + + + anchor point + point de début de sélection + + + Apply + Appliquer + + + auto-exit + sortie automatique + + + auto-repeat + répétition automatique + + + automatic link + Liaison automatique + + + automatic scrolling + défilement automatique + + + autoscroll + défilement automatique + + + Back + Précédent + + + barrel button + Bouton du stylet + + + barrel-tap + toucher-maintenir enfoncé + + + boxed edit + édition contrôlée + control + + + Browse + Parcourir + + + Cancel + Annuler + + + cascading menu + menu en cascade + + + check box + case à cocher + + + check mark + coche + + + child window + fenêtre enfant + + + choose + choisir + + + click + cliquer sur + verb, à l'écran + + + click + clic + noun + + + click + cliquer le + verb, bouton souris + + + Clipboard + Presse-papiers + + + Close + Fermer + + + Close + Fermeture + + + Close button + Fermer + + + collapse + réduire + outline + + + column heading + en-tête de colonne + control + + + combo box + zone de liste modifiable + + + command button + bouton de commande + + + container + conteneur + d'objets + + + context-sensitive Help + aide contextuelle + + + contextual + contextuelle + + + contextual + contextuel + + + control + contrôle + + + Copy + Copier + + + Copy here + Copier ici + + + Create Shortcut + Copier un raccourci + + + Create Shortcut Here + Copier un raccourci ice + + + Cut + Couper + + + default + par défaut + + + default button + bouton par défaut + + + Delete + Supprimer + + + desktop + bureau + + + destination + destination + + + dialog box + boîte de dialogue + + + disability + incapacité + + + disjoint selection + sélection d'objets disjoints + + + dock + aligner + + + document + document + + + double-click + cliquer deux fois + + + double-tap + toucher deux fois + + + drag + faire glisser + + + drag-and-drop + glisser-déplacer + + + drop-down combo box + zone de liste déroulante modifiable + + + drop-down list box + zone de liste déroulante fixe + + + drop-down menu + menu déroulant + + + Edit + Edition + + + Edit menu + modifier + + + ellipsis + points de suspension + + + embedded object + objet incorporé + + + Exit + Quitter + + + expand + développer + an outline + + + Explore + Explorer + + + extended selection + sélection étendue + + + extended selection list box + zone de liste à sélection étendue + + + File + Fichier + menu + + + file + fichier + + + Find + Rechercher + + + Find Next + Suivant + + + Find What + Rechercher + + + folder + dossier + + + font + police + + + font size + taille de police + + + font style + style de police + + + function key + touche de fonction + + + gesture + signe + + + glyph + glyphe + + + group box + zone de groupe + + + handle + handle + + + Help + ? + menu + + + Help + Aide + + + Hide + Masquer + + + hierarchical selection + sélection hiérarchique + + + hold + maintenir + + + hot spot + point d'impact + + + hot zone + zone critique + + + icon + icône + + + inactive + inactive + + + inactive + inactif + + + inactive window + fenêtre inactive + + + ink + dessin à main levée + + + ink edit + éditeur de dissin à main levée + + + input focus + zone d'interaction + + + Insert + Insertion + + + Insert Object + Insérer un objet + + + insertion point + point d'insertion + + + italic + italique + + + label + nom de volume + + + label + étiquette + + + landscape + paysage + + + lasso-tap + toucher lasso + + + lens + loupe + control + + + link + lier + verb + + + link + liaison + noun + + + Link Here + Lier ici + + + list box + zone de liste + + + list view + presentación de iconos + control + + + list view + Liste icônes + control + + + manual link + liaison manuelle + + + Maximize + Agrandissement + + + maximize button + agrandir + + + MDI + MDI + + + menu + menu + + + menu bar + barre de menus + + + menu button + bouton de menus + + + menu item + élément de menu + + + menu title + titre de menu + + + message box + boîte de message + + + Minimize + Réduction + + + minimize button + réduire + + + mixed-value + valeurs multiples + + + modal + modal + + + mode + mode + + + modeless + non modal + + + modifier key + touche de modification + + + mouse + souris + + + Move + Déplacement + + + Move Here + Transférer ici + + + Multiple Document Interface + Interface documents multiples + + + multiple selection list box + zone de liste à sélection multiple + + + My Computer + Poste de travail + icon + + + Network Neighborhood + Voisinage réseau + icon + + + New + Nouveau + + + Next + Suivant + + + object + objet + + + OK + OK + + + OLE + OLE + + + OLE drag and drop + glisser-déplacer OLE + + + OLE embedded object + Objet OLE incorporé + + + OLE linked object + Objet OLE lié + + + OLE nondefault drag and drop + glisser-déplacer OLE non standard + + + Open + Ouvrir + + + Open With + Ouvrir avec + + + option button + case d'option + + + option-set + état des caractéristiques + + + package + ensemble + + + Page Setup + Mise en page + + + palette window + palette + + + pane + volet + + + parent window + fenêtre parent + + + password + mot de passe + + + Paste + Coller + + + Paste Link + Coller avec liaison + + + Paste Shortcut + Coller le raccourci + + + Paste Special + Collage spécial + + + path + chemin + + + Pause + Pause + + + pen + stylet + + + Play + Exécuter + + + Plug and Play + Plug and Play + + + point + point + noun + + + point + amener le pointeur sur + verb + + + pointer + pointeur + + + pop-up menu + menu autonome + + + pop-up window + fenêtre autonome + + + portrait + portrait + + + press + appuyer + and hold a mouse button/et maintenir enfoncé + + + press + appuyer + a key/sur une touche + + + primary container + contenuer principale + + + primary window + fenêtre principale + + + Print + Imprimer + + + printer + imprimante + + + progress indicator + indicateur d'état + control + + + project + projet + + + Properties + Propriétés + + + property inspector + inspecteur de propriétés + + + property page + page de propriétés + + + property sheet + feuille de propriétés + + + property sheet control + feuille de propriétés + + + Quick View + Aperçu + + + read-only + en lecture seule + + + recognition + reconnaissance + + + Recycle Bin + Corbeille + Icon + + + Redo + Annuler Annuler + + + region selection + sélection par zone + + + registry + base des registres + + + Repeat + Répéter + + + Replace + Remplacer + + + Restore + Restauration + + + Restore button + Restaurer + + + Resume + Reprendre + + + Retry + Essayer de nouveau + + + rich-text box + zone de texte RTF + Rich Text Format + + + Run + Exécuter + + + Save + Enregistrer + + + Save as + Enregistrer sous + + + scroll + faire défiler + + + scroll arrow + flèche de défilement + + + scroll bar + barre de défilement + + + scroll box + curseur de défilement + + + secondary window + fenêtre secondaire + + + select + sélectionner + + + Select All + Tout sélectionner + + + selection + sélection + + + selection handle + handle de sélection + + + Send To + Envoyer vers + + + separator + séparateur + + + Settings + Paramètres + + + Setup + Installation + + + Setup + INSTALL + + + shortcut + raccourci + + + shortcut button + raccourci + + + shortcut icon + raccourci + + + shortcut key + touche de raccourci + + + shortcut key control + touche de raccourci + + + Show + Afficher + + + Shutdown + Arrêter l'ordinateur + + + single selection list box + zone de liste à sélection unique + + + Size + Dimension + + + size grip + poignée de redimensionnement + + + slider + défileur + + + spin box + compteur + + + Split + Fractionner + + + split bar + barre de fractionnement + + + split box + curseur de fractionnement + + + Start button + Démarrer + + + StartUp folder + dossier de démarrage + + + status bar + barre d'état + + + Stop + Arrêter + + + tab control + onglet + + + tap + toucher + + + task bar + barre des tâches + + + task-oriented Help + aide spécifique aux tâches + + + template + modèle + + + text box + zone de texte + + + title bar + barre de titre + + + title text + texte de la barre de titre + + + toggle key + touche bascule + + + toolbar + barre d'outils + + + tooltip + info-bulle + + + tree view control + arborescencel + + + type + type + noun + + + type + taper + verb + + + unavailable + pas disponible + + + Undo + Annuler + + + Uninstall + Désinstaller + + + View + Affichage + + + visual editing + activation sur place + + + well control + sélection graphique + + + What's This? + Qu'est-ce que c'est? + + + Window + Fenêtre + + + window + fenêtre + + + Windows Explorer + Explorateur Windows + + + wizard + assistant + + + workbook + classeur + + + workgroup + groupe de travail + + + workspace + espace de travail + + + Yes + Oui + + diff --git a/tools/linguist/phrasebooks/german.qph b/tools/linguist/phrasebooks/german.qph new file mode 100644 index 0000000..9149942 --- /dev/null +++ b/tools/linguist/phrasebooks/german.qph @@ -0,0 +1,1075 @@ + + + About + Info + + + access key + Zugriffstaste + + + accessibility + Eingabehilfe + + + action handle + Aktionspunkt + + + active + Aktiv + + + active end + Aktives Ende + + + active object + Aktives Objekt + + + active window + Aktives Fenster + + + adornment + Zubehör + + + Always on Top + Immer im Vordergrund + + + anchor point + Ankerpunkt + + + Apply + Zuweisen + + + auto-exit + Textfeld mit automatischer Freigabe + + + auto-repeat + Automatische Wiederholung + + + automatic link + Automatische OLE-Verknüpfung + + + automatic scrolling + Automatischer Bildlauf + + + autoscroll + Automatischer Bildlauf + + + Back + Zurück + + + barrel button + Pen-Knopf + pen + + + barrel-tap + Tippen mit Pen-Knopf + + + boxed edit + Texteditor + control/Steuerelement + + + Browse + Durchsuchen + + + Cancel + Abbrechen + + + cascading menu + Überlappendes Menü + + + check box + Kontrollkästchen + + + check mark + Markierung + Kontrollkästchen + + + child window + Untergeordnetes Fenster + + + choose + Wählen + + + click + Klicken + + + Clipboard + Zwischenablage + + + Close + Schließen + + + Close button + Schließen + Schaltfläche + + + collapse + Ausblenden + outline/Gliederung + + + column heading + Spaltenüberschrift + control/Steuerelement + + + combo box + Kombinationsfeld + + + command button + Schaltfläche + + + container + Container + + + context-sensitive Help + Kontextbezogene Hilfe + + + contextual + Kontextbezogen + + + control + Steuerelement + + + Copy + Kopieren + + + Copy here + Hierher kopieren + + + Create Shortcut + Verknüpfung erstellen + + + Create Shortcut Here + Hiermit verknüpfen + + + Cut + Ausschneiden + + + default + Standard + + + default button + Standardschaltfläche + + + Delete + Löschen + + + desktop + Desktop + + + destination + Ziel + + + dialog box + Dialogfeld + + + disability + Behinderung + + + disjoint selection + Nichtzusammenhängende Auswahl + + + dock + Verankern + + + document + Dokument + + + double-click + Doppelklicken + + + double-tap + Doppeltippen + + + drag + Ziehen + + + drag-and-drop + Drag & Drop + + + drop-down combo box + Dropdown-Kombinationsfeld + + + drop-down list box + Dropdown-Listenfeld + + + drop-down menu + Dropdown-Menü + + + Edit + Bearbeiten + + + Edit + Bearbeiten + menu/Menü + + + ellipsis + Auslassungspunkte + + + embedded object + Eingebettetes + + + Exit + Beenden + + + expand + Einblenden + an outline/einer Struktur + + + Explore + Explorer + Befehl + + + extended selection + Erweiterte Auswahl + + + extended selection list box + Listenfeld für erweiterte Auswahl + + + File + Datei + menu + + + file + Datei + + + Find + Suchen + + + Find Next + Weitersuchen + + + Find What + Suchen nach + + + folder + Ordner + + + font + Schriftart + + + font size + Schriftgrad + + + font style + Schriftschnitt + + + function key + Funktionstaste + + + gesture + Schriftzug + + + glyph + Zeichen + + + group box + Gruppenfeld + + + handle + Ziehpunkt + + + Help + ? + menu + + + Help + Hilfe + + + Hide + Ausblenden + + + hierarchical selection + Hierarchische Auswahl + + + hold + Halten + + + hot spot + Hot Spot + + + hot zone + Hot Zone + + + icon + Symbol + + + inactive + Inaktiv + + + inactive window + Inaktives Fenster + + + ink + Ink + + + ink edit + Inkeditor + + + input focus + Eingabefokus + + + Insert + Einfügen + Menü + + + Insert Object + Objekt einfügen + + + insertion point + Einfügemarke + + + italic + Kursiv + + + label + Bezeichnung + + + landscape + Querformat + + + lasso-tap + Lasso-tippen + + + lens + Lupe + control + + + link + Verknüpfung + noun + + + link + Verknüpfen + verb + + + Link Here + Hiermit verknüpfen + + + list box + Listenfeld + + + list view + Listenansicht + control + + + manual link + Manuelle OLE-Verknüpfung + + + Maximize + Maximieren + + + maximize button + Maximieren + Schaltfläche + + + MDI + MDI + + + menu + Menü + + + menu bar + Menüleiste + + + menu button + Menü + Schaltfläche + + + menu item + Menüelement + + + menu title + Menütitel + + + message box + Meldungsfeld + + + Minimize + Minimieren + + + minimize button + Minimieren + Schaltfläche + + + mixed-value + Gemischt + + + modal + Modal + + + mode + Modus + + + modeless + Interaktiv + + + modifier key + Zusatztaste + + + mouse + Maus + + + Move + Verschieben + + + Move Here + Hierher verschieben + + + Multiple Document Interface + MDI + Multiple Document Interface + + + multiple selection list box + Listenfeld für Mehrfachauswahl + + + My Computer + Arbeitsplatz + icon/Symbol + + + Network Neighborhood + Netzwerk + icon/Symbol + + + New + Neu + + + Next + Weiter + + + object + Objekt + + + OK + OK + + + OLE + OLE + + + OLE drag and drop + OLE-Drag & Drop + + + OLE embedded object + Eingebettetes OLE-Objekt + + + OLE linked object + Verknüpftes OLE-Objekt + + + OLE nondefault drag and drop + Vom Standard abweichendes OLE-Drag & Drop + + + OLE nondefault drag and drop + Aangepast slepen en neerzetten via OLE + + + Open + Öffnen + + + Open With + Öffnen mit + + + option button + Optionsfeld + + + option-set + Aktivierte Option + + + package + Paket + + + Page Setup + Seite einrichten + + + palette window + Palettenfenster + + + pane + Fensterbereich + + + parent window + Übergeordnetes Fenster + + + password + Kennwort + + + Paste + Einfügen + + + Paste Link + Verknüpfung einfügen + + + Paste Shortcut + Verknüpfung einfügen + + + Paste Special + Inhalte einfügen + + + path + Pfad + + + Pause + Anhalten + + + pen + Pen + + + Play + Wiedergeben + + + Plug and Play + Plug & Play + + + point + Zeigen + + + pointer + Zeiger + + + pop-up menu + Kontextmenü + + + pop-up window + Popup-Fenster + + + portrait + Hochformat + + + press + Drücken + and hold a mouse button/und Halten einer Maustaste + + + press + Drücken + a key/einer Taste + + + primary container + Primär-Container + + + primary window + Primärfenster + + + Print + Drucken + + + printer + Drucker + + + progress indicator + Statusanzeige + control + + + project + Projekt + + + Properties + Eigenschaften + + + property inspector + Eigenschaftenanzeige + + + property page + Eigenschaftengruppe + + + property sheet + Eigenschaftenfenster + + + property sheet control + Eigenschaftenfenster-Steuerelement + + + Quick View + Schnellansicht + + + read-only + Schreibgeschützt + + + recognition + Schrifterkennung + + + Recycle Bin + Papierkorb + Icon/Symbol + + + Redo + Wiederherstellen + + + region selection + Bereichsauswahl + + + registry + Registrierung + + + Repeat + Wiederholen + + + Replace + Ersetzen + + + Restore + Wiederherstellen + + + Restore button + Wiederherstellen + Schaltfläche + + + Resume + Fortsetzen + + + Retry + Wiederholen + + + rich-text box + RTF-Textfeld + + + Run + Ausführen + + + Save + Speichern + + + Save as + Speichern unter + + + scroll + Bildlauf durchführen + + + scroll arrow + Bildlaufpfeil + + + scroll bar + Bildlaufleiste + + + scroll box + Bildlauffeld + + + secondary window + Sekundärfenster + + + select + Auswählen + + + Select All + Alle markieren + + + selection + Auswahl + + + selection handle + Auswahlpunkt + + + Send To + Senden an + + + separator + Trennelement + + + Settings + Einstellungen + + + Setup + Einrichten + + + shortcut + Verknüpfung + + + shortcut button + Verknüpfte Schaltfläche + + + shortcut icon + Verknüpfungssymbol + + + shortcut key + Tastenkombination + + + shortcut key control + Steuerelement für Tastenbelegung + + + Show + Anzeigen + + + Shutdown + Beenden + + + single selection list box + Listenfeld für Einfachauswahl + + + Size + Größe ändern + + + size grip + Element für Größenänderung + + + slider + Schieber + + + spin box + Drehfeld + + + Split + Teilen + + + split bar + Fensterteiler + + + split box + Teilungsfeld + + + Start button + Start + Schaltfläche + + + StartUp folder + Autostart + Ordner + + + status bar + Statusleiste + + + Stop + Beenden + + + tab control + Register + + + tap + Tippen + + + task bar + Task-Leiste + + + task-oriented Help + Vorgangsbezogene Hilfe + + + template + Vorlage + + + text box + Textfeld + + + title bar + Titelleiste + + + title text + Titeltext + + + toggle key + Ein-/Aus-Taste + + + toolbar + Symbolleiste + + + tooltip + QuickInfo + + + tree view control + Strukturansicht + + + type + Eingeben + verb + + + type + Typ + noun + + + unavailable + Nicht verfügbar + + + Undo + Rückgängig + + + Uninstall + Deinstallieren + + + View + Ansicht + Menü + + + visual editing + Direkte Bearbeitung + + + well control + Steuerelement zur Grafikanzeige + + + What's This? + Direkthilfe + + + Window + Fenster + Menü + + + window + Fenster + + + Windows Explorer + Explorer + + + wizard + Assistent + + + workbook + Arbeitsmappe + + + workgroup + Arbeitsgruppe + + + workspace + Arbeitsbereich + + + Yes + Ja + + diff --git a/tools/linguist/phrasebooks/italian.qph b/tools/linguist/phrasebooks/italian.qph new file mode 100644 index 0000000..2aa3d7a --- /dev/null +++ b/tools/linguist/phrasebooks/italian.qph @@ -0,0 +1,1105 @@ + + + About + Informazioni su + + + access key + tasto di scelta + + + accessibility + accesso facilitato + + + action handle + identificatore dell'azione + + + active + attivo + + + active end + punto finale + + + active object + oggetto attivo + + + active window + finestra attiva + + + adornment + barra + + + Always on Top + Sempre in primo piano + + + anchor point + punto di ancoraggio + + + Apply + Applica + + + auto-exit + ad uscita automatica + + + auto-repeat + a ripetizione automatica + + + automatic link + collegamento automatico + + + automatic scrolling + scorrimento automatico + + + autoscroll + scorrimento automatico + + + Back + Indietro + + + barrel button + pulsante della penna + pen + + + barrel-tap + tocco con il pulsante premuto + + + boxed edit + casella di testo a griglia + control + + + Browse + Sfoglia + + + Cancel + Annulla + + + cascading menu + menu sovrapposto + + + check box + casella di controllo + + + check mark + segno di spunta + + + child window + finestra secondaria + + + choose + scegliere + + + click + fare clic + + + Clipboard + Appunti + + + Close + Chiudi + + + Close button + pulsante di chiusura + + + collapse + comprimere + outline, verb + + + column heading + intestazione di colonna + control + + + combo box + casella combinata + + + command button + pulsante di comando + + + container + contenitore + + + context-sensitive Help + guida sensibile al contesto + + + contextual + contestuale + + + control + controllo + + + Copy + Copia + + + Copy here + Copia + + + Create Shortcut + Crea collegamento + + + Create Shortcut Here + Crea collegamento + + + Cut + Taglia + + + default + predefinito + + + default button + pulsante predefinito + + + Delete + Elimina + + + desktop + desktop + + + destination + destinazione + + + dialog box + finestra di dialogo + + + disability + disabilità + + + disjoint selection + selezione multipla + + + dock + posizionare + + + document + documento + + + double-click + doppio clic + noun + + + double-click + fare doppio clic + verb + + + double-tap + toccare due volte in rapida successione + verb + + + double-tap + doppio tocco + noun + + + drag + trascinare + + + drag-and-drop + trascinare e rilasciare + verb + + + drag-and-drop + caratteristica Trascina selezione + noun + + + drop-down combo box + casella combinata a discesa + + + drop-down list box + casella di riepilogo a discesa + + + drop-down menu + menu a discesa + + + Edit + Modifica + + + Edit menu + menu Modifica + + + ellipsis + puntini di sospensione + + + embedded object + oggetto incorporato + + + Exit + Esci + + + expand + espandere + an outline/una struttura + + + Explore + Gestione risorse + + + extended selection + selezione estesa + + + extended selection list box + casella di riepilogo a selezione estesa + + + file + file + + + File menu + menu File + + + Find + Trova + + + Find Next + Trova successivo + + + Find What + Trova + + + folder + cartella + + + font + tipo di carattere + + + font size + dimensione carattere + + + font style + stile carattere + + + function key + tasto funzione + + + gesture + segno + + + glyph + icona + + + group box + casella di gruppo + + + handle + quadratino di ridimensionamento + noun + + + Help + Guida + + + Help menu + menu ? + + + Hide + Nascondi + + + hierarchical selection + selezione gerarchica + + + hold + tenere premuto + + + hot spot + area sensibile del puntatore + + + hot zone + area sensibile dell'oggetto + + + icon + icona + + + inactive + inattivo + + + inactive window + finestra inattiva + + + ink + tratto + + + ink edit + modifica tratto + + + input focus + elemento attivo + + + Insert + menu Inserisci + + + Insert Object + Inserisci oggetto + + + insertion point + punto di inserimento + + + italic + corsivo + + + label + etichetta + + + landscape + orizzontale + + + lasso-tap + selezione circolare + + + lens + lente + control + + + link + collegamento + noun + + + link + collegare + verb + + + Link Here + Collega + + + list box + casella di riepilogo + + + list view + visualizzazione elementi + control + + + manual link + collegamento manuale + + + Maximize + Ingrandisci + + + maximize button + pulsante di ingrandimento + + + MDI + MDI + + + menu + menu + + + menu bar + barra dei menu + + + menu button + pulsante menu + + + menu item + voce di menu + + + menu title + titolo di menu + + + message box + finestra di messaggio + + + Minimize + Riduci a icona + + + minimize button + pulsante di riduzione ad icona + + + mixed-value + valori misti + + + modal + a scelta obbligatoria + + + mode + modalità + + + modeless + non a scelta obbligatoria + + + modifier key + tasto di modifica delle funzioni di tastiera + + + modifier key + tasto di modifica dell'output di tastiera + + + mouse + mouse + + + Move + Sposta + + + Move Here + Sposta + + + Multiple Document Interface + interfaccia a documenti multipli + + + multiple selection list box + casella di riepilogo a selezione multipla + + + My Computer + Risorse del computer + icon/icono + + + Network Neighborhood + Risorse di rete + icon + + + New + Nuovo + + + Next + Avanti + + + object + oggetto + + + OK + OK + + + OLE + OLE + + + OLE drag and drop + caratteristica Trascina selezione + + + OLE embedded object + oggetto incorporato OLE + + + OLE linked object + oggetto collegato OLE + + + OLE nondefault drag and drop + caratteristica Trascina selezione OLE non predefinita + + + Open + Apri + + + Open With + Apri con + + + option button + pulsante di opzione + + + option-set + opzione impostata + + + option-set + opzione attivata + + + package + package + + + Page Setup + Imposta pagina + + + palette window + casella degli tavolozza di colori + + + palette window + casella degli strumenti + + + pane + riquadro + + + parent window + finestra principale + + + password + password + + + Paste + Incolla + + + Paste Link + Incolla collegamento + + + Paste Shortcut + Incolla collegamento + + + Paste Special + Incolla speciale + + + path + percorso + + + Pause + Interrompi + + + pen + penna + + + Play + Riproduci + + + Plug and Play + Plug and Play + + + point + punto + + + pointer + puntatore + + + pop-up menu + menu di scelta rapida + + + pop-up window + finestra popup + + + portrait + verticale + + + press + premere + a key/un tasto + + + press + premere + and hold a mouse button/e tenere premuto un pulsante del mouse + + + primary container + contenitore principale + + + primary window + finestra principale + + + Print + Stampa + + + printer + stampante + + + progress indicator + indicatore di avanzamento del processo + control + + + project + progetto + + + Properties + Proprietà + + + property inspector + visualizzatore proprietà + + + property page + scheda proprietà + + + property sheet + finestra proprietà + + + property sheet control + controllo finestra proprietà + + + Quick View + Anteprima + + + read-only + sola lettura + + + recognition + riconoscimento + + + Recycle Bin + Cestino + Icon + + + Redo + Ripeti + + + region selection + selezione dell'area + + + registry + registro di configurazione + + + Repeat + Ripeti + + + Replace + Sostituisci + + + Restore + Ripristina + + + Restore button + pulsante di ripristino + + + Resume + Riprendi + + + Retry + Riprova + + + rich-text box + casello di testo RTF + + + Run + Esegui + + + Save + Salva + + + Save as + Salva con nome + + + scroll + scorrere + verb + + + scroll arrow + freccia di scorrimento + + + scroll bar + barra di scorrimento + + + scroll box + casella di scorrimento + + + secondary window + finestra secondaria + + + select + selezionare + verb + + + Select All + Seleziona tutto + + + selection + selezione + + + selection handle + quadratino di selezione + + + Send To + Invia a + + + separator + separatore + + + Settings + Impostazioni + + + Setup + Imposta + + + shortcut + collegamento + + + shortcut button + pulsante di collegamento + + + shortcut icon + icona di collegamento + + + shortcut key + tasto di scelta rapida + + + shortcut key control + controllo tasto di scelta rapida + + + Show + Mostra + + + Shutdown + Chiudi sessione + comando del menu Avvio + + + Shutdown + Arresta il sistema + pulsanti e opzioni + + + single selection list box + casella di riepilogo a selezione singola + + + Size + Dimensione + + + size grip + punto di ridimensionamento + + + slider + dispositivo di scorrimento + + + spin box + casella di selezione + + + Split + Dividi + + + split bar + barra di divisione + + + split box + casella di divisione + + + Start button + pulsante Avvio + + + StartUp folder + cartella Esecuzione automatica + + + status bar + barra di stato + + + Stop + Ferma + + + tab control + controllo a schede + + + tap + toccare + verb + + + tap + tocco + noun + + + task bar + barra delle applicazioni + + + task-oriented Help + guida orientata alle attività + + + template + modello + + + text box + casella di testo + + + title bar + barra del titolo + + + title text + testo della barra del titolo + + + toggle key + tasto interruttore + + + toolbar + barra degli strumenti + + + tooltip + descrizione comando + + + tree view control + controllo per la visualizzazione ad albero + + + type + inserire + verb + + + type + digitare + verb + + + type + tipo + noun + + + unavailable + non disponibile + + + Undo + Annulla + + + Uninstall + Rimozione + + + View + menu Visualizza + + + visual editing + modifica diretta + + + well control + controllo di selezione grafica + + + What's This? + Guida rapida + + + Window + menu Finestra + + + window + finestra + + + Windows Explorer + Gestione risorse + + + wizard + installazione guidata + + + workbook + cartella di lavoro + + + workgroup + gruppo di lavoro + + + workspace + area di lavoro + + + Yes + + + diff --git a/tools/linguist/phrasebooks/norwegian.qph b/tools/linguist/phrasebooks/norwegian.qph new file mode 100644 index 0000000..d01187c --- /dev/null +++ b/tools/linguist/phrasebooks/norwegian.qph @@ -0,0 +1,1004 @@ + + + About + Om + + + access key + tilgangstast + + + accessibility + tilgjengelighet + + + action handle + handlingshåndtak + + + active + aktiv + + + active end + markeringsavslutning + + + active object + aktivt objekt + + + active window + aktivt vindu + + + adornment + verktøyselement + + + Always on Top + Alltid øverst + + + anchor point + forankringspunkt + + + Apply + Bruk + + + auto-exit + automatisk avslutning + + + auto-repeat + automatisk gjentagelse + + + automatic link + automatisk kobling + + + automatic scrolling + automatisk rulling + + + autoscroll + autorulling + + + Back + Tilbake + + + Browse + Bla gjennom + + + Cancel + Avbryt + + + cascading menu + undermeny + + + check box + avmerkingsboks + + + check mark + merke + + + child window + undervindu + + + choose + velge + + + click + klikke + + + Clipboard + utklippstavle + + + Close + Lukk + + + Close button + lukkeknapp + + + collapse + skjule + outline/disposisjon + + + column heading + kolonneoverskrift + control/kontroll + + + combo box + kombinasjonsboks + + + command button + kommandoknapp + + + container + beholder + + + context-sensitive Help + kontekstavhengig hjelp + + + contextual + kontekstavhengig + + + control + kontroll + + + Copy + Kopier + + + Copy here + Kopier hit + + + Create Shortcut + Lag snarvei + + + Create Shortcut Here + Lag snarvei her + + + Cut + Klipp ut + + + default + standard + + + default button + standardknapp + + + Delete + Slett + + + desktop + skrivebord + + + destination + mål + + + dialog box + dialogboks + + + disability + funksjonshemning + + + disjoint selection + ikke sammenhengende utvalg + + + dock + forankre + + + document + dokument + + + double-click + dobbeltklikke + + + drag + dra + + + drag-and-drop + dra och slippe + + + drop-down combo box + kombinasjonsboks + + + drop-down list box + rullegardinliste + + + drop-down menu + rullegardinmeny + + + Edit + Rediger + + + Edit menu + Rediger-menyen + + + ellipsis + ellipse + + + embedded object + innebygd objekt + + + Exit + Avslutt + + + expand + utvide + an outline/en disposisjon + + + Explore + Utforsk + + + extended selection + utvidet merking + + + extended selection list box + liste med utvidet merking + + + file + fil + + + File menu + Fil-menyen + + + Find + Søk etter + + + Find Next + Søk etter neste + + + Find What + Søk etter + + + folder + mappe + + + font + skrift + + + font size + skriftstørrelse + + + font style + skriftstil + + + function key + funksjonstast + + + group box + gruppeboks + + + handle + håndtak + + + Help + Hjelp + + + Help menu + Hjelp-menyen + + + Hide + Skjul + + + hierarchical selection + hierarkisk merking + + + hold + holde + + + hot spot + fokus + + + hot zone + fokuseringssone + + + icon + ikon + + + inactive + inaktiv + + + inactive window + inaktivt vindu + + + input focus + indatafokus + + + Insert + Sett inn-menyen + + + Insert Object + Sett inn objekt + + + insertion point + innsettingspunkt + + + italic + kursiv + + + label + etikett + + + landscape + liggende + + + link + koble + verb + + + link + kobling + noun + + + Link Here + Lag kobling her + + + list box + listeboks + + + list view + listevisning + control/kontroll + + + manual link + manuell kobling + + + Maximize + Maksimer + + + maximize button + maksimeringsknapp + + + MDI + MDI + + + menu + meny + + + menu bar + menylinje + + + menu button + menyknapp + + + menu item + menyelement + + + menu title + menytittel + + + message box + meldingsboks + + + Minimize + Minimer + + + minimize button + minimeringsknapp + + + mixed-value + blandet verdi + + + modal + modal + + + mode + modus + + + modeless + icke-modal + + + modifier key + modifiseringstast + + + mouse + mus + + + Move + Flytt + + + Move Here + Flytt hit + + + Multiple Document Interface + flerdokumentgrensesnitt + + + multiple selection list box + flervalgsliste + + + My Computer + Min datamaskin + icon/ikon + + + Network Neighborhood + Andre maskiner + icon/ikon + + + New + Ny + + + Next + Neste + + + object + objekt + + + OK + OK + + + OLE + OLE + + + OLE drag and drop + OLE dra og slipp + + + OLE embedded object + innebyggd OLE-objekt + + + OLE linked object + koblet OLE-objekt + + + OLE nondefault drag and drop + utvidet OLE dra og slipp + + + Open + Åpne + + + Open With + Åpne i + + + option button + alternativknapp + + + option-set + valgt alternativ + + + package + pakke + + + Page Setup + Utskriftsformat + + + palette window + palettvindu + + + pane + rute + + + parent window + hovedvindu + + + password + passord + + + Paste + Lim inn + + + Paste Link + Lim inn kobling + + + Paste Shortcut + Lim inn snarvei + + + Paste Special + Lim inn utvalg + + + path + bane + + + Pause + Pause + + + Play + Spill + + + Plug and Play + Plug and Play + + + point + punkt + + + point + peke + + + pointer + peker + + + pop-up menu + hurtigmeny + + + pop-up window + forklaringsvindu + + + portrait + stående + + + press + klikke + and hold a mouse button/og holde nede en musetast + + + press + trykke + a key/en tast + + + primary container + primærbeholder + + + primary window + primærvindu + + + Print + Skriv ut + + + printer + skriver + + + progress indicator + fremdriftsindikator + control/kontroll + + + project + prosjekt + + + Properties + Egenskaper + + + property inspector + egenskapsvisning + + + property page + egenskapsside + + + property sheet + egenskapsark + + + property sheet control + egenskapsarkkontroll + + + Quick View + Hurtigvisning + + + read-only + skrivebeskyttet + + + Recycle Bin + Papirkurv + Icon/ikon + + + Redo + Gjør om + + + region selection + områdemerking + + + registry + register + + + Repeat + Gjenta + + + Replace + Erstatt + + + Restore + Gjenopprett + + + Restore button + gjenopprettingsknapp + + + Resume + Fortsett + + + Retry + Prøv på nytt + + + rich-text box + boks for rik tekst + + + Run + Kjør + + + Save + Lagre + + + Save as + Lagre som + + + scroll + rulle + + + scroll arrow + rullepil + + + scroll bar + rullefelt + + + scroll box + rulleboks + + + secondary window + sekundærvindu + + + select + merke + + + Select All + Merk alt + + + selection + merket område + + + selection handle + markeringshåndtak + + + Send To + Send til + + + separator + skilletegn + + + Settings + Innstillinger + + + Setup + Installasjon + + + shortcut + snarvei + + + shortcut button + snarveisknapp + + + shortcut icon + snarveisikon + + + shortcut key + hurtigtast + + + shortcut key control + hurtigtastkontroll + + + Show + Vis + + + Shutdown + Avslutt + + + single selection list box + enkeltvalgsliste + + + Size + Størrelse + + + size grip + skaleringshåndtak + + + slider + glidebryter + + + spin box + verdisettingsboks + + + Split + Del + + + split bar + delelinje + + + split box + deleboks + + + Start button + startknapp + + + StartUp folder + Oppstart-mappen + + + status bar + statuslinje + + + Stop + Stopp + + + tab control + kategorikontroll + + + task bar + oppgavelinje + + + task-oriented Help + oppgaveorientert hjelp + + + template + mal + + + text box + tekstboks + + + title bar + tittellinje + + + title text + titteltekst + + + toggle key + veksletast + + + toolbar + verktøylinje + + + tooltip + verktøytips + + + tree view control + trevisningskontroll + + + type + skrive + verb + + + type + type + noun + + + unavailable + ikke tilgjengelig + + + Undo + Angre + + + Uninstall + Avinstaller + + + View + Vis-meny + + + visual editing + visuell redigering + + + well control + grafikkontroll + + + What's This? + Hva er dette? + + + Window + Vindu-menyen + + + window + vindu + + + Windows Explorer + Windows Utforsker + + + wizard + veiviser + + + workbook + arbeidsbok + + + workgroup + arbeidsgruppe + + + workspace + arbeidsområde + + + Yes + Ja + + diff --git a/tools/linguist/phrasebooks/russian.qph b/tools/linguist/phrasebooks/russian.qph new file mode 100644 index 0000000..ec64aae --- /dev/null +++ b/tools/linguist/phrasebooks/russian.qph @@ -0,0 +1,982 @@ + + + About + О программе + + + access key + горячая клавиша + + + accessibility + удобство + + + action handle + управление поведением + + + active + активный + + + active end + окончание выбора + + + active object + активный объект + + + active window + активное окно + + + adornment + украшение + + + Always on Top + Всегда наверху + + + anchor point + точка начала выбора + + + Apply + Применить + + + auto-exit + автоматический выход + + + auto-repeat + авто-повтор + + + automatic link + автоматическое связывание + + + automatic scrolling + автоматическая прокрутка + + + autoscroll + авто-прокрутка + + + Back + Назад + + + boxed edit + окно редактирования + + + Browse + Обзор + + + Cancel + Отмена + + + cascading menu + ниспадающее меню + + + check box + флажок + + + check mark + флажок + + + child window + дочернее окно + + + choose + выбрать + + + click + щелчок + + + Clipboard + Буфер обмена + + + Close + Закрыть + + + Close button + кнопка закрытия + + + collapse + крах + + + column heading + заголовок колонки + + + combo box + поле со списком + + + command button + кнопка + + + container + контейнер + + + context-sensitive Help + контекстная помощь + + + contextual + контекстный + + + control + элемент управления + + + Copy + Копировать + + + Copy here + Копировать сюда + + + Create Shortcut + Создать ярлык + + + Create Shortcut Here + Создать ярлык здесь + + + Cut + Вырезать + + + default + по умолчанию + + + default button + кнопка по умолчанию + + + Delete + Удалить + + + desktop + рабочий стол + + + destination + цель + + + dialog box + окно диалога + + + disability + неспособность + + + disjoint selection + разделить выбранные элементы + + + dock + док + + + document + документ + + + double-click + двойной щелчок + + + drag + перетащить + + + drag-and-drop + drag-and-drop + + + drop-down combo box + раскрыть поле со списком + + + drop-down list box + прокрутить список + + + drop-down menu + открыть меню + + + Edit + Правка + + + Edit menu + меню Правка + + + ellipsis + эллипс + + + embedded object + встроенный объект + + + Exit + Выход + + + expand + расширять + + + Explore + Исследовать + + + extended selection + расширенный выбор + + + extended selection list box + список с расширенным выбором + + + file + файл + + + File menu + меню Файл + + + Find + Поиск + + + Find Next + Продолжить поиск + + + Find What + Поиск + + + folder + каталог + + + font + шрифт + + + font size + размер шрифта + + + font style + стиль шрифта + + + function key + функциональная клавиша + + + glyph + глиф + + + group box + контейнер элементов + + + handle + управление + + + Help + Справка + + + Hide + Скрыть + + + hierarchical selection + иерархический выбор + + + hold + удерживать + + + hot spot + фокус + + + hot zone + активная зона + + + icon + пиктограмма + + + inactive + неактивный + + + inactive window + неактивное окно + + + input focus + фокус ввода + + + Insert + Вставить + + + Insert Object + Вставить объект + + + insertion point + место вставки + + + italic + курсив + + + label + надпись + + + landscape + альбом + + + link + ссылка + + + link + связать + + + Link Here + Создать ссылку здесь + + + list box + список + + + list view + древовидный список + + + manual link + ручное связывание + + + Maximize + Распахнуть + + + maximize button + кнопка максимизации + + + MDI + MDI + + + menu + меню + + + menu bar + строка меню + + + menu button + кнопка меню + + + menu item + элемент меню + + + menu title + заголовок меню + + + message box + окно сообщений + + + Minimize + Свернуть + + + minimize button + кнопка минимизации + + + modal + модальный + + + mode + режим + + + modeless + немодальный + + + modifier key + клавиша-модификатор + + + mouse + мышь + + + Move + Переместить + + + Move Here + Переместить сюда + + + Multiple Document Interface + Multiple Document Interface + + + multiple selection list box + список с множественным выбором + + + My Computer + Мой компьютер + + + Network Neighborhood + Сетевое окружение + + + New + Новый + + + Next + Следующий + + + object + объект + + + OK + OK + + + OLE + OLE + + + OLE drag and drop + OLE-механизм + + + OLE embedded object + внедренный OLE-объект + + + OLE linked object + связанный OLE-объект + + + OLE nondefault drag and drop + предопределенный OLE-механизм + + + Open + Открыть + + + Open With + Открыть с помощью + + + option button + переключатель + + + option-set + набор параметров + + + package + пакет + + + Page Setup + шаг установки + + + palette window + окно выбора палитры + + + pane + панель + + + parent window + родительское окно + + + password + пароль + + + Paste + Вставить + + + Paste Link + Вставить ссылку + + + Paste Shortcut + Вставить ярлык + + + Paste Special + Специальная вставка + + + path + путь + + + Pause + Пауза + + + Play + Воспроизведение + + + Plug and Play + Plug and Play + + + point + пункт + + + pointer + указатель + + + pop-up menu + всплывающее меню + + + pop-up window + всплывающее окно + + + portrait + портрет + + + press + нажимать + + + primary container + корневой контейнер + + + primary window + главное окно + + + Print + Печать + + + printer + принтер + + + progress indicator + индикатор хода процесса + + + project + проект + + + Properties + Свойства + + + property inspector + инспектор свойств + + + property page + страница свойств + + + property sheet + группа свойств + + + property sheet control + управление группой свойств + + + Quick View + Быстрый просмотр + + + read-only + только чтение + + + Recycle Bin + Корзина + + + Redo + Повторить + + + region selection + область выделения + + + registry + реестр + + + Repeat + Повторить + + + Replace + Заменить + + + Restore + Восстановить + + + Restore button + Кнопка восстановления + + + Resume + Продолжить + + + Retry + Повторить + + + rich-text box + окно RTF-редактора + + + Run + Выполнить + + + Save + Сохранить + + + Save as + Сохранить как + + + scroll + прокрутить + + + scroll arrow + кнопка прокрутки + + + scroll bar + полоса прокрутки + + + scroll box + окно с полосами прокрутки + + + secondary window + подчиненное окно + + + select + выбрать + + + Select All + Выделить все + + + selection + выбор + + + selection handle + осуществление выбора + + + Send To + Отправить + + + separator + разделитель + + + Settings + Настройки + + + Setup + Установить + + + shortcut + ярлык + + + shortcut button + кнопка + + + shortcut icon + пиктограмма + + + shortcut key + комбинация клавиш + + + shortcut key control + настройка комбинации клавиш + + + Show + Показать + + + Shutdown + Выключение + + + single selection list box + список с одиночным выбором + + + Size + Размер + + + size grip + уголок для изменения размера + + + slider + ползунок + + + spin box + поле со счетчиком + + + Split + Разделить + + + split bar + разделительная черта + + + split box + разделительная рамка + + + Start button + кнопка Пуск + + + StartUp folder + каталог Автозапуска + + + status bar + статусная строка + + + Stop + Стоп + + + tab control + вкладка + + + task bar + панель задач + + + task-oriented Help + контекстная справка + + + template + шаблон + + + text box + текстовое поле + + + title bar + заголовок + + + title text + текст заголовка + + + toggle key + кнопка-выключатель + + + toolbar + панель инструментов + + + tooltip + всплывающая подсказка + + + tree view control + древовидный список + + + type + тип + + + type + набирать + + + unavailable + недоступный + + + Undo + Отменить + + + Uninstall + Удалить + + + View + Вид + + + visual editing + визуальное редактирование + + + well control + элемент графического интерфейса + + + What's This? + Что это? + + + Window + Окно + + + window + окно + + + Windows Explorer + Проводник Windows + + + wizard + мастер + + + workbook + учебник + + + workgroup + рабочая группа + + + workspace + рабочая область + + + Yes + Да + + diff --git a/tools/linguist/phrasebooks/spanish.qph b/tools/linguist/phrasebooks/spanish.qph new file mode 100644 index 0000000..5559707 --- /dev/null +++ b/tools/linguist/phrasebooks/spanish.qph @@ -0,0 +1,1086 @@ + + + About + Acerca de + + + access key + tecla de acceso + + + accessibility + accesibilidad + + + action handle + controlador de acciones + + + active + activo + + + active end + fin de la selección activa + + + active object + objeto activo + + + active window + ventana activa + + + adornment + opción gráfica + + + Always on Top + Siempre visible + + + anchor point + inicio de la selección activa + + + Apply + Aplicar + + + auto-exit + salida automática + + + auto-repeat + repetición automática + + + automatic link + vínculo automático + + + automatic scrolling + desplazamiento automático + + + autoscroll + desplazamiento automático + + + Back + Atrás + + + barrel button + botón del lápiz + pen + + + barrel-tap + puntenar con el botón presionado + + + boxed edit + edición en casilla + control + + + Browse + Examinar + + + Cancel + Cancelar + + + cascading menu + menú en cascada + + + check box + casilla de verificación + + + check mark + marca de verificación + + + child window + ventana secundaria + + + choose + elegir + + + click + hacer clic + + + Clipboard + Portapapeles + + + Close + Cerrar + + + Close button + botón &quot;Cerrar&quot; + + + collapse + contraer + outline/esquerna + + + column heading + encabezado de columna + control + + + combo box + cuadro combinado + + + command button + botón de comando + + + container + contenedor + + + context-sensitive Help + ayuda interactiva + + + contextual + contextual + + + control + control + + + Copy + Copiar + + + Copy here + Copiar aquí + + + Create Shortcut + Crear acceso directo + + + Create Shortcut Here + Crear acceso directo aquí + + + Cut + Cortar + + + default + predeterminado + + + default button + botón predeterminado + + + Delete + Eliminar + + + desktop + escritorio + + + destination + destino + + + dialog box + cuadro de diálogo + + + disability + Discapacidades + + + disjoint selection + selección disjunta + + + dock + acoplar + + + document + documento + + + double-click + hacer doble clic + + + double-tap + puntear dos veces + + + drag + arrastrar + + + drag-and-drop + arrastrar y colocar + + + drop-down combo box + cuadro combinado desplegable + + + drop-down list box + cuadro de lista desplegable + + + drop-down menu + menú desplegable + + + Edit + Edición + + + Edit menu + menú Edición + + + ellipsis + puntos suspensivos + + + embedded object + objeto incrustado + + + Exit + Salir + + + expand + expandir + an outline/un esquema + + + Explore + Explorar + + + extended selection + selección extendida + + + extended selection list box + cuadro de lista de selección extendida + + + file + archivo + + + File menu + menú Archivo + + + Find + Buscar + + + Find Next + Buscar siguiente + + + Find What + Buscar + + + folder + carpeta + + + font + fuente + + + font size + tamaño de fuente + + + font style + estilo de fuente + + + function key + tecla de función + + + gesture + signo + + + glyph + símbolo gráfico + + + group box + cuadro de grupo + + + handle + controlar + verb + + + handle + controlador + noun + + + Help + Ayuda + + + Help menu + menú Ayuda + + + Hide + Ocultar + + + hierarchical selection + selección jerárquica + + + hold + mantener presionado + + + hot spot + punto interactivo + + + hot zone + zona interactiva + + + icon + icono + + + inactive + inactivo + + + inactive window + ventana inactiva + + + ink + trazo + + + ink edit + editor de trazos + + + input focus + zona de entrada + + + input focus + zona de entrada de datos + + + Insert + menú Insertar + + + Insert Object + Insertar objeto + + + insertion point + punto de inserción + + + italic + cursiva + + + label + etiqueta + + + landscape + horizontal + + + lasso-tap + punteo en la selección + + + lens + lente + control + + + link + vincular + verb + + + link + vínculo + noun + + + Link Here + Vincular aquí + + + list box + cuadro de lista + + + list view + ver lista + control + + + list view + presentación de iconos + control + + + manual link + vínculo manual + + + Maximize + Maximizar + + + maximize button + botón de maximizar + + + MDI + MDI + + + menu + menú + + + menu bar + barra de menús + + + menu button + botón de menú + + + menu item + elemento de menú + + + menu title + título de menú + + + message box + cuadro de mensaje + + + Minimize + Minimizar + + + minimize button + botón de minimizar + + + mixed-value + valores mezclados + + + modal + modal + + + mode + modo + + + modeless + sin modo + + + modifier key + tecla modificadora + + + mouse + mouse + + + Move + Mover + + + Move Here + Mover aquí + + + Multiple Document Interface + interfaz de documentos múltiples + + + multiple selection list box + cuadro de lista de selección múltiple + + + My Computer + Mi PC + icon/icono + + + Network Neighborhood + Entorno de red + icon/icono + + + New + Nuevo + + + Next + Sigulente + + + object + objeto + + + OK + Aceptar + + + OLE + OLE + + + OLE drag and drop + Arrastrar y colocar de OLE + + + OLE embedded object + Objeto incrustado de OLE + + + OLE linked object + Objeto vinculado de OLE + + + OLE nondefault drag and drop + Arrastrar y colocar no predeterminado de OLE + + + Open + Abrir + + + Open With + Abrir con + + + option button + botón de opción + + + option-set + opción establecida + + + package + paquete + + + Page Setup + Preparar página + + + palette window + ventana de paleta + + + pane + panel + + + parent window + ventana principal + + + password + contraseña + + + Paste + Pegar + + + Paste Link + Pegar vínculo + + + Paste Shortcut + Pegar acceso directo + + + Paste Special + Pegado especial + + + path + ruta de acceso + + + Pause + Pausa + + + pen + lápiz + + + Play + Reproducir + + + Plug and Play + Plug and Play + + + point + señalar + verb + + + point + punto + noun + + + pointer + puntero + + + pop-up menu + menú emergente + + + pop-up window + ventana emergente + + + portrait + vertical + + + press + presionar + and hold a mouse button/y mantener presionado un botón del mouse + + + press + presionar + a key/una tecla + + + primary container + contenedor primario + + + primary window + ventana principal + + + Print + Imprimir + + + printer + impresora + + + progress indicator + indicador de progreso + control + + + project + proyecto + + + Properties + Propiedades + + + property inspector + monitor de propiedades + + + property page + página de propiedades + + + property sheet + hoja de propiedades + + + property sheet control + control de la hoja de propiedades + + + Quick View + Vista rápida + + + read-only + sólo lectura + + + recognition + reconocimiento + + + Recycle Bin + Papelera de reciclaje + Icon/icono + + + Redo + Rehacer + + + region selection + selección de área + + + registry + Registro de configuraciones + + + Repeat + Repetir + + + Replace + Reemplazar + + + Restore + Restaurar + + + Restore button + botón &quot;Restaurar&quot; + + + Resume + Reanudar + + + Retry + Reintentar + + + rich-text box + cuadro de texto enriquecido + + + Run + Ejecutar + + + Save + Guardar + + + Save as + Guardar como + + + scroll + desplazar + + + scroll arrow + flecha de desplazamiento + + + scroll bar + barra de desplazamiento + + + scroll box + cuadro de desplazamiento + + + secondary window + ventana secundaria + + + select + seleccionar + + + Select All + Seleccionar todo + + + selection + selección + + + selection handle + controlador de selección + + + Send To + Enviar a + + + separator + separador + + + Settings + Configuración + + + Setup + Configurar + for a device already installed + + + Setup + Instalar + for an application + + + shortcut + acceso directo + + + shortcut button + botón de acceso directo + + + shortcut icon + icono de acceso directo + + + shortcut key + tecla de método abreviado + + + shortcut key control + control de la tecla de método abreviado + + + Show + Mostrar + + + Shutdown + Apagar el sistema + + + single selection list box + cuadro de lista de selección simple + + + Size + Tamaño + + + size grip + ajuste de tamaño + + + slider + control deslizante + + + spin box + cuadro selector + + + Split + Dividir + + + split bar + barra de división + + + split box + cuadro de división + + + Start button + botón &quot;Inicio&quot; + + + StartUp folder + carpeta Inicio + + + status bar + barra de estado + + + Stop + Detener + + + tab control + control de fichas + + + tap + puntear + + + task bar + barra de tareas + + + task-oriented Help + Ayuda relativa a la tarea + + + template + plantilla + + + text box + cuadro de texto + + + title bar + barra de título + + + title text + texto de título + + + toggle key + tecla para alternar + + + toolbar + barra de herramientas + + + tooltip + sugerencias + + + tree view control + control de visión en árbol + + + type + escribir + verb + + + type + tipo + noun + + + unavailable + no disponible + + + Undo + Deshacer + + + Uninstall + Desinstalar + + + View + menú Ver + + + visual editing + edición visual + + + well control + control de opciones gráficas + + + What's This? + ¿Qué es esto? + + + Window + menú Ventana + + + window + ventana + + + Windows Explorer + Explorador de Windows + + + wizard + asistente + + + workbook + libro + + + workbook + libro de trabajo + + + workgroup + grupo de trabajo + + + workspace + área de trabajo + + + Yes + + + diff --git a/tools/linguist/phrasebooks/swedish.qph b/tools/linguist/phrasebooks/swedish.qph new file mode 100644 index 0000000..9c44071 --- /dev/null +++ b/tools/linguist/phrasebooks/swedish.qph @@ -0,0 +1,1010 @@ + + + About + Om + + + access key + snabbtangent + + + accessibility + Hjälpmedel + ikonen Accessibility + + + accessibility + tillgänglighet + + + action handle + funktionshandtag + + + active + aktiv + + + active end + aktiv slutpunkt + + + active object + aktivt objekt + + + active window + aktivt fönster + + + adornment + fönsterfält + + + Always on Top + Alltid överst + + + anchor point + startpunkt + + + Apply + Verkställ + + + auto-exit + flytta automatiskt + + + auto-repeat + upprepa automatiskt + + + automatic link + automatisk länk + + + automatic scrolling + automatisk rullning + + + autoscroll + automatisk rullning + + + Back + Föregående + + + Browse + Bläddra + + + Cancel + Avbryt + + + cascading menu + undermeny + + + check box + kryssruta + + + check mark + markering + + + child window + underfönster + + + choose + välj + + + click + klicka + + + Clipboard + Urklipp + + + Close + Stäng + + + Close button + stängningsknapp + + + collapse + komprimera + outline + + + column heading + kolumnrubrik + control + + + combo box + kombinationsruta + + + command button + kommandoknapp + + + container + behållare + + + context-sensitive Help + sammanhangsberoende hjälp + + + contextual + sammanhangsberoende + + + control + kontroll + + + Copy + Kopiera + + + Copy here + Kopiera hit + + + Create Shortcut + Skapa genväg + + + Create Shortcut Here + Skapa genväg här + + + Cut + Klipp ut + + + default + standard + + + default button + standardknapp + + + Delete + Ta bort + + + desktop + skrivbord + + + destination + mål + + + dialog box + dialogruta + + + disability + oförmåga + + + disjoint selection + osammanhängande markering + + + dock + docka + + + document + dokument + + + double-click + dubbelklicka på + + + drag + dra + + + drag-and-drop + dra och släpp + + + drop-down combo box + nedrullningsbar kombinationsruta + + + drop-down list box + nedrullningsbar listruta + + + drop-down menu + nedrullningsbar meny + + + Edit + Redigera + + + ellipsis + punkter + + + embedded object + inbäddat objekt + + + Exit + Avsluta + + + expand + expandera + an outline + + + Explore + Utforska + + + extended selection + utökad markering + + + extended selection list box + listruta för utökad markering + + + File + Arkiv + menu/meny + + + file + fil + + + Find + Sök + + + Find Next + Sök nästa + + + Find What + Sök efter + + + folder + mapp + + + font + teckensnitt + + + font size + teckenstorlek + + + font style + teckenstil + + + function key + funktionstangent + + + group box + gruppruta + + + handle + handtag + + + Help + Hjälp + + + Hide + Dölj + + + hierarchical selection + hierarkisk markering + + + hold + hålla ned + + + hot spot + aktiv punkt + + + hot zone + aktiveringszon + + + icon + ikon + + + inactive + inaktiv + + + inactive window + inaktivt fönster + + + input focus + inmatningsfokus + + + Insert + Infoga-meny + + + Insert Object + Infoga objekt + + + insertion point + insättningspunkt + + + italic + kursiv + + + label + titel + + + landscape + liggande + + + link + länk + noun + + + link + länka + verb + + + Link Here + Länka hit + + + list box + listruta + + + list view + listvy + control + + + manual link + manuell länk + + + Maximize + Maximera + + + maximize button + maximeringsknapp + + + MDI + MDI + + + menu + meny + + + menu bar + menyrad + + + menu button + menyknapp + + + menu item + menyobjekt + + + menu title + menytitel + + + message box + meddelanderuta + + + Minimize + Minimera + + + minimize button + minimeringsknapp + + + mixed-value + blandvärde + + + modal + modal + + + mode + läge + + + modeless + icke-modal + + + modifier key + ändringstangent + + + mouse + mus + + + Move + Flytta + + + Move Here + Flytta hit + + + Multiple Document Interface + multiple document interface + + + multiple selection list box + listruta för multipel markering + + + My Computer + Den här datorn + icon + + + Network Neighborhood + Nätverket + icon + + + New + Ny + + + New + Nytt + + + Next + Nästa + + + object + objekt + + + OK + OK + + + OLE + OLE + + + OLE drag and drop + dra och släpp (OLE) + + + OLE embedded object + inbäddat objekt (OLE) + + + OLE linked object + länkat objekt (OLE) + + + OLE nondefault drag and drop + utökat drag och släpp (OLE) + + + Open + Öppna + + + Open With + Öppna med + + + option button + alternativknapp + + + option-set + valt alternativ + + + package + paket + + + Page Setup + Utskriftsformat + + + palette window + palettfönster + + + pane + fönsterruta + + + parent window + moderfönster + + + password + lösenord + + + Paste + Klistra in + + + Paste Link + Klistra in länk + + + Paste Shortcut + Klistra in genväg + + + Paste Special + Klistra in special + + + path + sökväg + + + Pause + Paus + + + Play + Spela upp + + + Plug and Play + Plug and Play + + + point + peka + + + pointer + pekare + + + pop-up menu + pop up-meny + + + pop-up window + pop up-fönster + + + portrait + stående + + + press + håll ned + and hold a mouse button + + + press + tryck på + a key + + + primary container + primär behållare + + + primary window + primärt fönster + + + Print + Skriv ut + + + printer + skrivare + + + progress indicator + förloppsindikator + control + + + project + projekt + + + Properties + Egenskaper + + + property inspector + egenskapsgranskare + + + property page + egenskapssida + + + property sheet + egenskapsförteckning + + + property sheet control + kontroll i egenskapsförteckning + + + Quick View + Snabbgranskning + + + read-only + skrivskydd + + + Recycle Bin + Papperskorgen + Icon + + + Redo + Gör om + + + region selection + områdesmarkering + + + registry + Registret + + + Repeat + Upprepa + + + Replace + Ersätt + + + Restore + Återställ + + + Restore button + knappen Återställ + + + Resume + Fortsätt + + + Retry + Försök igen + + + rich-text box + rich text-ruta + + + Run + Kör + + + Save + Spara + + + Save as + Spara som + + + scroll + rulla + + + scroll arrow + rullningspil + + + scroll bar + rullningslist + + + scroll box + rullningsruta + + + secondary window + sekundärt fönster + + + select + markera + + + Select All + Markera allt + + + selection + markering + + + selection handle + markeringshandtag + + + Send To + Skicka till + + + separator + avgränsare + + + Settings + Inställningar + + + Setup + installationsprogram + + + Setup + Inställningar + + + shortcut + genväg + + + shortcut button + genvägsknapp + + + shortcut icon + genvägsikon + + + shortcut key + kortkommando + + + shortcut key control + kortkommandokontroll + + + Show + Visa + + + Shutdown + Avsluta + + + single selection list box + listruta för enkel markering + + + Size + Ändra storlek + + + Size + Storlek + + + size grip + storleksgrepp + + + slider + skjutreglage + + + spin box + rotationsruta + + + Split + Dela + + + split bar + delningslist + + + split box + delningsruta + + + Start button + startknappen + + + StartUp folder + mappen Autostart + + + status bar + statusfält + + + Stop + Stanna + + + tab control + flik + + + task bar + Aktivitetsfältet + + + task-oriented Help + aktivitetsberoende hjälp + + + template + mall + + + text box + textruta + + + title bar + namnlist + + + title text + text i namnlist + + + toggle key + växlingstangent + + + toolbar + verktygsfält + + + tooltip + funktionsbeskrivning + + + tree view control + trädkontroll + + + type + typ + noun + + + type + skriva + verb + + + unavailable + ej tillgänglig + + + Undo + Ångra + + + Uninstall + Avinstallera + + + View + Visa-meny + + + visual editing + direktredigering + + + well control + grafikkontroll + + + What's This? + Förklaring + + + Window + Fönster-meny + + + window + fönster + + + Windows Explorer + Utforskaren + + + wizard + guide + + + workbook + arbetsbok + + + workgroup + arbetsgrupp + + + workspace + arbetsyta + + + Yes + Ja + + diff --git a/tools/linguist/qdoc.conf b/tools/linguist/qdoc.conf new file mode 100644 index 0000000..a89fb64 --- /dev/null +++ b/tools/linguist/qdoc.conf @@ -0,0 +1,15 @@ +SOURCEDIRS = $QTDIR/tools/linguist/doc +DOCDIRS = $QTDIR/tools/linguist/doc +EXAMPLEDIRS = $QTDIR/tools/linguist/tutorial +OUTPUTDIR = $QTDIR/tools/linguist/doc/html +BASE = file:$QTDIR/tools/linguist/doc/html/ +COMPANY = Trolltech +PRODUCT = Qt Linguist +VERSIONSYM = QT_VERSION_STR +DEFINE = QT_QDOC QT_.*_SUPPORT _WS_.*_ +FALSE = 0 1 +INTERNAL = no +STYLE = "h3.fn,span.fn { margin-left: 1cm; text-indent: -1cm; } +a:link { color: #af4f00; text-decoration: none } +a:visited { color: #8f2f00; text-decoration: none } +body { background: #ffffff; color: black; }" diff --git a/tools/linguist/qm2ts/main.cpp b/tools/linguist/qm2ts/main.cpp new file mode 100644 index 0000000..e04c99c --- /dev/null +++ b/tools/linguist/qm2ts/main.cpp @@ -0,0 +1,128 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +#include +#include +#include + +typedef QValueList TML; + +static void printUsage() +{ + fprintf( stderr, "Usage:\n" + " qm2ts [ options ] qm-files\n" + "Options:\n" + " -help Display this information and exit\n" + " -verbose\n" + " Explain what is being done\n" + " -version\n" + " Display the version of qm2ts and exit\n" ); +} + +int main( int argc, char **argv ) +{ + bool verbose = FALSE; + int numQmFiles = 0; + + for ( int i = 1; i < argc; i++ ) { + if ( qstrcmp(argv[i], "-help") == 0 ) { + printUsage(); + return 0; + } else if ( qstrcmp(argv[i], "-verbose") == 0 ) { + verbose = TRUE; + continue; + } else if ( qstrcmp(argv[i], "-version") == 0 ) { + fprintf( stderr, "qm2ts version %s\n", QT_VERSION_STR ); + return 0; + } + + numQmFiles++; + QTranslator tor( 0 ); + if ( tor.load(argv[i], ".") ) { + QString g = argv[i]; + g.replace( QRegExp(QString("\\.qm$")), QString::null ); + g += QString( ".ts" ); + + if ( verbose ) + fprintf( stderr, "Generating '%s'...\n", g.latin1() ); + + MetaTranslator metator; + int ignored = 0; + + TML all = tor.messages(); + TML::Iterator it; + for ( it = all.begin(); it != all.end(); ++it ) { + if ( (*it).sourceText() == 0 ) { + ignored++; + } else { + QCString context = (*it).context(); + if ( context.isEmpty() ) + context = "@default"; + metator.insert( MetaTranslatorMessage(context, + (*it).sourceText(), (*it).comment(), + (*it).translation(), FALSE, + MetaTranslatorMessage::Finished) ); + } + } + + if ( !metator.save(g) ) { + fprintf( stderr, + "qm2ts warning: For some reason, I cannot save '%s'\n", + g.latin1() ); + } else { + if ( verbose ) { + int converted = (int) metator.messages().count(); + fprintf( stderr, " %d message%s converted (%d ignored)\n", + converted, converted == 1 ? "" : "s", ignored ); + } + if ( ignored > 0 ) + fprintf( stderr, + "qm2ts warning: File '%s' is not a Qt 2.x .qm" + " file (some information is lost)\n", + argv[i] ); + } + } else { + fprintf( stderr, + "qm2ts warning: For some reason, I cannot load '%s'\n", + argv[i] ); + } + } + + if ( numQmFiles == 0 ) { + printUsage(); + return 1; + } + return 0; +} diff --git a/tools/linguist/qm2ts/qm2ts.1 b/tools/linguist/qm2ts/qm2ts.1 new file mode 100644 index 0000000..e1eb472 --- /dev/null +++ b/tools/linguist/qm2ts/qm2ts.1 @@ -0,0 +1,55 @@ +.TH qm2ts 1 "18 October 2001" "Trolltech AS" \" -*- nroff -*- +.\" +.\" Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +.\" +.\" This file is part of Qt and may be distributed and used according to +.\" the terms and conditions described in the LICENSE file. +.\" +.SH NAME +qm2ts \- generate Qt Linguist translation files from Qt 2.x message files +.SH SYNOPSIS +.B qm2ts +.RI "[ " options " ] " qm-files +.SH DESCRIPTION +This page documents the +.B Qt Linguist Qm2ts +tool for the Qt GUI toolkit. +.B Qm2ts +converts Qt 2.x message files (.qm files) into source message files +(.ts files). +.PP +The .ts file format is a simple human-readable XML format that can be +used with version control systems if required. It is understood by +.B lupdate, +.B lrelease +and +.B Qt Linguist. +.PP +.B qm2ts +is provided to ease porting from the old internationalization +tools +.B (findtr, +.B mergetr +and +.B msg2qm) +to the new ones. It will not accept Qt message files generated by +.B lrelease, +as +.B lrelease +compresses .qm files by stripping unnecessary information for lookup. +.SH OPTIONS +.TP +.I "-help" +Display the usage and exit. +.TP +.I "-verbose" +Explain what is being done. +.TP +.I "-version" +Display the version of +.B qm2ts +and exit. +.SH "SEE ALSO" +.BR http://doc.trolltech.com/i18n.html +.SH AUTHOR +Jasmin Blanchette, Trolltech ASA diff --git a/tools/linguist/qm2ts/qm2ts.pro b/tools/linguist/qm2ts/qm2ts.pro new file mode 100644 index 0000000..3868e30 --- /dev/null +++ b/tools/linguist/qm2ts/qm2ts.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +CONFIG += qt warn_on console +HEADERS = ../shared/metatranslator.h +SOURCES = main.cpp \ + ../shared/metatranslator.cpp + +DEFINES += QT_INTERNAL_XML +include( ../../../src/qt_professional.pri ) + +TARGET = qm2ts +INCLUDEPATH += ../shared +DESTDIR = ../../../bin + +target.path=$$bins.path +INSTALLS += target diff --git a/tools/linguist/shared/metatranslator.cpp b/tools/linguist/shared/metatranslator.cpp new file mode 100644 index 0000000..85f6199 --- /dev/null +++ b/tools/linguist/shared/metatranslator.cpp @@ -0,0 +1,601 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "metatranslator.h" + +#include +#include +#include +#include +#include +#include +#include + +static bool encodingIsUtf8( const QXmlAttributes& atts ) +{ + for ( int i = 0; i < atts.length(); i++ ) { + // utf8="true" is a pre-3.0 syntax + if ( atts.qName(i) == QString("utf8") ) { + return ( atts.value(i) == QString("true") ); + } else if ( atts.qName(i) == QString("encoding") ) { + return ( atts.value(i) == QString("UTF-8") ); + } + } + return FALSE; +} + +class TsHandler : public QXmlDefaultHandler +{ +public: + TsHandler( MetaTranslator *translator ) + : tor( translator ), type( MetaTranslatorMessage::Finished ), + inMessage( FALSE ), ferrorCount( 0 ), contextIsUtf8( FALSE ), + messageIsUtf8( FALSE ) { } + + virtual bool startElement( const QString& namespaceURI, + const QString& localName, const QString& qName, + const QXmlAttributes& atts ); + virtual bool endElement( const QString& namespaceURI, + const QString& localName, const QString& qName ); + virtual bool characters( const QString& ch ); + virtual bool fatalError( const QXmlParseException& exception ); + +private: + MetaTranslator *tor; + MetaTranslatorMessage::Type type; + bool inMessage; + QString context; + QString source; + QString comment; + QString translation; + + QString accum; + int ferrorCount; + bool contextIsUtf8; + bool messageIsUtf8; +}; + +bool TsHandler::startElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName, + const QXmlAttributes& atts ) +{ + if ( qName == QString("byte") ) { + for ( int i = 0; i < atts.length(); i++ ) { + if ( atts.qName(i) == QString("value") ) { + QString value = atts.value( i ); + int base = 10; + if ( value.startsWith("x") ) { + base = 16; + value = value.mid( 1 ); + } + int n = value.toUInt( 0, base ); + if ( n != 0 ) + accum += QChar( n ); + } + } + } else { + if ( qName == QString("context") ) { + context.truncate( 0 ); + source.truncate( 0 ); + comment.truncate( 0 ); + translation.truncate( 0 ); + contextIsUtf8 = encodingIsUtf8( atts ); + } else if ( qName == QString("message") ) { + inMessage = TRUE; + type = MetaTranslatorMessage::Finished; + source.truncate( 0 ); + comment.truncate( 0 ); + translation.truncate( 0 ); + messageIsUtf8 = encodingIsUtf8( atts ); + } else if ( qName == QString("translation") ) { + for ( int i = 0; i < atts.length(); i++ ) { + if ( atts.qName(i) == QString("type") ) { + if ( atts.value(i) == QString("unfinished") ) + type = MetaTranslatorMessage::Unfinished; + else if ( atts.value(i) == QString("obsolete") ) + type = MetaTranslatorMessage::Obsolete; + else + type = MetaTranslatorMessage::Finished; + } + } + } + accum.truncate( 0 ); + } + return TRUE; +} + +bool TsHandler::endElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName ) +{ + if ( qName == QString("codec") || qName == QString("defaultcodec") ) { + // "codec" is a pre-3.0 syntax + tor->setCodec( accum ); + } else if ( qName == QString("name") ) { + context = accum; + } else if ( qName == QString("source") ) { + source = accum; + } else if ( qName == QString("comment") ) { + if ( inMessage ) { + comment = accum; + } else { + if ( contextIsUtf8 ) + tor->insert( MetaTranslatorMessage(context.utf8(), + ContextComment, + accum.utf8(), QString::null, TRUE, + MetaTranslatorMessage::Unfinished) ); + else + tor->insert( MetaTranslatorMessage(context.ascii(), + ContextComment, + accum.ascii(), QString::null, FALSE, + MetaTranslatorMessage::Unfinished) ); + } + } else if ( qName == QString("translation") ) { + translation = accum; + } else if ( qName == QString("message") ) { + if ( messageIsUtf8 ) + tor->insert( MetaTranslatorMessage(context.utf8(), source.utf8(), + comment.utf8(), translation, + TRUE, type) ); + else + tor->insert( MetaTranslatorMessage(context.ascii(), source.ascii(), + comment.ascii(), translation, + FALSE, type) ); + inMessage = FALSE; + } + return TRUE; +} + +bool TsHandler::characters( const QString& ch ) +{ + QString t = ch; + t.replace( "\r", "" ); + accum += t; + return TRUE; +} + +bool TsHandler::fatalError( const QXmlParseException& exception ) +{ + if ( ferrorCount++ == 0 ) { + QString msg; + msg.sprintf( "Parse error at line %d, column %d (%s).", + exception.lineNumber(), exception.columnNumber(), + exception.message().latin1() ); + if ( qApp == 0 ) + fprintf( stderr, "XML error: %s\n", msg.latin1() ); + else + QMessageBox::information( qApp->mainWidget(), + QObject::tr("Qt Linguist"), msg ); + } + return FALSE; +} + +static QString numericEntity( int ch ) +{ + return QString( ch <= 0x20 ? "" : "&#x%1;" ) + .arg( ch, 0, 16 ); +} + +static QString protect( const QCString& str ) +{ + QString result; + int len = (int) str.length(); + for ( int k = 0; k < len; k++ ) { + switch( str[k] ) { + case '\"': + result += QString( """ ); + break; + case '&': + result += QString( "&" ); + break; + case '>': + result += QString( ">" ); + break; + case '<': + result += QString( "<" ); + break; + case '\'': + result += QString( "'" ); + break; + default: + if ( (uchar) str[k] < 0x20 && str[k] != '\n' ) + result += numericEntity( (uchar) str[k] ); + else + result += str[k]; + } + } + return result; +} + +static QString evilBytes( const QCString& str, bool utf8 ) +{ + if ( utf8 ) { + return protect( str ); + } else { + QString result; + QCString t = protect( str ).latin1(); + int len = (int) t.length(); + for ( int k = 0; k < len; k++ ) { + if ( (uchar) t[k] >= 0x7f ) + result += numericEntity( (uchar) t[k] ); + else + result += QChar( t[k] ); + } + return result; + } +} + +MetaTranslatorMessage::MetaTranslatorMessage() + : utfeight( FALSE ), ty( Unfinished ) +{ +} + +MetaTranslatorMessage::MetaTranslatorMessage( const char *context, + const char *sourceText, + const char *comment, + const QString& translation, + bool utf8, Type type ) + : QTranslatorMessage( context, sourceText, comment, translation ), + utfeight( FALSE ), ty( type ) +{ + /* + Don't use UTF-8 if it makes no difference. UTF-8 should be + reserved for the real problematic case: non-ASCII (possibly + non-Latin-1) characters in .ui files. + */ + if ( utf8 ) { + if ( sourceText != 0 ) { + int i = 0; + while ( sourceText[i] != '\0' ) { + if ( (uchar) sourceText[i] >= 0x80 ) { + utfeight = TRUE; + break; + } + i++; + } + } + if ( !utfeight && comment != 0 ) { + int i = 0; + while ( comment[i] != '\0' ) { + if ( (uchar) comment[i] >= 0x80 ) { + utfeight = TRUE; + break; + } + i++; + } + } + } +} + +MetaTranslatorMessage::MetaTranslatorMessage( const MetaTranslatorMessage& m ) + : QTranslatorMessage( m ), utfeight( m.utfeight ), ty( m.ty ) +{ +} + +MetaTranslatorMessage& MetaTranslatorMessage::operator=( + const MetaTranslatorMessage& m ) +{ + QTranslatorMessage::operator=( m ); + utfeight = m.utfeight; + ty = m.ty; + return *this; +} + +bool MetaTranslatorMessage::operator==( const MetaTranslatorMessage& m ) const +{ + return qstrcmp( context(), m.context() ) == 0 && + qstrcmp( sourceText(), m.sourceText() ) == 0 && + qstrcmp( comment(), m.comment() ) == 0; +} + +bool MetaTranslatorMessage::operator<( const MetaTranslatorMessage& m ) const +{ + int delta = qstrcmp( context(), m.context() ); + if ( delta == 0 ) + delta = qstrcmp( sourceText(), m.sourceText() ); + if ( delta == 0 ) + delta = qstrcmp( comment(), m.comment() ); + return delta < 0; +} + +MetaTranslator::MetaTranslator() +{ + clear(); +} + +MetaTranslator::MetaTranslator( const MetaTranslator& tor ) + : mm( tor.mm ), codecName( tor.codecName ), codec( tor.codec ) +{ +} + +MetaTranslator& MetaTranslator::operator=( const MetaTranslator& tor ) +{ + mm = tor.mm; + codecName = tor.codecName; + codec = tor.codec; + return *this; +} + +void MetaTranslator::clear() +{ + mm.clear(); + codecName = "ISO-8859-1"; + codec = 0; +} + +bool MetaTranslator::load( const QString& filename ) +{ + QFile f( filename ); + if ( !f.open(IO_ReadOnly) ) + return FALSE; + + QTextStream t( &f ); + QXmlInputSource in( t ); + QXmlSimpleReader reader; + reader.setFeature( "http://xml.org/sax/features/namespaces", FALSE ); + reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", TRUE ); + QXmlDefaultHandler *hand = new TsHandler( this ); + reader.setContentHandler( hand ); + reader.setErrorHandler( hand ); + + bool ok = reader.parse( in ); + reader.setContentHandler( 0 ); + reader.setErrorHandler( 0 ); + delete hand; + f.close(); + return ok; +} + +bool MetaTranslator::save( const QString& filename ) const +{ + QFile f( filename ); + if ( !f.open(IO_WriteOnly) ) + return FALSE; + + QTextStream t( &f ); + t.setCodec( QTextCodec::codecForName("ISO-8859-1") ); + + t << "\n"; + if ( codecName != "ISO-8859-1" ) + t << "" << codecName << "\n"; + TMM::ConstIterator m = mm.begin(); + while ( m != mm.end() ) { + TMMInv inv; + TMMInv::Iterator i; + bool contextIsUtf8 = m.key().utf8(); + QCString context = m.key().context(); + QCString comment = ""; + + do { + if ( QCString(m.key().sourceText()) == ContextComment ) { + if ( m.key().type() != MetaTranslatorMessage::Obsolete ) { + contextIsUtf8 = m.key().utf8(); + comment = QCString( m.key().comment() ); + } + } else { + inv.insert( *m, m.key() ); + } + } while ( ++m != mm.end() && QCString(m.key().context()) == context ); + + t << "\n"; + t << " " << evilBytes( context, contextIsUtf8 ) + << "\n"; + if ( !comment.isEmpty() ) + t << " " << evilBytes( comment, contextIsUtf8 ) + << "\n"; + + for ( i = inv.begin(); i != inv.end(); ++i ) { + // no need for such noise + if ( (*i).type() == MetaTranslatorMessage::Obsolete && + (*i).translation().isEmpty() ) + continue; + + t << " \n" + << " " << evilBytes( (*i).sourceText(), + (*i).utf8() ) + << "\n"; + if ( !QCString((*i).comment()).isEmpty() ) + t << " " << evilBytes( (*i).comment(), + (*i).utf8() ) + << "\n"; + t << " " << protect( (*i).translation().utf8() ) + << "\n"; + t << " \n"; + } + t << "\n"; + } + t << "\n"; + f.close(); + return TRUE; +} + +bool MetaTranslator::release( const QString& filename, bool verbose, + QTranslator::SaveMode mode ) const +{ + QTranslator tor( 0 ); + int finished = 0; + int unfinished = 0; + int untranslated = 0; + TMM::ConstIterator m; + + for ( m = mm.begin(); m != mm.end(); ++m ) { + if ( m.key().type() != MetaTranslatorMessage::Obsolete ) { + if ( m.key().translation().isEmpty() ) { + untranslated++; + } else { + if ( m.key().type() == MetaTranslatorMessage::Unfinished ) + unfinished++; + else + finished++; + + QCString context = m.key().context(); + QCString sourceText = m.key().sourceText(); + QCString comment = m.key().comment(); + QString translation = m.key().translation(); + + /* + Drop the comment in (context, sourceText, comment), + unless (context, sourceText, "") already exists, or + unless we already dropped the comment of (context, + sourceText, comment0). + */ + if ( comment.isEmpty() + || contains(context, sourceText, "") + || !tor.findMessage(context, sourceText, "").translation() + .isNull() ) { + tor.insert( m.key() ); + } else { + tor.insert( QTranslatorMessage(context, sourceText, "", + translation) ); + } + } + } + } + + bool saved = tor.save( filename, mode ); + if ( saved && verbose ) + fprintf( stderr, + " %d finished, %d unfinished and %d untranslated messages\n", + finished, unfinished, untranslated ); + + return saved; +} + +bool MetaTranslator::contains( const char *context, const char *sourceText, + const char *comment ) const +{ + return mm.find( MetaTranslatorMessage(context, sourceText, comment) ) != + mm.end(); +} + +void MetaTranslator::insert( const MetaTranslatorMessage& m ) +{ + int pos = (int)mm.count(); + TMM::Iterator n = mm.find( m ); + if ( n != mm.end() ) + pos = *n; + mm.replace( m, pos ); +} + +void MetaTranslator::stripObsoleteMessages() +{ + TMM newmm; + + TMM::Iterator m = mm.begin(); + while ( m != mm.end() ) { + if ( m.key().type() != MetaTranslatorMessage::Obsolete ) + newmm.insert( m.key(), *m ); + ++m; + } + mm = newmm; +} + +void MetaTranslator::stripEmptyContexts() +{ + TMM newmm; + + TMM::Iterator m = mm.begin(); + while ( m != mm.end() ) { + if ( QCString(m.key().sourceText()) == ContextComment ) { + TMM::Iterator n = m; + ++n; + // the context comment is followed by other messages + if ( n != newmm.end() && + qstrcmp(m.key().context(), n.key().context()) == 0 ) + newmm.insert( m.key(), *m ); + } else { + newmm.insert( m.key(), *m ); + } + ++m; + } + mm = newmm; +} + +void MetaTranslator::setCodec( const char *name ) +{ + const int latin1 = 4; + + codecName = name; + codec = QTextCodec::codecForName( name ); + if ( codec == 0 || codec->mibEnum() == latin1 ) + codec = 0; +} + +QString MetaTranslator::toUnicode( const char *str, bool utf8 ) const +{ + if ( utf8 ) + return QString::fromUtf8( str ); + else if ( codec == 0 ) + return QString( str ); + else + return codec->toUnicode( str ); +} + +QValueList MetaTranslator::messages() const +{ + int n = (int)mm.count(); + TMM::ConstIterator *t = new TMM::ConstIterator[n + 1]; + TMM::ConstIterator m; + for ( m = mm.begin(); m != mm.end(); ++m ) + t[*m] = m; + + QValueList val; + for ( int i = 0; i < n; i++ ) + val.append( t[i].key() ); + + delete[] t; + return val; +} + +QValueList MetaTranslator::translatedMessages() const +{ + QValueList val; + TMM::ConstIterator m; + for ( m = mm.begin(); m != mm.end(); ++m ) { + if ( m.key().type() == MetaTranslatorMessage::Finished ) + val.append( m.key() ); + } + return val; +} diff --git a/tools/linguist/shared/metatranslator.h b/tools/linguist/shared/metatranslator.h new file mode 100644 index 0000000..25adfb0 --- /dev/null +++ b/tools/linguist/shared/metatranslator.h @@ -0,0 +1,120 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef METATRANSLATOR_H +#define METATRANSLATOR_H + +#include +#include +#include +#include + +class QTextCodec; + +class MetaTranslatorMessage : public QTranslatorMessage +{ +public: + enum Type { Unfinished, Finished, Obsolete }; + + MetaTranslatorMessage(); + MetaTranslatorMessage( const char *context, const char *sourceText, + const char *comment, + const QString& translation = QString::null, + bool utf8 = FALSE, Type type = Unfinished ); + MetaTranslatorMessage( const MetaTranslatorMessage& m ); + + MetaTranslatorMessage& operator=( const MetaTranslatorMessage& m ); + + void setType( Type nt ) { ty = nt; } + Type type() const { return ty; } + bool utf8() const { return utfeight; } + + bool operator==( const MetaTranslatorMessage& m ) const; + bool operator!=( const MetaTranslatorMessage& m ) const + { return !operator==( m ); } + bool operator<( const MetaTranslatorMessage& m ) const; + bool operator<=( const MetaTranslatorMessage& m ) + { return !operator>( m ); } + bool operator>( const MetaTranslatorMessage& m ) const + { return this->operator<( m ); } + bool operator>=( const MetaTranslatorMessage& m ) const + { return !operator<( m ); } + +private: + bool utfeight; + Type ty; +}; + +class MetaTranslator +{ +public: + MetaTranslator(); + MetaTranslator( const MetaTranslator& tor ); + + MetaTranslator& operator=( const MetaTranslator& tor ); + + void clear(); + bool load( const QString& filename ); + bool save( const QString& filename ) const; + bool release( const QString& filename, bool verbose = FALSE, + QTranslator::SaveMode mode = QTranslator::Stripped ) const; + + bool contains( const char *context, const char *sourceText, + const char *comment ) const; + void insert( const MetaTranslatorMessage& m ); + + void stripObsoleteMessages(); + void stripEmptyContexts(); + + void setCodec( const char *name ); + QString toUnicode( const char *str, bool utf8 ) const; + + QValueList messages() const; + QValueList translatedMessages() const; + +private: + typedef QMap TMM; + typedef QMap TMMInv; + + TMM mm; + QCString codecName; + QTextCodec *codec; +}; + +/* + This is a quick hack. The proper way to handle this would be + to extend MetaTranslator's interface. +*/ +#define ContextComment "QT_LINGUIST_INTERNAL_CONTEXT_COMMENT" + +#endif diff --git a/tools/linguist/shared/proparser.cpp b/tools/linguist/shared/proparser.cpp new file mode 100644 index 0000000..7528361 --- /dev/null +++ b/tools/linguist/shared/proparser.cpp @@ -0,0 +1,217 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "proparser.h" + +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_UNIX +#include +#endif + +#ifdef Q_OS_WIN32 +#define QT_POPEN _popen +#else +#define QT_POPEN popen +#endif + +QString loadFile( const QString &fileName ) +{ + QFile file( fileName ); + if ( !file.open(IO_ReadOnly) ) { + fprintf( stderr, "error: Cannot load '%s': %s\n", + file.name().latin1(), + file.errorString().latin1() ); + return QString(); + } + + QTextStream in( &file ); + return in.read(); +} + +QMap proFileTagMap( const QString& text ) +{ + QString t = text; + QMap tagMap; + bool stillProcess = true; // If include() has a $$tag then we need to reprocess + + while(stillProcess) { + + /* + Strip any commments before we try to include. We + still need to do it after we include to make sure the + included file does not have comments + */ + t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") ); + + /* + Process include() commands. + $$PWD is a special case so we have to change it while + we know where the included file is. + */ + QRegExp callToInclude("include\\s*\\(\\s*([^()\\s]+)\\s*\\)"); + int i = 0; + while ( (i = callToInclude.search(t, i)) != -1 ) { + bool doneWithVar = false; + QString fileName = callToInclude.cap(1); + QString after = fileName.replace("$$PWD", QDir::currentDirPath()); + if (!tagMap.isEmpty() && after.contains("$$")) { + QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" ); + int ii = 0; + while ((ii = after.find(var, ii)) != -1) { + if (tagMap.contains(var.cap(1))) { + after.replace(ii, var.cap(0).length(), tagMap[var.cap(1)]); + } else { // Couldn't find it + doneWithVar = true; + break; + } + } + + } + if (doneWithVar || !after.contains("$$")) { + after = loadFile(after); + QFileInfo fi(callToInclude.cap(1)); + after.replace("$$PWD", fi.dirPath()); + t.replace( i, callToInclude.matchedLength(), after ); + } + i += after.length(); + } + + /* + Strip comments, merge lines ending with backslash, add + spaces around '=' and '+=', replace '\n' with ';', and + simplify white spaces. + */ + t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") ); + t.replace( QRegExp(QString("\\\\[^\n\\S]*\n")), QString(" ") ); + t.replace( "=", QString(" = ") ); + t.replace( "+ =", QString(" += ") ); + t.replace( "\n", QString(";") ); + t = t.simplifyWhiteSpace(); + + /* + Populate tagMap with 'key = value' entries. + */ + QStringList lines = QStringList::split( QChar(';'), t ); + QStringList::Iterator line; + for ( line = lines.begin(); line != lines.end(); ++line ) { + QStringList toks = QStringList::split( QChar(' '), *line ); + + if ( toks.count() >= 3 && + (toks[1] == QString("=") || toks[1] == QString("+=")) ) { + QString tag = toks.first(); + int k = tag.findRev( QChar(':') ); // as in 'unix:' + if ( k != -1 ) + tag = tag.mid( k + 1 ); + toks.remove( toks.begin() ); + + QString action = toks.first(); + toks.remove( toks.begin() ); + + if ( tagMap.contains(tag) ) { + if ( action == QString("=") ) + tagMap.replace( tag, toks.join(QChar(' ')) ); + else + tagMap[tag] += QChar( ' ' ) + toks.join( QChar(' ') ); + } else { + tagMap[tag] = toks.join( QChar(' ') ); + } + } + } + + /* + Expand $$variables within the 'value' part of a 'key = value' + pair. + */ + QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" ); + QMap::Iterator it; + for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { + int i = 0; + while ( (i = var.search((*it), i)) != -1 ) { + int len = var.matchedLength(); + QString invocation = var.cap(1); + QString after; + + if ( invocation == "system" ) { + // skip system(); it will be handled in the next pass + ++i; + } else { + if ( tagMap.contains(invocation) ) + after = tagMap[invocation]; + else if (invocation.lower() == "pwd") + after = QDir::currentDirPath(); + (*it).replace( i, len, after ); + i += after.length(); + } + } + } + + /* + Execute system() calls. + */ + QRegExp callToSystem( "\\$\\$system\\s*\\(([^()]*)\\)" ); + for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { + int i = 0; + while ( (i = callToSystem.search((*it), i)) != -1 ) { + /* + This code is stolen from qmake's project.cpp file. + Ideally we would use the same parser, so we wouldn't + have this code duplication. + */ + QString after; + char buff[256]; + FILE *proc = QT_POPEN( callToSystem.cap(1).latin1(), "r" ); + while ( proc && !feof(proc) ) { + int read_in = (int)fread( buff, 1, 255, proc ); + if ( !read_in ) + break; + for ( int i = 0; i < read_in; i++ ) { + if ( buff[i] == '\n' || buff[i] == '\t' ) + buff[i] = ' '; + } + buff[read_in] = '\0'; + after += buff; + } + (*it).replace( i, callToSystem.matchedLength(), after ); + i += after.length(); + } + } + stillProcess = callToInclude.search(t) != -1; + } + return tagMap; +} diff --git a/tools/linguist/shared/proparser.h b/tools/linguist/shared/proparser.h new file mode 100644 index 0000000..7e05090 --- /dev/null +++ b/tools/linguist/shared/proparser.h @@ -0,0 +1,42 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Linguist. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PROPARSER_H +#define PROPARSER_H + +#include +#include + +QMap proFileTagMap( const QString& text ); + +#endif diff --git a/tools/linguist/tutorial/tt1/main.cpp b/tools/linguist/tutorial/tt1/main.cpp new file mode 100644 index 0000000..7d10349 --- /dev/null +++ b/tools/linguist/tutorial/tt1/main.cpp @@ -0,0 +1,25 @@ +/**************************************************************** +** +** Translation tutorial 1 +** +****************************************************************/ + +#include +#include +#include + + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + + QTranslator translator( 0 ); + translator.load( "tt1_la", "." ); + app.installTranslator( &translator ); + + QPushButton hello( QPushButton::tr("Hello world!"), 0 ); + + app.setMainWidget( &hello ); + hello.show(); + return app.exec(); +} diff --git a/tools/linguist/tutorial/tt1/tt1.pro b/tools/linguist/tutorial/tt1/tt1.pro new file mode 100644 index 0000000..3b5249c --- /dev/null +++ b/tools/linguist/tutorial/tt1/tt1.pro @@ -0,0 +1,4 @@ +TEMPLATE = app +CONFIG += qt warn_on +SOURCES = main.cpp +TRANSLATIONS = tt1_la.ts diff --git a/tools/linguist/tutorial/tt2/arrowpad.cpp b/tools/linguist/tutorial/tt2/arrowpad.cpp new file mode 100644 index 0000000..3c0da64 --- /dev/null +++ b/tools/linguist/tutorial/tt2/arrowpad.cpp @@ -0,0 +1,31 @@ +/**************************************************************** +** +** Implementation of ArrowPad class, translation tutorial 2 +** +****************************************************************/ + +#include "arrowpad.h" + +#include + +ArrowPad::ArrowPad( QWidget *parent, const char *name ) + : QGrid( 3, Horizontal, parent, name ) +{ + setMargin( 10 ); + setSpacing( 10 ); + + skip(); + (void) new QPushButton( tr("&Up"), this ); + skip(); + (void) new QPushButton( tr("&Left"), this ); + skip(); + (void) new QPushButton( tr("&Right"), this ); + skip(); + (void) new QPushButton( tr("&Down"), this ); + skip(); +} + +void ArrowPad::skip() +{ + (void) new QWidget( this ); +} diff --git a/tools/linguist/tutorial/tt2/arrowpad.h b/tools/linguist/tutorial/tt2/arrowpad.h new file mode 100644 index 0000000..2fe75c2 --- /dev/null +++ b/tools/linguist/tutorial/tt2/arrowpad.h @@ -0,0 +1,22 @@ +/**************************************************************** +** +** Definition of ArrowPad class, translation tutorial 2 +** +****************************************************************/ + +#ifndef ARROWPAD_H +#define ARROWPAD_H + +#include + +class ArrowPad : public QGrid +{ + Q_OBJECT +public: + ArrowPad( QWidget *parent = 0, const char *name = 0 ); + +private: + void skip(); +}; + +#endif diff --git a/tools/linguist/tutorial/tt2/main.cpp b/tools/linguist/tutorial/tt2/main.cpp new file mode 100644 index 0000000..c0e8b01 --- /dev/null +++ b/tools/linguist/tutorial/tt2/main.cpp @@ -0,0 +1,26 @@ +/**************************************************************** +** +** Translation tutorial 2 +** +****************************************************************/ + +#include "mainwindow.h" + +#include +#include +#include +#include + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + + QTranslator translator( 0 ); + translator.load( QString("tt2_") + QTextCodec::locale(), "." ); + app.installTranslator( &translator ); + + MainWindow *mw = new MainWindow; + app.setMainWidget( mw ); + mw->show(); + return app.exec(); +} diff --git a/tools/linguist/tutorial/tt2/mainwindow.cpp b/tools/linguist/tutorial/tt2/mainwindow.cpp new file mode 100644 index 0000000..e9a1567 --- /dev/null +++ b/tools/linguist/tutorial/tt2/mainwindow.cpp @@ -0,0 +1,26 @@ +/**************************************************************** +** +** Implementation of MainWindow class, translation tutorial 2 +** +****************************************************************/ + +#include "arrowpad.h" +#include "mainwindow.h" + +#include +#include +#include +#include + +MainWindow::MainWindow( QWidget *parent, const char *name ) + : QMainWindow( parent, name ) +{ + ArrowPad *ap = new ArrowPad( this, "arrow pad" ); + setCentralWidget( ap ); + + QPopupMenu *file = new QPopupMenu( this ); + file->insertItem( tr("E&xit"), qApp, SLOT(quit()), + tr("Ctrl+Q", "Quit") ); + menuBar()->insertItem( tr("&File"), file ); + menuBar()->setSeparator( QMenuBar::InWindowsStyle ); +} diff --git a/tools/linguist/tutorial/tt2/mainwindow.h b/tools/linguist/tutorial/tt2/mainwindow.h new file mode 100644 index 0000000..f021869 --- /dev/null +++ b/tools/linguist/tutorial/tt2/mainwindow.h @@ -0,0 +1,19 @@ +/**************************************************************** +** +** Definition of MainWindow class, translation tutorial 2 +** +****************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow( QWidget *parent = 0, const char *name = 0 ); +}; + +#endif diff --git a/tools/linguist/tutorial/tt2/tt2.pro b/tools/linguist/tutorial/tt2/tt2.pro new file mode 100644 index 0000000..8c1ea6d --- /dev/null +++ b/tools/linguist/tutorial/tt2/tt2.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +CONFIG += qt warn_on +HEADERS = arrowpad.h \ + mainwindow.h +SOURCES = arrowpad.cpp \ + main.cpp \ + mainwindow.cpp +TRANSLATIONS = tt2_fr.ts \ + tt2_nl.ts diff --git a/tools/linguist/tutorial/tt3/main.cpp b/tools/linguist/tutorial/tt3/main.cpp new file mode 100644 index 0000000..e5abaf6 --- /dev/null +++ b/tools/linguist/tutorial/tt3/main.cpp @@ -0,0 +1,26 @@ +/**************************************************************** +** +** Translation tutorial 3 +** +****************************************************************/ + +#include "mainwindow.h" + +#include +#include +#include +#include + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + + QTranslator translator( 0 ); + translator.load( QString("tt3_") + QTextCodec::locale(), "." ); + app.installTranslator( &translator ); + + MainWindow *mw = new MainWindow; + app.setMainWidget( mw ); + mw->show(); + return app.exec(); +} diff --git a/tools/linguist/tutorial/tt3/mainwindow.cpp b/tools/linguist/tutorial/tt3/mainwindow.cpp new file mode 100644 index 0000000..6b22bc4 --- /dev/null +++ b/tools/linguist/tutorial/tt3/mainwindow.cpp @@ -0,0 +1,47 @@ +/**************************************************************** +** +** Implementation of MainWindow class, translation tutorial 3 +** +****************************************************************/ + +#include "mainwindow.h" +#include "printpanel.h" + +#include +#include +#include +#include +#include + +MainWindow::MainWindow( QWidget *parent, const char *name ) + : QMainWindow( parent, name ) +{ + setCaption( tr("Troll Print 1.0") ); + + PrintPanel *pp = new PrintPanel( this ); + setCentralWidget( pp ); + + QPopupMenu *file = new QPopupMenu( this ); + file->insertItem( tr("E&xit"), qApp, SLOT(quit()), + tr("Ctrl+Q", "Quit") ); + QPopupMenu *help = new QPopupMenu( this ); + help->insertItem( tr("&About"), this, SLOT(about()), Key_F1 ); + help->insertItem( tr("About &Qt"), this, SLOT(aboutQt()) ); + + menuBar()->insertItem( tr("&File"), file ); + menuBar()->insertSeparator(); + menuBar()->insertItem( tr("&Help"), help ); + menuBar()->setSeparator( QMenuBar::InWindowsStyle ); +} + +void MainWindow::about() +{ + QMessageBox::information( this, tr("About Troll Print 1.0"), + tr("Troll Print 1.0.\n\n" + "Copyright 1999 Macroshaft, Inc.") ); +} + +void MainWindow::aboutQt() +{ + QMessageBox::aboutQt( this ); +} diff --git a/tools/linguist/tutorial/tt3/mainwindow.h b/tools/linguist/tutorial/tt3/mainwindow.h new file mode 100644 index 0000000..77f23f8 --- /dev/null +++ b/tools/linguist/tutorial/tt3/mainwindow.h @@ -0,0 +1,23 @@ +/**************************************************************** +** +** Definition of MainWindow class, translation tutorial 3 +** +****************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow( QWidget *parent = 0, const char *name = 0 ); + +private slots: + void about(); + void aboutQt(); +}; + +#endif diff --git a/tools/linguist/tutorial/tt3/printpanel.cpp b/tools/linguist/tutorial/tt3/printpanel.cpp new file mode 100644 index 0000000..5cbd468 --- /dev/null +++ b/tools/linguist/tutorial/tt3/printpanel.cpp @@ -0,0 +1,37 @@ +/**************************************************************** +** +** Implementation of PrintPanel class, translation tutorial 3 +** +****************************************************************/ + +#include "printpanel.h" + +#include +#include +#include + +PrintPanel::PrintPanel( QWidget *parent, const char *name ) + : QVBox( parent, name ) +{ + setMargin( 10 ); + setSpacing( 10 ); + +/* + QLabel *lab = new QLabel( tr("TROLL PRINT"), this ); + lab->setAlignment( AlignCenter ); +*/ + + QRadioButton *but; + + QHButtonGroup *twoSided = new QHButtonGroup( this ); + twoSided->setTitle( tr("2-sided") ); + but = new QRadioButton( tr("Enabled"), twoSided ); + but = new QRadioButton( tr("Disabled"), twoSided ); + but->toggle(); + + QHButtonGroup *colors = new QHButtonGroup( this ); + colors->setTitle( tr("Colors") ); + but = new QRadioButton( tr("Enabled"), colors ); + but = new QRadioButton( tr("Disabled"), colors ); + but->toggle(); +} diff --git a/tools/linguist/tutorial/tt3/printpanel.h b/tools/linguist/tutorial/tt3/printpanel.h new file mode 100644 index 0000000..0110c52 --- /dev/null +++ b/tools/linguist/tutorial/tt3/printpanel.h @@ -0,0 +1,19 @@ +/**************************************************************** +** +** Definition of PrintPanel class, translation tutorial 3 +** +****************************************************************/ + +#ifndef PRINTPANEL_H +#define PRINTPANEL_H + +#include + +class PrintPanel : public QVBox +{ + Q_OBJECT +public: + PrintPanel( QWidget *parent = 0, const char *name = 0 ); +}; + +#endif diff --git a/tools/linguist/tutorial/tt3/tt3.pro b/tools/linguist/tutorial/tt3/tt3.pro new file mode 100644 index 0000000..c219d1e --- /dev/null +++ b/tools/linguist/tutorial/tt3/tt3.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +CONFIG += qt warn_on +HEADERS = mainwindow.h \ + printpanel.h +SOURCES = main.cpp \ + mainwindow.cpp \ + printpanel.cpp +TRANSLATIONS = tt3_pt.ts diff --git a/tools/linguist/tutorial/tt3/tt3_pt.ts b/tools/linguist/tutorial/tt3/tt3_pt.ts new file mode 100644 index 0000000..cf8ff4f --- /dev/null +++ b/tools/linguist/tutorial/tt3/tt3_pt.ts @@ -0,0 +1,65 @@ + + + MainWindow + + Troll Print 1.0 + Troll Imprimir 1.0 + + + E&xit + &Sair + + + &About + &Sobre + + + About &Qt + Sobre &Qt + + + &File + &Arquivo + + + &Help + A&juda + + + About Troll Print 1.0 + Sobre Troll Imprimir 1.0 + + + Troll Print 1.0. + +Copyright 1999 Macroshaft, Inc. + Troll Imprimir 1.0 + +Copyright 1999 Macroshaft, Inc. + + + Ctrl+Q + Quit + Ctrl+Q + + + + PrintPanel + + 2-sided + 2-lados + + + Enabled + Ativado + + + Disabled + Desativado + + + Colors + Cores + + + diff --git a/tools/makeqpf/main.cpp b/tools/makeqpf/main.cpp new file mode 100644 index 0000000..0dceee3 --- /dev/null +++ b/tools/makeqpf/main.cpp @@ -0,0 +1,320 @@ +/********************************************************************** +** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef Q_WS_QWS +#include +#endif + +#include + + +class FontViewItem : public QListViewItem { + QString family; + int pointSize; + int weight; + bool italic; + QFont font; + +public: + FontViewItem(const QString& f, int pt, int w, bool ital, QListView* parent) : + QListViewItem(parent), + family(f), pointSize(pt), weight(w), italic(ital) + { + } + + void renderAndSave() + { + font = QFont(family,pointSize,weight,italic); +#ifdef Q_WS_QWS + memorymanager->savePrerenderedFont((QMemoryManager::FontID)font.handle()); +#endif + setHeight(QFontMetrics(font).lineSpacing()); + repaint(); + } + + void render(int from, int to) + { + font = QFont(family,pointSize,weight,italic); +#ifdef Q_WS_QWS + for (int i=from; i<=to; i++) { + if ( memorymanager->inFont((QMemoryManager::FontID)font.handle(),QChar(i))) { + memorymanager->lockGlyph((QMemoryManager::FontID)font.handle(),QChar(i)); + memorymanager->unlockGlyph((QMemoryManager::FontID)font.handle(),QChar(i)); + } + } +#endif + } + + void save() + { + font = QFont(family,pointSize,weight,italic); +#ifdef Q_WS_QWS + memorymanager->savePrerenderedFont((QMemoryManager::FontID)font.handle(),FALSE); +#endif + setHeight(QFontMetrics(font).lineSpacing()); + repaint(); + } + + void paintCell( QPainter *p, const QColorGroup & cg, + int column, int width, int alignment ) + { + p->setFont(font); + QListViewItem::paintCell(p,cg,column,width,alignment); + } + + int width( const QFontMetrics&, + const QListView* lv, int column) const + { + QFontMetrics fm(font); + return QListViewItem::width(fm,lv,column); + } + + QString text(int col) const + { + switch (col) { + case 0: + return family; + case 1: + return QString::number(pointSize)+"pt"; + case 2: + if ( weight < QFont::Normal ) { + return "Light"; + } else if ( weight >= QFont::Black ) { + return "Black"; + } else if ( weight >= QFont::Bold ) { + return "Bold"; + } else if ( weight >= QFont::DemiBold ) { + return "DemiBold"; + } else { + return "Normal"; + } + case 3: + return italic ? "Italic" : "Roman"; + } + return QString::null; + } +}; + +class MakeQPF : public QMainWindow +{ + Q_OBJECT + QListView* view; +public: + MakeQPF() + { + view = new QListView(this); + view->addColumn("Family"); + view->addColumn("Size"); + view->addColumn("Weight"); + view->addColumn("Style"); + setCentralWidget(view); + QString fontdir = QString(getenv("QTDIR")) + "/lib/fonts"; + readFontDir(fontdir); + + connect(view,SIGNAL(selectionChanged(QListViewItem*)), + this,SLOT(renderAndSave(QListViewItem*))); + } + + void readFontDir(const QString& fntd) + { + QString fontdir = fntd + "/fontdir"; + QFile fd(fontdir); + if ( !fd.open(IO_ReadOnly) ) { + QMessageBox::warning(this, "Read Error", + "

    Cannot read "+fontdir); + return; + } + while ( !fd.atEnd() ) { + QString line; + fd.readLine(line,9999); + if ( line[0] != '#' ) { + QStringList attr = QStringList::split(" ",line); + if ( attr.count() >= 7 ) { + QString family = attr[0]; + int weight = QString(attr[4]).toInt(); + bool italic = QString(attr[3]) == "y"; + QStringList sizes = attr[5]; + if ( sizes[0] == "0" ) { + if ( attr[7].isNull() ) + sizes = QStringList::split(',',attr[6]); + else + sizes = QStringList::split(',',attr[7]); + } + for (QStringList::Iterator it = sizes.begin(); it != sizes.end(); ++it) { + int pointSize = (*it).toInt()/10; + if ( pointSize ) + new FontViewItem( + family, pointSize, weight, italic, view); + } + } + } + } + } + + void renderAndSaveAll() + { + QListViewItem* c = view->firstChild(); + while ( c ) { + renderAndSave(c); + qApp->processEvents(); + c = c->nextSibling(); + } + } + + void renderAndSave(const QString& family) + { + QListViewItem* c = view->firstChild(); + while ( c ) { + if ( c->text(0).lower() == family.lower() ) + renderAndSave(c); + c = c->nextSibling(); + } + } + + void render(const QString& family, int from, int to) + { + QListViewItem* c = view->firstChild(); + while ( c ) { + if ( c->text(0).lower() == family.lower() ) + ((FontViewItem*)c)->render(from,to); + c = c->nextSibling(); + } + } + + void save(const QString& family) + { + QListViewItem* c = view->firstChild(); + while ( c ) { + if ( c->text(0).lower() == family.lower() ) + ((FontViewItem*)c)->save(); + c = c->nextSibling(); + } + } + +private slots: + void renderAndSave(QListViewItem* i) + { + ((FontViewItem*)i)->renderAndSave(); + } +}; + +static void usage() +{ + qWarning("Usage: makeqpf [-A] [-f spec-file] [font ...]"); + qWarning(""); + qWarning(" Saves QPF font files by rendering and saving fonts."); + qWarning(""); + qWarning(" -A = Render and save all fonts in fontdir"); + qWarning(" -f = File of lines:"); + qWarning(" fontname character-ranges"); + qWarning(" eg."); + qWarning(" smoothtimes 0-ff,20a0-20af"); + qWarning(" font = Font to render and save"); +} + +int main(int argc, char** argv) +{ + QApplication app(argc, argv, QApplication::GuiServer); + MakeQPF m; + if ( argc > 1 ) { + argv++; + QString specfile; + while ( *argv && argv[0][0] == '-' ) { + if (argv[0][1] == 'A' ) + m.renderAndSaveAll(); + else if (argv[0][1] == 'f' ) + specfile = *++argv; + else { + usage(); + specfile=QString::null; + *argv=0; + break; + } + argv++; + } + if ( !specfile.isNull() ) { + QFile f(specfile); + if ( f.open(IO_ReadOnly) ) { + QTextStream s(&f); + while (!s.atEnd()) { + QString family,ranges; + s >> family >> ranges; + QStringList r = QStringList::split(',',ranges); + for (QStringList::Iterator it=r.begin(); it!=r.end(); ++it) { + QString rng = *it; + int dash = rng.find('-'); + int from,to; + if ( dash==0 ) { + from=0; + to=rng.mid(1).toInt(0,16); + } else if ( dash==(int)rng.length()-1 ) { + from=rng.left(dash).toInt(0,16); + to=65535; + } else if ( dash<0 ) { + from=to=rng.toInt(0,16); + } else { + from=rng.left(dash).toInt(0,16); + to=rng.mid(dash+1).toInt(0,16); + } + m.render(family,from,to); + } + m.save(family); + } + } else { + qWarning("Cannot open %s",specfile.latin1()); + } + } else { + while (*argv) + m.renderAndSave(*argv++); + } + } else { + // Interactive + app.setMainWidget(&m); + m.show(); + return app.exec(); + } +} + +#include "main.moc" diff --git a/tools/makeqpf/makeall b/tools/makeqpf/makeall new file mode 100755 index 0000000..cd5008c --- /dev/null +++ b/tools/makeqpf/makeall @@ -0,0 +1,4 @@ +for dpy in LinuxFb Transformed:Rot90 Transformed:Rot180 Transformed:Rot270 +do + QWS_DISPLAY=$dpy ./makeqpf +done diff --git a/tools/makeqpf/makeqpf.pro b/tools/makeqpf/makeqpf.pro new file mode 100644 index 0000000..8a61af6 --- /dev/null +++ b/tools/makeqpf/makeqpf.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +CONFIG += qt warn_on release +HEADERS = +SOURCES = main.cpp +INTERFACES = +TARGET = makeqpf +REQUIRES=full-config nocrosscompiler + +target.path = $$bins.path +INSTALLS += target diff --git a/tools/mergetr/mergetr.cpp b/tools/mergetr/mergetr.cpp new file mode 100644 index 0000000..c286a84 --- /dev/null +++ b/tools/mergetr/mergetr.cpp @@ -0,0 +1,347 @@ +/********************************************************************** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This is a utility program for merging findtr msgfiles +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include + +#include +#include + +bool isEmpty( const QString& line ) +{ + int i = 0; + while ( i < int(line.length()) ) { + if ( !line[i].isSpace() ) + return FALSE; + i++; + } + return TRUE; +} + + +bool hasHandle( const QString& line, const QString& handle) +{ + return line.left(handle.length()) == handle; +} + +bool isUserComment( const QString& line ) +{ + return line.length() > 2 && line[0] == '#' && line[1].isSpace(); +} + +bool isSystemComment( const QString& line ) +{ + return line.length() > 1 && line[0] == '#' && !line[1].isSpace(); +} + + +QString extractContents( const QString& line ) +{ + QString contents; + int pos = 0; + bool inStr = FALSE; + while ( pos < int(line.length()) ) { + if ( line[pos] == '"' ) { + inStr = !inStr; + pos++; + } else { + if ( inStr ) { + if ( line[pos] == '\\') { + pos++; + switch (char(line[pos]) ) { + case 'n': + contents += '\n'; + break; + case 't': + contents += '\t'; + break; + case 'r': + contents += '\r'; + break; + case 'a': + contents += '\a'; + break; + case 'f': + contents += '\f'; + break; + case 'v': + contents += '\v'; + break; + case 'b': + contents += '\b'; + break; + default: + contents += char(line[pos]); + break; + } + } else { + contents += line[pos]; + } + } + pos++; + } + } + return contents; +} + +struct Item +{ + Item() {} + Item( const Item &i ) :usercomments(i.usercomments), + systemcomments(i.systemcomments), msgid(i.msgid), msgstr(i.msgstr){} + Item &operator=( const Item &i ) { + usercomments = i.usercomments; systemcomments = i.systemcomments; + msgid = i.msgid; msgstr = i.msgstr; + return *this; + } + bool isNull() const { return usercomments.isNull()&&systemcomments.isNull() + &&msgstr.isNull() &&msgid.isNull(); } + + QString usercomments; + QString systemcomments; + QString msgid; + QString msgstr; +}; + +enum Status { Equal, First, Second, FirstJunk, SecondJunk }; + +Item getItem( QTextStream &str, QString &s ) +{ + Item i; + while ( !str.atEnd() && s.isEmpty() ) { + s = str.readLine().stripWhiteSpace(); + } + while ( !str.atEnd() && !s.isEmpty() ) { + if ( isSystemComment(s) ) { + i.systemcomments += s + "\n"; + s = str.readLine().stripWhiteSpace(); + } else if ( isUserComment(s) ) { + i.usercomments += s + "\n"; + s = str.readLine().stripWhiteSpace(); + } else if ( hasHandle( s, "msgid" ) ) { + QString r = s + "\n"; + s = str.readLine().stripWhiteSpace(); + while ( !str.atEnd() && hasHandle(s, "\"") ) { + r += s; + s = str.readLine().stripWhiteSpace(); + r += "\n"; + } + i.msgid = r; + } else if ( hasHandle( s, "msgstr" ) ) { + QString r = s + "\n"; + s = str.readLine().stripWhiteSpace(); + while ( hasHandle(s, "\"") ) { + r += s; + s = str.readLine().stripWhiteSpace(); + r += "\n"; + } + i.msgstr = r; + } else { + s = str.readLine().stripWhiteSpace(); + } + } + return i; +} + +static int nMerge, nNew, nOld, nJunk; + + +void writecomment( QTextStream &str, const QString &s ) +{ + if ( s.isEmpty() ) + return; + int idx = 0; + int len = s.length(); + while ( idx < len ) { + int nl = s.find( '\n', idx ); + if ( nl < 0 ) { + qWarning( "writecomment: string lacks newline" ); + str << "# " << s.mid( idx ) << '\n'; + return; + } + str << "# " << s.mid( idx, nl-idx+1 ); + idx = nl+1; + } +} + +void writemerge( QTextStream &str, const Item &i1, const Item &i2 ) +{ + nMerge++; + if ( !i2.usercomments.isEmpty() ) + str << i2.usercomments; + if ( !i1.systemcomments.isEmpty() ) + str << i1.systemcomments; + str << i1.msgid; + str << i2.msgstr; + str << "\n"; +} +void writenew( QTextStream &str, const Item &i1 ) +{ + nNew++; + if ( !i1.usercomments.isEmpty() ) + str << i1.usercomments; + if ( !i1.systemcomments.isEmpty() ) + str << i1.systemcomments; + str << i1.msgid; + str << i1.msgstr; + str << "\n"; +} + +void writeold( QTextStream &str, const Item &i2 ) +{ + nOld++; + writecomment( str, i2.usercomments ); + writecomment( str, i2.systemcomments ); + writecomment( str, i2.msgid ); + writecomment( str, i2.msgstr ); + str << "\n"; +} + +void writejunk( QTextStream &str, const Item &it ) +{ + nJunk++; + if ( !it.usercomments.isEmpty() ) + str << it.usercomments; + writecomment( str, it.systemcomments ); + writecomment( str, it.msgid ); + writecomment( str, it.msgstr ); + str << "\n"; +} + +Status compare( const Item &i1, const Item &i2 ) +{ + if ( i1.isNull() && i2.isNull() ) + return Equal; + if ( i1.isNull() ) + return Second; + if ( i2.isNull() ) + return First; + if ( i1.msgid.isEmpty() ) + return FirstJunk; + if ( i2.msgid.isEmpty() ) + return SecondJunk; + QString s1 = extractContents( i1.msgid ); + QString s2 = extractContents( i2.msgid ); + if ( !s1 && !s2 ) + return Equal; + if ( !s1 ) + return First; + if ( !s2 ) + return Second; + int i = strcmp( s1.ascii(), s2.ascii() ); + if ( i < 0 ) + return First; + if ( i == 0 ) + return Equal; + // i > 0 + return Second; +} + +void merge( const QString& newname, const QString& oldname, + const QString& resname ) +{ + QFile f1(newname); + if ( !f1.open( IO_ReadOnly) ) + return; + + QFile f2(oldname); + if ( !f2.open( IO_ReadOnly) ) + return; + + QBuffer fout; + fout.open(IO_WriteOnly); + + QTextStream in1( &f1 ); + QTextStream in2( &f2 ); + QTextStream out( &fout ); + + QString buf1 = in1.readLine().stripWhiteSpace(); + QString buf2 = in2.readLine().stripWhiteSpace(); + + Item i1 = getItem( in1, buf1 ); + Item i2 = getItem( in2, buf2 ); + while ( !i1.isNull() || !i2.isNull() ) { + Status s = compare( i1, i2 ); + if ( s == Equal ) { + writemerge(out,i1,i2); + i1 = getItem( in1, buf1 ); + i2 = getItem( in2, buf2 ); + } else if ( s == First ) { + writenew( out, i1 ); + i1 = getItem( in1, buf1 ); + } else if ( s == FirstJunk ) { + //solitary comment + writejunk( out, i1 ); + i1 = getItem( in1, buf1 ); + } else if ( s == Second ) { + writeold( out, i2 ); + i2 = getItem( in2, buf2 ); + } else if ( s == SecondJunk ) { + //solitary comment + writejunk( out, i2 ); + i2 = getItem( in2, buf2 ); + } + } + + f1.close(); + f2.close(); + fout.close(); + QFile fileout(resname); + if ( !fileout.open( IO_WriteOnly | IO_Translate ) ) + return; + fileout.writeBlock(fout.buffer()); + fileout.close(); +} + + +int main( int argc, char* argv[] ) +{ + + int orgfile = 1; + int newfile = 2; + + if ( argc <= newfile || argc > 1 && argv[1][0] == '-') { + printf("usage: %s orgfile newfile [outfile]\n", argv[0]); + exit(1); + } + + merge( argv[newfile], argv[orgfile], + argc > newfile+1 ? argv[newfile+1] : argv[orgfile] ); + + printf( "Merged %d entries, added %d new entries and removed %d entries\n", + nMerge, nNew, nOld ); + if ( nJunk > 0 ) + printf( "Found %d junk entries\n", nJunk ); + return 0; +} diff --git a/tools/mergetr/mergetr.pro b/tools/mergetr/mergetr.pro new file mode 100644 index 0000000..4fbdae1 --- /dev/null +++ b/tools/mergetr/mergetr.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +CONFIG += console qt warn_on release +HEADERS = +SOURCES = mergetr.cpp +TARGET = mergetr +REQUIRES=full-config nocrosscompiler + +target.path = $$bins.path +INSTALLS += target diff --git a/tools/msg2qm/msg2qm.cpp b/tools/msg2qm/msg2qm.cpp new file mode 100644 index 0000000..6ac8c36 --- /dev/null +++ b/tools/msg2qm/msg2qm.cpp @@ -0,0 +1,236 @@ +/********************************************************************** +** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved. +** +** This is a utility program for converting findtr msgfiles to +** qtranslator message files +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include +#include +#include +#include + +#include +#include + +static QString* defaultScope = 0; + +bool hasHandle( const QString& line, const QString& handle) +{ + return line.left(handle.length()) == handle; +} + + +QString extractContents( const QString& line ) +{ + QString contents; + if ( line.contains('\"') < 2) + return contents; + int pos = 0; + while ( pos < int(line.length()) && line[pos] != '\"' ) + pos++; + pos++; + while ( pos < int(line.length()) && line[pos] != '\"' ) { + // 0xa5: the yen sign is the Japanese backslash + if ( line[pos] == '\\' || line[pos] == QChar(0xa5) ) { + pos++; + switch (char(line[pos]) ) { + case 'n': + contents += '\n'; + break; + case 't': + contents += '\t'; + break; + case 'r': + contents += '\r'; + break; + case 'a': + contents += '\a'; + break; + case 'f': + contents += '\f'; + break; + case 'v': + contents += '\v'; + break; + case 'b': + contents += '\b'; + break; + default: + contents += char(line[pos]); + break; + } + } + else + contents += line[pos]; + pos++; + } + return contents; +} + + +void addTranslation( QTranslator* translator, const QString& msgid, const QString& msgstr) +{ + if (!msgid.isNull() && !msgstr.isNull() ) { + QString scope = ""; + QString id = msgid; + int coloncolon = msgid.find("::"); + if (coloncolon != -1) { + scope = msgid.left( coloncolon ); + id = msgid.right( msgid.length() - scope.length() - 2 ); + } + else if (defaultScope) + scope = *defaultScope; + + if (translator->contains( scope.ascii(), id.ascii() ) ) { + qWarning("Error: \"%s\" already in use", msgid.ascii() ); + } + else { + translator->insert( scope.latin1(), id.latin1(), msgstr ); + } + } +} + + + +void translate( const QString& filename, const QString& qmfile ) +{ + QFile f(filename); + if ( !f.open( IO_ReadOnly) ) + return; + QTranslator* translator = new QTranslator(0); + QTextCodec *codec = 0; + for (int pass = 0; pass < 2; pass++) { + f.at(0); + QTextStream t( &f ); + QString line; + QString msgid; + QString msgstr; + if ( codec != 0 ) { + t.setCodec( codec ); + } + while ( !t.atEnd() || !line.isEmpty() ) { + if (line.isEmpty()) { + t.skipWhiteSpace(); + line = t.readLine(); + } + if ( hasHandle( line, "msgid") ) { + msgstr = QString::null; + msgid = extractContents( line ); + if (!t.atEnd()) { + t.skipWhiteSpace(); + line = t.readLine(); + } + else + line = QString::null; + while ( hasHandle( line, "\"") ) { + msgid += extractContents( line ); + if (!t.atEnd()) { + t.skipWhiteSpace(); + line = t.readLine(); + } + else + line = QString::null; + } + } + else if ( hasHandle( line, "msgstr") ) { + msgstr = extractContents( line ); + if (!t.atEnd()) { + t.skipWhiteSpace(); + line = t.readLine(); + } + else + line = QString::null; + while ( hasHandle( line, "\"") ) { + msgstr += extractContents( line ); + if (!t.atEnd()) { + t.skipWhiteSpace(); + line = t.readLine(); + } + else + line = QString::null; + } + if ( pass == 1 ) + addTranslation( translator, msgid, msgstr); + + if ( pass == 0 && msgid.isEmpty() ) { + // Check for the encoding. + int cpos = msgstr.find( "charset=" ); + if ( cpos >= 0 ) { + cpos = cpos + 8; //skip "charset=" + int i = cpos; + int len = msgstr.length(); + while ( i < len && !msgstr[i].isSpace() ) + i++; + QString charset = msgstr.mid( cpos, i-cpos ); + codec = QTextCodec::codecForName( charset.ascii() ); + if ( codec ) { + debug( "PO file character set: %s. Codec: %s", + charset.ascii(), codec->name() ); + } else { + debug( "No codec for %s", charset.ascii() ); + } + } + break; + } + } + else + line = QString::null; + } + } + f.close(); + translator->save( qmfile ); +} + + +// workaround for BCC problem, qtranslator.h includes qwindowdefs.h via qobject.h, see NEEDS_QMAIN +#if defined(main) +#undef main +#endif + +int main( int argc, char* argv[] ) +{ + + int infile = 1; + if (argc > 1) { + if ( QString("-scope") == argv[1] ) { + defaultScope = new QString(argv[2]); + infile += 2; + } + } + + if ( argc <= infile ) { + printf("usage: %s [-scope default] infile [outfile]\n", argv[0]); + exit(1); + } + + translate(argv[infile], argc > infile+1 ? argv[infile+1] : "tr.qm"); + return 0; +} diff --git a/tools/msg2qm/msg2qm.pro b/tools/msg2qm/msg2qm.pro new file mode 100644 index 0000000..f81f03e --- /dev/null +++ b/tools/msg2qm/msg2qm.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +DEPENDPATH = ../../include +CONFIG += console qt warn_on release +HEADERS = +SOURCES = msg2qm.cpp +TARGET = msg2qm +REQUIRES=full-config nocrosscompiler + +target.path = $$bins.path +INSTALLS += target diff --git a/tools/qconfig/LICENSE.GPL b/tools/qconfig/LICENSE.GPL new file mode 100644 index 0000000..3221c03 --- /dev/null +++ b/tools/qconfig/LICENSE.GPL @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/tools/qconfig/main.cpp b/tools/qconfig/main.cpp new file mode 100644 index 0000000..f906fea --- /dev/null +++ b/tools/qconfig/main.cpp @@ -0,0 +1,733 @@ +/********************************************************************** +** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "main.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(Q_OS_WIN32) +#include +#else +#include +#endif +#include + + +/* XPM */ +static const char * const logo_xpm[] = { +/* width height ncolors chars_per_pixel */ +"50 50 17 1", +/* colors */ +" c #000000", +". c #495808", +"X c #2A3304", +"o c #242B04", +"O c #030401", +"+ c #9EC011", +"@ c #93B310", +"# c #748E0C", +"$ c #A2C511", +"% c #8BA90E", +"& c #99BA10", +"* c #060701", +"= c #181D02", +"- c #212804", +"; c #61770A", +": c #0B0D01", +"/ c None", +/* pixels */ +"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$@;.o=::=o.;@$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$+#X* **X#+$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$#oO* O **o#+$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$&.* OO O*.&$$$$$$$$$$$$$", +"$$$$$$$$$$$$@XOO * OO X&$$$$$$$$$$$$", +"$$$$$$$$$$$@XO OO O **:::OOO OOO X@$$$$$$$$$$$", +"$$$$$$$$$$&XO O-;#@++@%.oOO X&$$$$$$$$$$", +"$$$$$$$$$$.O : *-#+$$$$$$$$+#- : O O*.$$$$$$$$$$", +"$$$$$$$$$#*OO O*.&$$$$$$$$$$$$+.OOOO **#$$$$$$$$$", +"$$$$$$$$+-OO O *;$$$$$$$$$$$&$$$$;* o+$$$$$$$$", +"$$$$$$$$#O* O .+$$$$$$$$$$@X;$$$+.O *#$$$$$$$$", +"$$$$$$$$X* -&$$$$$$$$$$@- :;$$$&- OX$$$$$$$$", +"$$$$$$$@*O *O#$$$$$$$$$$@oOO**;$$$# O*%$$$$$$$", +"$$$$$$$; -+$$$$$$$$$@o O OO ;+$$-O *;$$$$$$$", +"$$$$$$$. ;$$$$$$$$$@-OO OO X&$$;O .$$$$$$$", +"$$$$$$$o *#$$$$$$$$@o O O O-@$$$#O *o$$$$$$$", +"$$$$$$+= *@$$$$$$$@o* OO -@$$$$&: =$$$$$$$", +"$$$$$$+: :+$$$$$$@- *-@$$$$$$: :+$$$$$$", +"$$$$$$+: :+$$$$$@o* O *-@$$$$$$: :+$$$$$$", +"$$$$$$$= :@$$$$@o*OOO -@$$$$@: =+$$$$$$", +"$$$$$$$- O%$$$@o* O O O O-@$$$#* OX$$$$$$$", +"$$$$$$$. O *O;$$&o O*O* *O -@$$; O.$$$$$$$", +"$$$$$$$;* Oo+$$;O*O:OO-- Oo@+= *;$$$$$$$", +"$$$$$$$@* O O#$$$;*OOOo@@-O Oo;O* **@$$$$$$$", +"$$$$$$$$X* OOO-+$$$;O o@$$@- O O OX$$$$$$$$", +"$$$$$$$$#* * O.$$$$;X@$$$$@-O O O#$$$$$$$$", +"$$$$$$$$+oO O OO.+$$+&$$$$$$@-O o+$$$$$$$$", +"$$$$$$$$$#* **.&$$$$$$$$$$@o OO:#$$$$$$$$$", +"$$$$$$$$$+. O* O-#+$$$$$$$$+;O OOO:@$$$$$$$$$", +"$$$$$$$$$$&X *O -;#@++@#;=O O -@$$$$$$$$", +"$$$$$$$$$$$&X O O*O::::O OO Oo@$$$$$$$", +"$$$$$$$$$$$$@XOO OO O*X+$$$$$$", +"$$$$$$$$$$$$$&.* ** O :: *:#$$$$$$$", +"$$$$$$$$$$$$$$$#o*OO O Oo#@-OOO=#$$$$$$$$", +"$$$$$$$$$$$$$$$$+#X:* * O**X#+$$@-*:#$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$%;.o=::=o.#@$$$$$$@X#$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$+++$$$$$$$$$$$+$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", +"/$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$/", +}; + + +#define FIXED_LAYOUT + +static const char*back_xpm[]={ +"16 16 5 1", +"# c #000000", +"a c #ffffff", +"c c #808080", +"b c #c0c0c0", +". c None", +"................", +".......#........", +"......##........", +".....#a#........", +"....#aa########.", +"...#aabaaaaaaa#.", +"..#aabbbbbbbbb#.", +"...#abbbbbbbbb#.", +"...c#ab########.", +"....c#a#ccccccc.", +".....c##c.......", +"......c#c.......", +".......cc.......", +"........c.......", +"................", +"......................"}; + +static const char*forward_xpm[]={ +"16 16 5 1", +"# c #000000", +"a c #ffffff", +"c c #808080", +"b c #c0c0c0", +". c None", +"................", +"................", +".........#......", +".........##.....", +".........#a#....", +"..########aa#...", +"..#aaaaaaabaa#..", +"..#bbbbbbbbbaa#.", +"..#bbbbbbbbba#..", +"..########ba#c..", +"..ccccccc#a#c...", +"........c##c....", +"........c#c.....", +"........cc......", +"........c.......", +"................", +"................"}; + +class ChoiceItem : public QCheckListItem { +public: + QString id; + ChoiceItem(const QString& i, QListViewItem* parent) : + QCheckListItem(parent, + i.mid(6), // strip "QT_NO_" as we reverse the logic + CheckBox), + id(i) + { + setOpen(TRUE); + label = text(0); + avl = TRUE; + } + + // We reverse the logic + void setDefined(bool y) { setOn(!y); } + bool isDefined() const { return !isOn(); } + + void setAvailable(bool y) + { + if ( avl != y ) { + avl = y; + repaint(); + } + } + bool isAvailable() const { return avl; } + + virtual void setOn(bool y) + { + QCheckListItem::setOn(y); + setOpen(y); +/* + for (QListViewItem* i=firstChild(); i; i = i->nextSibling() ) { + ChoiceItem* ci = (ChoiceItem*)i; // all are ChoiceItem + if ( ci->isSelectable() != y ) { + ci->setSelectable(y); + listView()->repaintItem(ci); + } + } +*/ + } + + void paintBranches( QPainter * p, const QColorGroup & cg, + int w, int y, int h) + { + QListViewItem::paintBranches(p,cg,w,y,h); + } + + void paintCell( QPainter * p, const QColorGroup & cg, + int column, int width, int align ) + { + if ( !isSelectable() || !isAvailable() ) { + QColorGroup c = cg; + c.setColor(QColorGroup::Text, lightGray); + QCheckListItem::paintCell(p,c,column,width,align); + } else { + QCheckListItem::paintCell(p,cg,column,width,align); + } + } + + void setInfo(const QString& l, const QString& d) + { + label = l; + doc = d; + setText(0,label); + } + + QString label; + + QString info() const + { + return "

    "+label+"

    "+doc; + } + +private: + QString doc; + bool avl; +}; + +Main::Main() +{ + setIcon( (const char**)logo_xpm ); +#ifdef FIXED_LAYOUT + QHBox* horizontal = new QHBox(this); +#else + QSplitter* horizontal = new QSplitter(this); +#endif + + lv = new QListView(horizontal); + lv->setSorting(-1); + lv->setRootIsDecorated(TRUE); + lv->addColumn("ID"); + + info = new Info(horizontal); + info->setBackgroundMode(PaletteBase); + info->setMargin(10); + info->setFrameStyle(QFrame::WinPanel|QFrame::Sunken); + info->setAlignment(AlignTop); + + connect(info, SIGNAL(idClicked(const QString&)), + this, SLOT(selectId(const QString&))); + +#ifdef FIXED_LAYOUT + horizontal->setStretchFactor(info,2); +#endif + + connect(lv, SIGNAL(pressed(QListViewItem*)), + this, SLOT(updateAvailability(QListViewItem*))); + connect(lv, SIGNAL(selectionChanged(QListViewItem*)), + this, SLOT(showInfo(QListViewItem*))); + + setCentralWidget(horizontal); + + QToolBar* tb = new QToolBar( this, "browser controls" ); + tb->setLabel( "Browser Controls" ); + (void)new QToolButton( QPixmap(back_xpm), "Back", QString::null, + info, SLOT(back()), tb, "back" ); + (void)new QToolButton( QPixmap(forward_xpm), "Forward", QString::null, + info, SLOT(forward()), tb, "forward" ); + + QPopupMenu* file = new QPopupMenu( menuBar() ); + file->insertItem( "&Open", this, SLOT(open()), CTRL+Key_O ); + file->insertItem( "&Save", this, SLOT(save()), CTRL+Key_S ); + file->insertSeparator(); + file->insertItem( "&Test all", this, SLOT(testAll()), CTRL+Key_T ); + file->insertSeparator(); + file->insertItem( "E&xit", qApp, SLOT(quit()), CTRL+Key_Q ); + + menuBar()->insertItem( "&File",file ); + + menuBar()->insertSeparator(); + + QPopupMenu *help = new QPopupMenu( menuBar() ); + help->insertItem( "&About", this, SLOT(about()) ); + help->insertItem( "About &Qt", this, SLOT(aboutQt()) ); + + menuBar()->insertItem( "&Help", help ); + + statusBar()->message( "Ready" ); +} + +void Main::open() +{ +} + +void Main::save() +{ +} + +void Main::testAll() +{ + QString qtdir = getenv("QTDIR"); + chdir((qtdir+"/src").ascii()); + QString c; + for (QStringList::ConstIterator it = choices.begin(); it != choices.end(); ++it) + { + c += "Feature: "; + c += *it; + c += "\n"; + + c += "Section: "; + c += section[*it]; + c += "\n"; + + c += "Requires: "; + c += dependencies[*it].join(" "); + c += "\n"; + + c += "Name: "; + c += label[*it]; + c += "\n"; + + c += "SeeAlso: ???\n"; + + c += "\n"; + } + QFile f("features.txt"); + f.open(IO_WriteOnly); + f.writeBlock(c.ascii(),c.length()); + f.close(); + // system("./feature_size_calculator"); + +#if 0 + system("mv ../include/qconfig.h ../include/qconfig.h-orig"); + for (QStringList::ConstIterator it = choices.begin(); it != choices.end(); ++it) + { + QString choice = *it; + QFile f("../include/qconfig.h"); + f.open(IO_WriteOnly); + QCString s = "#define "; + s += choice.latin1(); + s += "\n"; + f.writeBlock(s,s.length()); + f.close(); + int err = system("make"); + if ( err != 0 ) + break; + } + system("mv ../include/qconfig.h-orig ../include/qconfig.h"); +#endif +} + + +// ##### should be in QMap? +template +QValueList keys(QMap map) +{ + QValueList result; + for (Q_TYPENAME QMap::ConstIterator it = map.begin(); it!=map.end(); ++it) + result.append(it.key()); + return result; +} + +void Main::loadFeatures(const QString& filename) +{ + QFile file(filename); + if ( !file.open(IO_ReadOnly) ) { + QMessageBox::warning(this,"Warning", + "Cannot open file " + filename); + return; + } + QTextStream s(&file); + QRegExp qt_no_xxx("QT_NO_[A-Z_0-9]*"); + QStringList sections; + +#if 1 + QString line = s.readLine(); + QString feature, lab, sec; + QStringList deps, seealso; + QMap sectioncontents; + while (!s.atEnd()) { + if ( line.length() <= 1 ) { + if ( !feature.isEmpty() ) { + dependencies[feature] = deps; + for (QStringList::ConstIterator it = deps.begin(); it!=deps.end(); ++it) + rdependencies[*it].append(feature); + label[feature] = lab; + links[feature] = seealso; + section[feature] = sec; + sectioncontents[sec].append(feature); + choices.append(feature); + } else { + qDebug("Unparsed text"); + } + + feature = lab = sec = QString::null; + deps.clear(); seealso.clear(); + line = s.readLine(); + continue; + } + + QString nextline = s.readLine(); + while ( nextline[0] == ' ' ) { + line += nextline; + nextline = s.readLine(); + } + + int colon = line.find(':'); + if ( colon < 0 ) { + qDebug("Cannot parse: %s",line.ascii()); + } else { + QString tag = line.left(colon); + QString value = line.mid(colon+1).stripWhiteSpace(); + if ( tag == "Feature" ) + feature = value; + else if ( tag == "Requires" ) + deps = QStringList::split(QChar(' '),value); + else if ( tag == "Name" ) + lab = value; + else if ( tag == "Section" ) + sec = value; + else if ( tag == "SeeAlso" ) + seealso = QStringList::split(QChar(' '),value); + } + + line = nextline; + } + sections = keys(sectioncontents); + +#else + QString sec; + QString lab; + QString doc; + bool on = FALSE; + bool docmode = FALSE; + QStringList deps; + + do { + QString line = s.readLine(); + line.replace(QRegExp("# *define"),"#define"); + + QStringList token = QStringList::split(QChar(' '),line); + if ( on ) { + if ( docmode ) { + if ( token[0] == "*/" ) + docmode = FALSE; + else if ( lab.isEmpty() ) + lab = line.stripWhiteSpace(); + else + doc += line.simplifyWhiteSpace() + "\n"; + } else if ( token[0] == "//#define" || token[0] == "#define" ) { + dependencies[token[1]] = deps; + for (QStringList::ConstIterator it = deps.begin(); it!=deps.end(); ++it) + rdependencies[*it].append(token[1]); + section[token[1]] = sec; + documentation[token[1]] = doc; + label[token[1]] = lab; + choices.append(token[1]); + doc = ""; + lab = ""; + } else if ( token[0] == "/*!" ) { + docmode = TRUE; + } else if ( token[0] == "//" ) { + token.remove(token.begin()); + sec = token.join(" "); + sections.append(sec); + } else if ( token[0] == "#if" ) { + Q_ASSERT(deps.isEmpty()); + for (int i=1; i<(int)token.count(); i++) { + if ( token[i][0] == 'd' ) { + int index; + int len; + index = qt_no_xxx.match(token[i],0,&len); + if ( index >= 0 ) { + QString d = token[i].mid(index,len); + deps.append(d); + } + } + } + } else if ( token[0] == "#endif" ) { + deps.clear(); + } else if ( token[0].isEmpty() ) { + } else { + qDebug("Cannot parse: %s",token.join(" ").ascii()); + } + } else if ( token[0] == "#include" ) { + on = TRUE; + } + } while (!s.atEnd()); +#endif + + lv->clear(); + sections.sort(); + // ##### QListView default sort order is reverse of insertion order + for (QStringList::Iterator se = sections.fromLast(); se != sections.end(); --se) { + sectionitem[*se] = new QListViewItem(lv,*se); + } + for (QStringList::Iterator ch = choices.begin(); ch != choices.end(); ++ch) { + createItem(*ch); + } + +#ifdef FIXED_LAYOUT + lv->setFixedWidth(lv->sizeHint().width()); +#endif +} + +void Main::createItem(const QString& ch) +{ + if ( !item[ch] ) { + QStringList deps = dependencies[ch]; + QString sec = section[ch]; + QListViewItem* parent = 0; + for (QStringList::Iterator dp = deps.begin(); dp != deps.end(); ++dp) { + QString dsec = section[*dp]; + if ( dsec.isEmpty() ) + qDebug("No section for %s",(*dp).latin1()); + if ( !parent && dsec == sec ) { + createItem(*dp); + parent = item[*dp]; + } + } + if ( !parent ) + parent = sectionitem[section[ch]]; + ChoiceItem* ci = new ChoiceItem(ch,parent); + item[ch] = ci; + if ( !label[ch].isEmpty() ) + ci->setInfo(label[ch],documentation[ch]); + } +} + +void Main::loadConfig(const QString& filename) +{ + QFile file(filename); + if ( !file.open(IO_ReadOnly) ) { + QMessageBox::warning(this,"Warning", + "Cannot open file " + filename); + return; + } + QTextStream s(&file); + QRegExp qt_no_xxx("QT_NO_[A-Z_0-9]*"); + + for (QStringList::Iterator ch = choices.begin(); ch != choices.end(); ++ch) { + item[*ch]->setDefined(FALSE); + } + do { + QString line = s.readLine(); + QStringList token = QStringList::split(QChar(' '),line); + if ( token[0] == "#define" ) { + ChoiceItem* i = item[token[1]]; + if ( i ) + i->setDefined(TRUE); + else + qDebug("The item %s is not used by qfeatures.h", token[1].latin1()); + } + } while (!s.atEnd()); +} + +void Main::updateAvailability(QListViewItem* i) +{ + if ( !i || !i->parent() ) { + // section. do nothing for now + } else { + ChoiceItem* choice = (ChoiceItem*)i; + QStringList deps = rdependencies[choice->id]; + for (QStringList::ConstIterator it = deps.begin(); + it != deps.end(); ++it) + { + ChoiceItem* d = item[*it]; + QStringList ddeps = dependencies[d->id]; + bool av = TRUE; + for (QStringList::ConstIterator dit = ddeps.begin(); + av && dit != ddeps.end(); ++dit) + { + ChoiceItem* dd = item[*dit]; + if ( dd ) { + if ( dd->isDefined() || !dd->isAvailable() ) + av = FALSE; + } else + qDebug("%s ???",(*dit).latin1()); + } + if ( d->isAvailable() != av ) { + d->setAvailable(av); + updateAvailability(d); + } + } +qDebug("%s: %d",choice->id.latin1(),choice->isAvailable()); + } +} + +void Main::showInfo(QListViewItem* i) +{ + if ( !i ) + return; + if ( !i->parent() ) { + // section. do nothing for now + } else { + ChoiceItem* choice = (ChoiceItem*)i; + QString i = choice->info(); + QStringList deps = dependencies[choice->id]; + if ( !deps.isEmpty() ) { + i += "

    Requires:

    "; + } + QStringList rdeps = rdependencies[choice->id]; + if ( !rdeps.isEmpty() ) { + i += "

    Required for:

      "; + for (QStringList::ConstIterator it = rdeps.begin(); + it != rdeps.end(); ++it) + { + ChoiceItem* d = item[*it]; + if ( d ) + i += "
    • id+">"+d->label+""; + } + i += "
    "; + } + info->setText(i); + } +} + +void Main::selectId(const QString& id) +{ + QListViewItem* it = item[id]; + if ( it ) { + lv->setSelected(it,TRUE); + lv->ensureItemVisible(it); + } +} + +Info::Info( QWidget* parent, const char* name ) : + QTextBrowser(parent, name) +{ +} + +void Info::setSource(const QString& name) +{ + if ( name.left(5) == "id://" ) { + emit idClicked(name.mid(5,name.length()-6)); // skip trailing "/" too + } else { + QTextBrowser::setSource(name); + } +} + +void Main::about() +{ + QMessageBox::about(this, "About qconfig", + "

    Qt/Embedded build configuration

    " + "

    " + "

    Version 1.0

    " + "

    Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.

    " + "

    " + "

    This program is licensed to you under the terms of the GNU General " + "Public License Version 2 as published by the Free Software Foundation. This " + "gives you legal permission to copy, distribute and/or modify this software " + "under certain conditions. For details, see the file 'LICENSE.GPL' that came with " + "this software distribution. If you did not get the file, send email to " + "info@trolltech.com.

    \n\n

    The program is provided AS IS with NO WARRANTY " + "OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS " + "FOR A PARTICULAR PURPOSE.

    " + ); +} + +void Main::aboutQt() +{ + QMessageBox::aboutQt( this, tr("qconfig") ); +} + +int main(int argc, char** argv) +{ + QApplication app(argc,argv); + Main m; + QString qtdir = getenv("QTDIR"); + QString qfeatures = qtdir + "/src/tools/qfeatures.txt"; + //QString qfeatures = qtdir + "/include/qfeatures.h"; + QString qconfig = qtdir + "/include/qconfig.h"; + for (int i=1; i +#include +#include +#include + +class ChoiceItem; +class QListViewItem; +class QListView; +class QLabel; + +class Info : public QTextBrowser { + Q_OBJECT +public: + Info( QWidget* parent, const char* name=0 ); + +signals: + void idClicked(const QString& name); + +public slots: + void setSource(const QString& name); +}; + +class Main : public QMainWindow { + Q_OBJECT +public: + Main(); + void loadFeatures(const QString& filename); + void loadConfig(const QString& filename); + +private: + void createItem(const QString& ch); + QMap label; + QMap documentation; + QMap links; + QMap dependencies; + QMap rdependencies; + QMap section; + QMap item; + QMap sectionitem; + QStringList choices; + QListView* lv; + QTextBrowser* info; + +private slots: + void updateAvailability(QListViewItem* i); + void showInfo(QListViewItem* i); + void selectId(const QString&); + void open(); + void save(); + void testAll(); + void about(); + void aboutQt(); +}; diff --git a/tools/qconfig/qconfig.pro b/tools/qconfig/qconfig.pro new file mode 100644 index 0000000..bc05273 --- /dev/null +++ b/tools/qconfig/qconfig.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +CONFIG += qt warn_on release +HEADERS = main.h +SOURCES = main.cpp +INTERFACES = +TARGET = qconfig +REQUIRES=full-config nocrosscompiler diff --git a/tools/qembed/qembed.cpp b/tools/qembed/qembed.cpp new file mode 100644 index 0000000..db0a87d --- /dev/null +++ b/tools/qembed/qembed.cpp @@ -0,0 +1,338 @@ +/**************************************************************************** +** +** Utility program for embedding binary data into a C/C++ source code. +** It reads a binary file and generates a C array with the binary data. +** The C code is written to standard output. +** +** Created : 951017 +** +** Copyright (C) 1995-2008 Trolltech ASA. All rights reserved. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that this copyright notice appears in all copies. +** No representations are made about the suitability of this software for any +** purpose. It is provided "as is" without express or implied warranty. +** +*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void embedData( const QByteArray &input, QFile *output ); +static void embedData( const uchar* input, int size, QFile *output ); +static void embedData( const QRgb* input, int size, QFile *output ); +static QString convertFileNameToCIdentifier( const char * ); + +static const char header[] = "/* Generated by qembed */\n"; + +struct Embed { + uint size; + QString name; + QString cname; +}; + +struct EmbedImage { + int width; + int height; + int depth; + int numColors; + QRgb* colorTable; + QString name; + QString cname; + bool alpha; +}; + +int main( int argc, char **argv ) +{ + if ( argc < 2 ) { + qWarning( "Usage:\n\t%s [--images] files", argv[0] ); + return 1; + } + + QFile output; + bool output_hdr = FALSE; + bool images = FALSE; + output.open( IO_WriteOnly, stdout ); + QTextStream out( &output ); + + QPtrList list_image; + QPtrList list; + list.setAutoDelete( TRUE ); + list_image.setAutoDelete( TRUE ); + + long l = rand(); + out << "#ifndef _QEMBED_" << l << endl; + out << "#define _QEMBED_" << l << endl; + + QStringList args; + for ( int i = 1; i < argc; ++i ) { + QString file( argv[i] ); +#ifdef Q_WS_WIN + // Since wildcards are not expanded automatically for us on Windows, we need to do + // it ourselves + if ( file.contains( '*' ) || file.contains( '?' ) ) { + QDir d; + const QFileInfoList *fiList = d.entryInfoList( file, QDir::Files ); + QFileInfoListIterator it(*fiList); + while ( it.current() ) { + args << (*it)->filePath(); + ++it; + } + } else +#endif + args << file; + } + for ( QStringList::Iterator it = args.begin(); it != args.end(); ++it ) { + QString arg = (*it); + if ( arg == "--images" ) { + if ( !images ) { + out << "#include \n"; + out << "#include \n"; + images = TRUE; + } + } else { + QFile f( *it ); + if ( !f.open(IO_ReadOnly) ) { + qWarning( "Cannot open file %s, ignoring it", (*it).latin1() ); + continue; + } + QByteArray a( f.size() ); + if ( f.size() == 0 + || f.readBlock(a.data(), f.size()) != (int)f.size() ) { + qWarning( "Cannot read file %s, ignoring it", (*it).latin1() ); + continue; + } + if ( images ) { + QImage img; + if ( !img.loadFromData(a) ) { + qWarning( "Cannot read image from file %s, ignoring it", (*it).latin1() ); + continue; + } + EmbedImage *e = new EmbedImage; + e->width = img.width(); + e->height = img.height(); + e->depth = img.depth(); + e->numColors = img.numColors(); + e->colorTable = new QRgb[e->numColors]; + e->alpha = img.hasAlphaBuffer(); + memcpy(e->colorTable, img.colorTable(), e->numColors*sizeof(QRgb)); + QFileInfo fi( (*it) ); + e->name = fi.baseName(); + e->cname = convertFileNameToCIdentifier( e->name.latin1() ); + list_image.append( e ); + QString s; + if ( e->depth == 32 ) { + out << s.sprintf( "static const QRgb %s_data[] = {", + (const char *)e->cname ); + embedData( (QRgb*)img.bits(), e->width*e->height, &output ); + } else { + if ( e->depth == 1 ) + img = img.convertBitOrder(QImage::BigEndian); + out << s.sprintf( "static const unsigned char %s_data[] = {", + (const char *)e->cname ); + embedData( img.bits(), img.numBytes(), &output ); + } + out << "\n};\n\n"; + if ( e->numColors ) { + out << s.sprintf( "static const QRgb %s_ctable[] = {", + (const char *)e->cname ); + embedData( e->colorTable, e->numColors, &output ); + out << "\n};\n\n"; + } + } else { + Embed *e = new Embed; + e->size = f.size(); + e->name = (*it); + e->cname = convertFileNameToCIdentifier( (*it) ); + list.append( e ); + QString s; + out << s.sprintf( "static const unsigned int %s_len = %d;\n", + (const char *)e->cname, e->size ); + out << s.sprintf( "static const unsigned char %s_data[] = {", + (const char *)e->cname ); + embedData( a, &output ); + out << "\n};\n\n"; + } + if ( !output_hdr ) { + output_hdr = TRUE; + out << header; + } + } + } + + if ( list.count() > 0 ) { + out << "#include \n"; + if ( !images ) + out << "#include \n"; + + out << "static struct Embed {\n" + " unsigned int size;\n" + " const unsigned char *data;\n" + " const char *name;\n" + "} embed_vec[] = {\n"; + Embed *e = list.first(); + while ( e ) { + out << " { " << e->size << ", " << e->cname << "_data, " + << "\"" << e->name << "\" },\n"; + e = list.next(); + } + out << " { 0, 0, 0 }\n};\n"; + + out << "\n" +"static const QByteArray& qembed_findData( const char* name )\n" +"{\n" +" static QDict dict;\n" +" QByteArray* ba = dict.find( name );\n" +" if ( !ba ) {\n" +" for ( int i = 0; embed_vec[i].data; i++ ) {\n" +" if ( strcmp(embed_vec[i].name, name) == 0 ) {\n" +" ba = new QByteArray;\n" +" ba->setRawData( (char*)embed_vec[i].data,\n" +" embed_vec[i].size );\n" +" dict.insert( name, ba );\n" +" break;\n" +" }\n" +" }\n" +" if ( !ba ) {\n" +" static QByteArray dummy;\n" +" return dummy;\n" +" }\n" +" }\n" +" return *ba;\n" +"}\n\n"; + } + + if ( list_image.count() > 0 ) { + out << "static struct EmbedImage {\n" + " int width, height, depth;\n" + " const unsigned char *data;\n" + " int numColors;\n" + " const QRgb *colorTable;\n" + " bool alpha;\n" + " const char *name;\n" + "} embed_image_vec[] = {\n"; + EmbedImage *e = list_image.first(); + while ( e ) { + out << " { " + << e->width << ", " + << e->height << ", " + << e->depth << ", " + << "(const unsigned char*)" << e->cname << "_data, " + << e->numColors << ", "; + if ( e->numColors ) + out << e->cname << "_ctable, "; + else + out << "0, "; + if ( e->alpha ) + out << "TRUE, "; + else + out << "FALSE, "; + out << "\"" << e->name << "\" },\n"; + e = list_image.next(); + } + out << " { 0, 0, 0, 0, 0, 0, 0, 0 }\n};\n"; + + out << "\n" +"static const QImage& qembed_findImage( const QString& name )\n" +"{\n" +" static QDict dict;\n" +" QImage* img = dict.find( name );\n" +" if ( !img ) {\n" +" for ( int i = 0; embed_image_vec[i].data; i++ ) {\n" +" if ( strcmp(embed_image_vec[i].name, name.latin1()) == 0 ) {\n" +" img = new QImage((uchar*)embed_image_vec[i].data,\n" +" embed_image_vec[i].width,\n" +" embed_image_vec[i].height,\n" +" embed_image_vec[i].depth,\n" +" (QRgb*)embed_image_vec[i].colorTable,\n" +" embed_image_vec[i].numColors,\n" +" QImage::BigEndian );\n" +" if ( embed_image_vec[i].alpha )\n" +" img->setAlphaBuffer( TRUE );\n" +" dict.insert( name, img );\n" +" break;\n" +" }\n" +" }\n" +" if ( !img ) {\n" +" static QImage dummy;\n" +" return dummy;\n" +" }\n" +" }\n" +" return *img;\n" +"}\n\n"; + } + + out << "#endif" << endl; + + return 0; +} + + +QString convertFileNameToCIdentifier( const char *s ) +{ + QString r = s; + int len = r.length(); + if ( len > 0 && !isalpha( (char)r[0].latin1() ) ) + r[0] = '_'; + for ( int i = 1; i < len; i++ ) { + if ( !isalnum( (char)r[i].latin1() ) ) + r[i] = '_'; + } + return r; +} + + +void embedData( const QByteArray &input, QFile *output ) +{ + embedData((uchar*)input.data(), input.size(), output); +} + +void embedData( const uchar* input, int nbytes, QFile *output ) +{ + static const char hexdigits[] = "0123456789abcdef"; + QString s; + for ( int i=0; iwriteBlock( (const char*)s, s.length() ); + s.truncate( 0 ); + } + uint v = input[i]; + s += "0x"; + s += hexdigits[(v >> 4) & 15]; + s += hexdigits[v & 15]; + if ( i < nbytes-1 ) + s += ','; + } + if ( s.length() ) + output->writeBlock( (const char*)s, s.length() ); +} + +void embedData( const QRgb* input, int n, QFile *output ) +{ + QString s; + for ( int i = 0; i < n; i++ ) { + if ( (i % 14) == 0 ) { + s += "\n "; + output->writeBlock( (const char*)s, s.length() ); + s.truncate( 0 ); + } + QRgb v = input[i]; + s += "0x"; + s += QString::number( v, 16 ); + if ( i < n-1 ) + s += ','; + } + if ( s.length() ) + output->writeBlock( (const char*)s, s.length() ); +} diff --git a/tools/qembed/qembed.pro b/tools/qembed/qembed.pro new file mode 100644 index 0000000..a10bbcd --- /dev/null +++ b/tools/qembed/qembed.pro @@ -0,0 +1,7 @@ +CONFIG += console qt warn_on release +SOURCES = qembed.cpp +TARGET = qembed +REQUIRES=full-config nocrosscompiler + +target.path = $$bins.path +INSTALLS += target diff --git a/tools/qtconfig/LICENSE.GPL b/tools/qtconfig/LICENSE.GPL new file mode 100644 index 0000000..3221c03 --- /dev/null +++ b/tools/qtconfig/LICENSE.GPL @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/tools/qtconfig/colorbutton.cpp b/tools/qtconfig/colorbutton.cpp new file mode 100644 index 0000000..1e678f2 --- /dev/null +++ b/tools/qtconfig/colorbutton.cpp @@ -0,0 +1,177 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "colorbutton.h" + +#include +#include +#include +#include +#include + + +ColorButton::ColorButton(QWidget *parent, const char *name) + : QButton(parent, name), mousepressed(FALSE) +{ + setAcceptDrops(TRUE); + col = black; + connect(this, SIGNAL(clicked()), SLOT(changeColor())); +} + + +ColorButton::ColorButton(const QColor &c, QWidget *parent, const char *name) + : QButton(parent, name) +{ + setAcceptDrops(TRUE); + col = c; + connect(this, SIGNAL(clicked()), SLOT(changeColor())); +} + + +void ColorButton::setColor(const QColor &c) +{ + col = c; + update(); +} + + +void ColorButton::changeColor() +{ + QColor c = QColorDialog::getColor(col, qApp->activeWindow()); + + if (c.isValid()) { + setColor(c); + emit colorChanged(color()); + } +} + + +QSize ColorButton::sizeHint() const +{ + return QSize(40, 25); +} + + +QSize ColorButton::minimumSizeHint() const +{ + return QSize(40, 25); +} + + +void ColorButton::drawButton(QPainter *p) +{ + style().drawPrimitive(QStyle::PE_ButtonBevel, p, rect(), colorGroup(), + isDown() ? QStyle::Style_Down : QStyle::Style_Raised); + drawButtonLabel(p); + + if (hasFocus()) + style().drawPrimitive(QStyle::PE_FocusRect, p, + style().subRect(QStyle::SR_PushButtonFocusRect, this), + colorGroup(), QStyle::Style_Default); +} + + +void ColorButton::drawButtonLabel(QPainter *p) +{ + QColor pen = (isEnabled() ? + (hasFocus() ? palette().active().buttonText() : + palette().inactive().buttonText()) + : palette().disabled().buttonText()); + p->setPen( pen ); + p->setBrush(col); + p->drawRect(width() / 4, height() / 4, width() / 2, height() / 2); +} + + +void ColorButton::dragEnterEvent(QDragEnterEvent *e) +{ + if (! QColorDrag::canDecode(e)) { + e->ignore(); + return; + } +} + + +void ColorButton::dragMoveEvent(QDragMoveEvent *e) +{ + if (! QColorDrag::canDecode(e)) { + e->ignore(); + return; + } + + e->accept(); +} + + +void ColorButton::dropEvent(QDropEvent *e) +{ + if (! QColorDrag::canDecode(e)) { + e->ignore(); + return; + } + + QColor c; + QColorDrag::decode(e, c); + setColor(c); + emit colorChanged(color()); +} + + +void ColorButton::mousePressEvent(QMouseEvent *e) +{ + presspos = e->pos(); + mousepressed = TRUE; + QButton::mousePressEvent(e); +} + + +void ColorButton::mouseReleaseEvent(QMouseEvent *e) +{ + mousepressed = FALSE; + QButton::mouseReleaseEvent(e); +} + + +void ColorButton::mouseMoveEvent(QMouseEvent *e) +{ + if (! mousepressed) + return; + + if ((presspos - e->pos()).manhattanLength() > QApplication::startDragDistance()) { + mousepressed = FALSE; + setDown(FALSE); + + QColorDrag *cd = new QColorDrag(color(), this); + cd->dragCopy(); + } +} diff --git a/tools/qtconfig/colorbutton.h b/tools/qtconfig/colorbutton.h new file mode 100644 index 0000000..4f370d0 --- /dev/null +++ b/tools/qtconfig/colorbutton.h @@ -0,0 +1,82 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef COLORBUTTON_H +#define COLORBUTTON_H + +#include + + +class ColorButton : public QButton +{ + Q_OBJECT + +public: + ColorButton(QWidget *, const char * = 0); + ColorButton(const QColor &, QWidget *, const char * = 0); + + const QColor &color() const { return col; } + + void setColor(const QColor &); + QSize sizeHint() const; + QSize minimumSizeHint() const; + + void mousePressEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + void dragEnterEvent(QDragEnterEvent *); + void dragMoveEvent(QDragMoveEvent *); + void dropEvent(QDropEvent *); + + +signals: + void colorChanged(const QColor &); + + +protected: + void drawButton(QPainter *); + void drawButtonLabel(QPainter *); + + +private slots: + void changeColor(); + + +private: + QColor col; + QPoint presspos; + bool mousepressed; +}; + + +#endif // COLORBUTTON_H diff --git a/tools/qtconfig/images/appicon.png b/tools/qtconfig/images/appicon.png new file mode 100644 index 0000000..0cb2b68 Binary files /dev/null and b/tools/qtconfig/images/appicon.png differ diff --git a/tools/qtconfig/main.cpp b/tools/qtconfig/main.cpp new file mode 100644 index 0000000..980e64c --- /dev/null +++ b/tools/qtconfig/main.cpp @@ -0,0 +1,45 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "mainwindow.h" +#include + + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + MainWindow mw; + app.setMainWidget(&mw); + mw.show(); + return app.exec(); +} diff --git a/tools/qtconfig/mainwindow.cpp b/tools/qtconfig/mainwindow.cpp new file mode 100644 index 0000000..c9f81ff --- /dev/null +++ b/tools/qtconfig/mainwindow.cpp @@ -0,0 +1,1142 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "mainwindow.h" +#include "colorbutton.h" +#include "previewframe.h" +#include "paletteeditoradvanced.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +// from qapplication.cpp and qapplication_x11.cpp - These are NOT for +// external use ignore them +extern bool Q_EXPORT qt_resolve_symlinks; + + +static const char *appearance_text = +"

    Appearance

    " +"
    " +"

    Use this tab to customize the appearance of your Qt applications.

    " +"

    You can select the default GUI Style from the drop down list and " +"customize the colors.

    " +"

    Any GUI Style plugins in your plugin path will automatically be added " +"to the list of built-in Qt styles. (See the Library Paths tab for " +"information on adding new plugin paths.)

    " +"

    When you choose 3-D Effects and Background colors, the Qt Configuration " +"program will automatically generate a palette for you. To customize " +"colors further, press the Tune Palette button to open the advanced " +"palette editor." +"

    The Preview Window shows what the selected Style and colors look " +"like."; + +static const char *font_text = +"

    Fonts

    " +"
    " +"

    Use this tab to select the default font for your Qt applications. " +"The selected font is shown (initially as 'Sample Text') in the line " +"edit below the Family, " +"Style and Point Size drop down lists.

    " +"

    Qt has a powerful font substitution feature that allows you to " +"specify a list of substitute fonts. Substitute fonts are used " +"when a font cannot be loaded, or if the specified font doesn't have " +"a particular character." +"

    For example, if you select the font Lucida, which doesn't have Korean " +"characters, but need to show some Korean text using the Mincho font family " +"you can do so by adding Mincho to the list. Once Mincho is added, any " +"Korean characters that are not found in the Lucida font will be taken " +"from the Mincho font. Because the font substitutions are " +"lists, you can also select multiple families, such as Song Ti (for " +"use with Chinese text)."; + +static const char *interface_text = +"

    Interface

    " +"
    " +"

    Use this tab to customize the feel of your Qt applications.

    " +"

    If the Resolve Symlinks checkbox is checked Qt will follow symlinks " +"when handling URLs. For example, in the file dialog, if this setting is turned " +"on and /usr/tmp is a symlink to /var/tmp, entering the /usr/tmp directory " +"will cause the file dialog to change to /var/tmp. With this setting turned " +"off, symlinks are not resolved or followed.

    " +"

    The Global Strut setting is useful for people who require a " +"minimum size for all widgets (e.g. when using a touch panel or for users " +"who are visually impaired). Leaving the Global Strut width and height " +"at 0 will disable the Global Strut feature

    " +"

    XIM (Extended Input Methods) are used for entering characters in " +"languages that have large character sets, for example, Chinese and " +"Japanese."; +// ### What does the 'Enhanced support for languages written R2L do? + +static const char *libpath_text = +"

    Library Paths

    " +"
    " +"

    Use this tab to select additional directories where Qt should search " +"for component plugins." +"

    These directories should be the base directory of where your plugins " +"are stored. For example, if you wish to store GUI Style plugins in " +"$HOME/plugins/styles and Qt Designer plugins in $HOME/plugins/designer, " +"you would add $HOME/plugins to your Library Path.

    Notes:" +"

    • The Qt Configuration program does not support environment " +"variables, so you must give full path names, for example " +"/home/brad/myplugins not $HOME/myplugins" +"
    • Qt automatically " +"searches in the directory where you installed Qt for component plugins. " +"Removing that path is not possible.
    "; + +static const char *printer_text = +"

    Printer

    " +"
    " +"

    Use this tab to configure the way Qt generates output for the printer." +"You can specify if Qt should try to embed fonts into its generated output." +"If you enable font embedding, the resulting postscript will be more " +"portable and will more accurately reflect the " +"visual output on the screen; however the resulting postscript file " +"size will be bigger." +"

    When using font embedding you can select additional directories where " +"Qt should search for embeddable font files. By default, the X " +"server font path is used."; + +static const char *about_text = +"

    Qt Configuration

    " +"

    A graphical configuration tool for programs using Qt

    " +"

    Version 1.0

    " +"

    Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.

    " +"

    " +"

    This program is licensed to you under the terms of the GNU General " +"Public License Version 2 as published by the Free Software Foundation. This " +"gives you legal permission to copy, distribute and/or modify this software " +"under certain conditions. For details, see the file 'LICENSE.GPL' that came with " +"this software distribution. If you did not get the file, send email to " +"info@trolltech.com.

    \n\n

    The program is provided AS IS with NO WARRANTY " +"OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS " +"FOR A PARTICULAR PURPOSE.

    "; + + +static QColorGroup::ColorRole centralFromItem( int item ) +{ + switch( item ) { + case 0: return QColorGroup::Background; + case 1: return QColorGroup::Foreground; + case 2: return QColorGroup::Button; + case 3: return QColorGroup::Base; + case 4: return QColorGroup::Text; + case 5: return QColorGroup::BrightText; + case 6: return QColorGroup::ButtonText; + case 7: return QColorGroup::Highlight; + case 8: return QColorGroup::HighlightedText; + default: return QColorGroup::NColorRoles; + } +} + + +static QColorGroup::ColorRole effectFromItem( int item ) +{ + switch( item ) { + case 0: return QColorGroup::Light; + case 1: return QColorGroup::Midlight; + case 2: return QColorGroup::Mid; + case 3: return QColorGroup::Dark; + case 4: return QColorGroup::Shadow; + default: return QColorGroup::NColorRoles; + } +} + + +static void setStyleHelper(QWidget *w, QStyle *s) +{ + w->unsetPalette(); + w->setStyle(s); + + const QObjectList *children = w->children(); + if (! children) + return; + + QPtrListIterator childit(*children); + QObject *child; + while ((child = childit.current()) != 0) { + ++childit; + + if (child->isWidgetType()) + setStyleHelper((QWidget *) child, s); + } +} + + +MainWindow::MainWindow() + : MainWindowBase(0, "main window"), + editPalette(palette()), previewPalette(palette()), previewstyle(0) +{ + modified = TRUE; + + QStringList gstyles = QStyleFactory::keys(); + gstyles.sort(); + gstylecombo->insertStringList(gstyles); + + QSettings settings; + QString currentstyle = settings.readEntry("/qt/style"); + if (currentstyle.isNull()) + currentstyle = QApplication::style().className(); + { + int s = 0; + QStringList::Iterator git = gstyles.begin(); + while (git != gstyles.end()) { + if (*git == currentstyle) + break; + s++; + git++; + } + + if (s < gstylecombo->count()) { + gstylecombo->setCurrentItem(s); + } else { + // no predefined style, try to find the closest match + // class names usually contain the name of the style, so we + // iterate over the items in the combobox, and use the one whose + // name is contained in the classname of the style + s = 0; + git = gstyles.begin(); + while (git != gstyles.end()) { + if (currentstyle.contains(*git)) + break; + s++; + git++; + } + + if (s < gstylecombo->count()) { + gstylecombo->setCurrentItem(s); + } else { + // we give up + gstylecombo->insertItem("Unknown"); + gstylecombo->setCurrentItem(gstylecombo->count() - 1); + } + } + } + + buttonMainColor->setColor(palette().color(QPalette::Active, + QColorGroup::Button)); + buttonMainColor2->setColor(palette().color(QPalette::Active, + QColorGroup::Background)); + + QFontDatabase db; + QStringList families = db.families(); + familycombo->insertStringList(families); + + QStringList fs = families; + QStringList fs2 = QFont::substitutions(); + QStringList::Iterator fsit = fs2.begin(); + while (fsit != fs2.end()) { + if (! fs.contains(*fsit)) + fs += *fsit; + fsit++; + } + fs.sort(); + familysubcombo->insertStringList(fs); + + choosesubcombo->insertStringList(families); + QValueList sizes = db.standardSizes(); + QValueList::Iterator it = sizes.begin(); + while (it != sizes.end()) + psizecombo->insertItem(QString::number(*it++)); + + dcispin->setValue(QApplication::doubleClickInterval()); + cfispin->setValue(QApplication::cursorFlashTime()); + wslspin->setValue(QApplication::wheelScrollLines()); + resolvelinks->setChecked(qt_resolve_symlinks); + + effectcheckbox->setChecked(QApplication::isEffectEnabled(UI_General)); + effectbase->setEnabled(effectcheckbox->isChecked()); + + if (QApplication::isEffectEnabled(UI_FadeMenu)) + menueffect->setCurrentItem(2); + else if (QApplication::isEffectEnabled(UI_AnimateMenu)) + menueffect->setCurrentItem(1); + + if (QApplication::isEffectEnabled(UI_AnimateCombo)) + comboeffect->setCurrentItem(1); + + if (QApplication::isEffectEnabled(UI_FadeTooltip)) + tooltipeffect->setCurrentItem(2); + else if (QApplication::isEffectEnabled(UI_AnimateTooltip)) + tooltipeffect->setCurrentItem(1); + + if ( QApplication::isEffectEnabled( UI_AnimateToolBox ) ) + toolboxeffect->setCurrentItem( 1 ); + + QSize globalStrut = QApplication::globalStrut(); + strutwidth->setValue(globalStrut.width()); + strutheight->setValue(globalStrut.height()); + + libpathlistbox->clear(); + libpathlistbox->insertStringList(QApplication::libraryPaths()); + + // find the default family + QStringList::Iterator sit = families.begin(); + int i = 0, possible = -1; + while (sit != families.end()) { + if (*sit == QApplication::font().family()) + break; + if ((*sit).contains(QApplication::font().family())) + possible = i; + + i++; + sit++; + } + if (sit == families.end()) + i = possible; + if (i == -1) // no clue about the current font + i = 0; + + familycombo->setCurrentItem(i); + + QStringList styles = db.styles(familycombo->currentText()); + stylecombo->insertStringList(styles); + + QString stylestring = db.styleString(QApplication::font()); + sit = styles.begin(); + i = 0; + possible = -1; + while (sit != styles.end()) { + if (*sit == stylestring) + break; + if ((*sit).contains(stylestring)) + possible = i; + + i++; + sit++; + } + if (sit == styles.end()) + i = possible; + if (i == -1) // no clue about the current font + i = 0; + stylecombo->setCurrentItem(i); + + i = 0; + while (i < psizecombo->count()) { + if (psizecombo->text(i) == QString::number(QApplication::font().pointSize())) { + psizecombo->setCurrentItem(i); + break; + } + + i++; + } + + QStringList subs = QFont::substitutes(familysubcombo->currentText()); + sublistbox->clear(); + sublistbox->insertStringList(subs); + + rtlExtensions->setChecked( settings.readBoolEntry( "/qt/useRtlExtensions", FALSE ) ); + +#if defined(Q_WS_X11) + inputStyle->setCurrentText( settings.readEntry( "/qt/XIMInputStyle", trUtf8( "On The Spot" ) ) ); +#else + inputStyle->hide(); + inputStyleLabel->hide(); +#endif + +#if defined(Q_WS_X11) && !defined(QT_NO_IM_EXTENSIONS) + /* + This code makes it possible to set up default input method. + + The list of identifier names of input method which can be used + is acquired using QInputContextFactory::keys(). And it is + translated to display name and set to inputMethodCombo which + displays the list of input method. + */ + inputMethodIdentifiers = QInputContextFactory::keys(); + QStringList imDispNames; + { + // input method switcher should named with "imsw-" prefix to + // prevent to be listed in ordinary input method list. + QStringList::Iterator imIt = inputMethodIdentifiers.begin(); + while (imIt != inputMethodIdentifiers.end()) { + if ((*imIt).find("imsw-") == 0) + imIt = inputMethodIdentifiers.remove(imIt); + else + imIt++; + } + // we should not sort the list + //inputMethodIdentifiers.sort(); + for (imIt = inputMethodIdentifiers.begin(); + imIt != inputMethodIdentifiers.end(); + imIt++) { + QString dispName = QInputContextFactory::displayName(*imIt); + if (dispName.isNull() || dispName.isEmpty()) + dispName = *imIt; + imDispNames << dispName; + } + } + //inputMethodCombo->insertStringList(inputMethodIdentifiers); + inputMethodCombo->insertStringList(imDispNames); + + /* + input method set up as a default in the past is chosen. + If nothing is set up, default input method in the platform is chosen. + */ + // default input method is XIM in X11. + QString currentIM = settings.readEntry("/qt/DefaultInputMethod", "xim"); + { + int index = inputMethodIdentifiers.findIndex(currentIM); + // set up Selected input method. + if (0 <= index && index < inputMethodIdentifiers.count()) { + inputMethodCombo->setCurrentItem(index); + } else { + // Give up. this part is executed when specified IM is not + // installed. + QString dispName = tr("Unknown Input Method") + " (" + currentIM + ")"; + inputMethodCombo->insertItem(dispName); + inputMethodCombo->setCurrentItem(inputMethodCombo->count() - 1); + inputMethodIdentifiers << currentIM; + } + } +#else + inputMethodCombo->hide(); + inputMethodLabel->hide(); +#endif + + fontembeddingcheckbox->setChecked( settings.readBoolEntry("/qt/embedFonts", TRUE) ); + fontpaths = settings.readListEntry("/qt/fontPath", ':'); + fontpathlistbox->insertStringList(fontpaths); + + setModified(FALSE); +} + + +MainWindow::~MainWindow() +{ +} + + +void MainWindow::fileSave() +{ + if (! modified) { + statusBar()->message("No changes to be saved.", 2000); + return; + } + + statusBar()->message("Saving changes..."); + + { + QSettings settings; + QFontDatabase db; + QFont font = db.font(familycombo->currentText(), + stylecombo->currentText(), + psizecombo->currentText().toInt()); + QStringList actcg, inactcg, discg; + + int i; + for (i = 0; i < QColorGroup::NColorRoles; i++) + actcg << editPalette.color(QPalette::Active, + (QColorGroup::ColorRole) i).name(); + for (i = 0; i < QColorGroup::NColorRoles; i++) + inactcg << editPalette.color(QPalette::Inactive, + (QColorGroup::ColorRole) i).name(); + for (i = 0; i < QColorGroup::NColorRoles; i++) + discg << editPalette.color(QPalette::Disabled, + (QColorGroup::ColorRole) i).name(); + + settings.writeEntry("/qt/font", font.toString()); + settings.writeEntry("/qt/Palette/active", actcg); + settings.writeEntry("/qt/Palette/inactive", inactcg); + settings.writeEntry("/qt/Palette/disabled", discg); + + QStringList libpath = QApplication::libraryPaths(); + QString libpathkey = + QString("/qt/%1.%2/libraryPath").arg( QT_VERSION >> 16 ).arg( (QT_VERSION & 0xff00 ) >> 8 ); + settings.writeEntry(libpathkey, libpath, ':'); + settings.writeEntry("/qt/fontPath", fontpaths, ':'); + settings.writeEntry("/qt/embedFonts", fontembeddingcheckbox->isChecked() ); + settings.writeEntry("/qt/style", gstylecombo->currentText()); + settings.writeEntry("/qt/doubleClickInterval", + dcispin->value()); + settings.writeEntry("/qt/cursorFlashTime", cfispin->value() == 9 ? 0 : cfispin->value() ); + settings.writeEntry("/qt/wheelScrollLines", wslspin->value()); + settings.writeEntry("/qt/resolveSymlinks", resolvelinks->isChecked()); + + QStringList strut; + strut << QString::number(strutwidth->value()); + strut << QString::number(strutheight->value()); + settings.writeEntry("/qt/globalStrut", strut); + + settings.writeEntry("/qt/useRtlExtensions", rtlExtensions->isChecked() ); + +#ifdef Q_WS_X11 + QString style = inputStyle->currentText(); + QString str = "On The Spot"; + if ( style == trUtf8( "Over The Spot" ) ) + str = "Over The Spot"; + else if ( style == trUtf8( "Off The Spot" ) ) + str = "Off The Spot"; + else if ( style == trUtf8( "Root" ) ) + str = "Root"; + settings.writeEntry( "/qt/XIMInputStyle", inputStyle->currentText() ); + +#if !defined(QT_NO_IM_EXTENSIONS) + QString imSwitcher = settings.readEntry("/qt/DefaultInputMethodSwitcher", "imsw-multi"); + settings.writeEntry("/qt/DefaultInputMethodSwitcher", imSwitcher); + int imIndex = inputMethodCombo->currentItem(); + settings.writeEntry("/qt/DefaultInputMethod", inputMethodIdentifiers[imIndex]); +#endif +#endif + + QStringList effects; + if (effectcheckbox->isChecked()) { + effects << "general"; + + switch (menueffect->currentItem()) { + case 1: effects << "animatemenu"; break; + case 2: effects << "fademenu"; break; + } + + switch (comboeffect->currentItem()) { + case 1: effects << "animatecombo"; break; + } + + switch (tooltipeffect->currentItem()) { + case 1: effects << "animatetooltip"; break; + case 2: effects << "fadetooltip"; break; + } + + switch ( toolboxeffect->currentItem() ) { + case 1: effects << "animatetoolbox"; break; + } + } else + effects << "none"; + settings.writeEntry("/qt/GUIEffects", effects); + + QStringList familysubs = QFont::substitutions(); + QStringList::Iterator fit = familysubs.begin(); + while (fit != familysubs.end()) { + QStringList subs = QFont::substitutes(*fit); + settings.writeEntry("/qt/Font Substitutions/" + *fit, subs); + fit++; + } + } + +#if defined(Q_WS_X11) + QApplication::x11_apply_settings(); +#endif // Q_WS_X11 + + setModified(FALSE); + statusBar()->message("Saved changes."); +} + + +void MainWindow::fileExit() +{ + qApp->closeAllWindows(); +} + + +void MainWindow::setModified(bool m) +{ + if (modified == m) + return; + + modified = m; + fileSaveAction->setEnabled(m); +} + + +void MainWindow::buildPalette() +{ + int i; + QColorGroup cg; + QColor btn = buttonMainColor->color(); + QColor back = buttonMainColor2->color(); + QPalette automake( btn, back ); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), automake.active().color( centralFromItem(i) ) ); + + editPalette.setActive( cg ); + buildActiveEffect(); + + cg = editPalette.inactive(); + + QPalette temp( editPalette.active().color( QColorGroup::Button ), + editPalette.active().color( QColorGroup::Background ) ); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), temp.inactive().color( centralFromItem(i) ) ); + + editPalette.setInactive( cg ); + buildInactiveEffect(); + + cg = editPalette.disabled(); + + for (i = 0; i<9; i++) + cg.setColor( centralFromItem(i), temp.disabled().color( centralFromItem(i) ) ); + + editPalette.setDisabled( cg ); + buildDisabledEffect(); + + updateColorButtons(); + + setModified(TRUE); +} + + +void MainWindow::buildActiveEffect() +{ + QColorGroup cg = editPalette.active(); + QColor btn = cg.color( QColorGroup::Button ); + + QPalette temp( btn, btn ); + + for (int i = 0; i<5; i++) + cg.setColor( effectFromItem(i), temp.active().color( effectFromItem(i) ) ); + + editPalette.setActive( cg ); + setPreviewPalette( editPalette ); + + updateColorButtons(); +} + + +void MainWindow::buildInactive() +{ + editPalette.setInactive( editPalette.active() ); + buildInactiveEffect(); +} + + +void MainWindow::buildInactiveEffect() +{ + QColorGroup cg = editPalette.inactive(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setInactive( cg ); + setPreviewPalette( editPalette ); + updateColorButtons(); +} + + +void MainWindow::buildDisabled() +{ + QColorGroup cg = editPalette.active(); + cg.setColor( QColorGroup::ButtonText, darkGray ); + cg.setColor( QColorGroup::Foreground, darkGray ); + cg.setColor( QColorGroup::Text, darkGray ); + cg.setColor( QColorGroup::HighlightedText, darkGray ); + editPalette.setDisabled( cg ); + + buildDisabledEffect(); +} + + +void MainWindow::buildDisabledEffect() +{ + QColorGroup cg = editPalette.disabled(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setDisabled( cg ); + setPreviewPalette( editPalette ); + updateColorButtons(); +} + + +void MainWindow::setPreviewPalette( const QPalette& pal ) +{ + QColorGroup cg; + + switch (paletteCombo->currentItem()) { + case 0: + default: + cg = pal.active(); + break; + case 1: + cg = pal.inactive(); + break; + case 2: + cg = pal.disabled(); + break; + } + previewPalette.setActive( cg ); + previewPalette.setInactive( cg ); + previewPalette.setDisabled( cg ); + + previewFrame->setPreviewPalette(previewPalette); +} + + +void MainWindow::updateColorButtons() +{ + buttonMainColor->setColor( editPalette.active().color( QColorGroup::Button )); + buttonMainColor2->setColor( editPalette.active().color( QColorGroup::Background )); +} + + +void MainWindow::tunePalette() +{ + bool ok; + QPalette pal = PaletteEditorAdvanced::getPalette(&ok, editPalette, + backgroundMode(), this); + if (! ok) + return; + + editPalette = pal; + setPreviewPalette(editPalette); + setModified(TRUE); +} + + +void MainWindow::paletteSelected(int) +{ + setPreviewPalette(editPalette); +} + + +void MainWindow::styleSelected(const QString &stylename) +{ + QStyle *style = QStyleFactory::create(stylename); + if (! style) + return; + + setStyleHelper(previewFrame, style); + delete previewstyle; + previewstyle = style; + + setModified(TRUE); +} + + +void MainWindow::familySelected(const QString &family) +{ + QFontDatabase db; + QStringList styles = db.styles(family); + stylecombo->clear(); + stylecombo->insertStringList(styles); + familysubcombo->insertItem(family); + buildFont(); +} + + +void MainWindow::buildFont() +{ + QFontDatabase db; + QFont font = db.font(familycombo->currentText(), + stylecombo->currentText(), + psizecombo->currentText().toInt()); + samplelineedit->setFont(font); + setModified(TRUE); +} + + +void MainWindow::substituteSelected(const QString &family) +{ + QStringList subs = QFont::substitutes(family); + sublistbox->clear(); + sublistbox->insertStringList(subs); +} + + +void MainWindow::removeSubstitute() +{ + if (sublistbox->currentItem() < 0 || + uint(sublistbox->currentItem()) > sublistbox->count()) + return; + + int item = sublistbox->currentItem(); + QStringList subs = QFont::substitutes(familysubcombo->currentText()); + subs.remove(subs.at(sublistbox->currentItem())); + sublistbox->clear(); + sublistbox->insertStringList(subs); + if (uint(item) > sublistbox->count()) + item = int(sublistbox->count()) - 1; + sublistbox->setCurrentItem(item); + QFont::removeSubstitution(familysubcombo->currentText()); + QFont::insertSubstitutions(familysubcombo->currentText(), subs); + setModified(TRUE); +} + + +void MainWindow::addSubstitute() +{ + if (sublistbox->currentItem() < 0 || + uint(sublistbox->currentItem()) > sublistbox->count()) { + QFont::insertSubstitution(familysubcombo->currentText(), choosesubcombo->currentText()); + QStringList subs = QFont::substitutes(familysubcombo->currentText()); + sublistbox->clear(); + sublistbox->insertStringList(subs); + setModified(TRUE); + return; + } + + int item = sublistbox->currentItem(); + QFont::insertSubstitution(familysubcombo->currentText(), choosesubcombo->currentText()); + QStringList subs = QFont::substitutes(familysubcombo->currentText()); + sublistbox->clear(); + sublistbox->insertStringList(subs); + sublistbox->setCurrentItem(item); + setModified(TRUE); +} + + +void MainWindow::downSubstitute() +{ + if (sublistbox->currentItem() < 0 || + uint(sublistbox->currentItem()) >= sublistbox->count()) + return; + + int item = sublistbox->currentItem(); + QStringList subs = QFont::substitutes(familysubcombo->currentText()); + QStringList::Iterator it = subs.at(item); + QString fam = *it; + subs.remove(it); + it = subs.at(item); + subs.insert(++it, fam); + sublistbox->clear(); + sublistbox->insertStringList(subs); + sublistbox->setCurrentItem(item + 1); + QFont::removeSubstitution(familysubcombo->currentText()); + QFont::insertSubstitutions(familysubcombo->currentText(), subs); + setModified(TRUE); +} + + +void MainWindow::upSubstitute() +{ + if (sublistbox->currentItem() < 1) + return; + + int item = sublistbox->currentItem(); + QStringList subs = QFont::substitutes(familysubcombo->currentText()); + QStringList::Iterator it = subs.at(item); + QString fam = *it; + subs.remove(it); + it = subs.at(item - 1); + subs.insert(it, fam); + sublistbox->clear(); + sublistbox->insertStringList(subs); + sublistbox->setCurrentItem(item - 1); + QFont::removeSubstitution(familysubcombo->currentText()); + QFont::insertSubstitutions(familysubcombo->currentText(), subs); + setModified(TRUE); +} + + +void MainWindow::removeLibpath() +{ + if (libpathlistbox->currentItem() < 0 || + uint(libpathlistbox->currentItem()) > libpathlistbox->count()) + return; + + int item = libpathlistbox->currentItem(); + QStringList paths = QApplication::libraryPaths(); + paths.remove(paths.at(libpathlistbox->currentItem())); + libpathlistbox->clear(); + libpathlistbox->insertStringList(paths); + if (uint(item) > libpathlistbox->count()) + item = int(libpathlistbox->count()) - 1; + libpathlistbox->setCurrentItem(item); + QApplication::setLibraryPaths(paths); + setModified(TRUE); +} + + +void MainWindow::addLibpath() +{ + if (libpathlineedit->text().isEmpty()) + return; + + if (libpathlistbox->currentItem() < 0 || + uint(libpathlistbox->currentItem()) > libpathlistbox->count()) { + QStringList paths = QApplication::libraryPaths(); + paths.append(libpathlineedit->text()); + libpathlistbox->clear(); + libpathlistbox->insertStringList(paths); + QApplication::setLibraryPaths(paths); + setModified(TRUE); + + return; + } + + int item = libpathlistbox->currentItem(); + QStringList paths =QApplication::libraryPaths(); + paths.insert(++paths.at(libpathlistbox->currentItem()), + libpathlineedit->text()); + libpathlistbox->clear(); + libpathlistbox->insertStringList(paths); + libpathlistbox->setCurrentItem(item); + QApplication::setLibraryPaths(paths); + setModified(TRUE); +} + + +void MainWindow::downLibpath() +{ + if (libpathlistbox->currentItem() < 0 || + uint(libpathlistbox->currentItem()) >= libpathlistbox->count() - 1) + return; + + int item = libpathlistbox->currentItem(); + QStringList paths = QApplication::libraryPaths(); + QStringList::Iterator it = paths.at(item); + QString fam = *it; + paths.remove(it); + it = paths.at(item); + paths.insert(++it, fam); + libpathlistbox->clear(); + libpathlistbox->insertStringList(paths); + libpathlistbox->setCurrentItem(item + 1); + QApplication::setLibraryPaths(paths); + setModified(TRUE); +} + + +void MainWindow::upLibpath() +{ + if (libpathlistbox->currentItem() < 1) + return; + + int item = libpathlistbox->currentItem(); + QStringList paths = QApplication::libraryPaths(); + QStringList::Iterator it = paths.at(item); + QString fam = *it; + paths.remove(it); + it = paths.at(item - 1); + paths.insert(it, fam); + libpathlistbox->clear(); + libpathlistbox->insertStringList(paths); + libpathlistbox->setCurrentItem(item - 1); + QApplication::setLibraryPaths(paths); + setModified(TRUE); +} + + +void MainWindow::browseLibpath() +{ + QString dirname = QFileDialog::getExistingDirectory(QString::null, this, 0, + tr("Select a Directory")); + if (dirname.isNull()) + return; + + libpathlineedit->setText(dirname); +} + + +void MainWindow::removeFontpath() +{ + if (fontpathlistbox->currentItem() < 0 || + uint(fontpathlistbox->currentItem()) > fontpathlistbox->count()) + return; + + int item = fontpathlistbox->currentItem(); + fontpaths.remove(fontpaths.at(fontpathlistbox->currentItem())); + fontpathlistbox->clear(); + fontpathlistbox->insertStringList(fontpaths); + if (uint(item) > fontpathlistbox->count()) + item = int(fontpathlistbox->count()) - 1; + fontpathlistbox->setCurrentItem(item); + setModified(TRUE); +} + + +void MainWindow::addFontpath() +{ + if (fontpathlineedit->text().isEmpty()) + return; + + if (fontpathlistbox->currentItem() < 0 || + uint(fontpathlistbox->currentItem()) > fontpathlistbox->count()) { + fontpaths.append(fontpathlineedit->text()); + fontpathlistbox->clear(); + fontpathlistbox->insertStringList(fontpaths); + setModified(TRUE); + + return; + } + + int item = fontpathlistbox->currentItem(); + fontpaths.insert(++fontpaths.at(fontpathlistbox->currentItem()), + fontpathlineedit->text()); + fontpathlistbox->clear(); + fontpathlistbox->insertStringList(fontpaths); + fontpathlistbox->setCurrentItem(item); + setModified(TRUE); +} + + +void MainWindow::downFontpath() +{ + if (fontpathlistbox->currentItem() < 0 || + uint(fontpathlistbox->currentItem()) >= fontpathlistbox->count() - 1) + return; + + int item = fontpathlistbox->currentItem(); + QStringList::Iterator it = fontpaths.at(item); + QString fam = *it; + fontpaths.remove(it); + it = fontpaths.at(item); + fontpaths.insert(++it, fam); + fontpathlistbox->clear(); + fontpathlistbox->insertStringList(fontpaths); + fontpathlistbox->setCurrentItem(item + 1); + setModified(TRUE); +} + + +void MainWindow::upFontpath() +{ + if (fontpathlistbox->currentItem() < 1) + return; + + int item = fontpathlistbox->currentItem(); + QStringList::Iterator it = fontpaths.at(item); + QString fam = *it; + fontpaths.remove(it); + it = fontpaths.at(item - 1); + fontpaths.insert(it, fam); + fontpathlistbox->clear(); + fontpathlistbox->insertStringList(fontpaths); + fontpathlistbox->setCurrentItem(item - 1); + setModified(TRUE); +} + + +void MainWindow::browseFontpath() +{ + QString dirname = QFileDialog::getExistingDirectory(QString::null, this, 0, + tr("Select a Directory")); + if (dirname.isNull()) + return; + + fontpathlineedit->setText(dirname); +} + + +void MainWindow::somethingModified() +{ + setModified(TRUE); +} + + +void MainWindow::helpAbout() +{ + QMessageBox::about(this, tr("Qt Configuration"), + tr(about_text)); +} + + +void MainWindow::helpAboutQt() +{ + QMessageBox::aboutQt(this, tr("Qt Configuration")); +} + + +void MainWindow::pageChanged(QWidget *page) +{ + if (page == tab) + helpview->setText(tr(appearance_text)); + else if (page == tab_2) + helpview->setText(tr(font_text)); + else if (page == tab_3) + helpview->setText(tr(interface_text)); + else if (page == tab_4) + helpview->setText(tr(libpath_text)); + else if (page == tab_5) + helpview->setText(tr(printer_text)); +} + + +void MainWindow::closeEvent(QCloseEvent *e) +{ + if (modified) { + switch(QMessageBox::warning(this, tr("Save Changes"), + tr("Save changes to settings?"), + tr("&Yes"), tr("&No"), tr("&Cancel"), 0, 2)) { + case 0: // save + qApp->processEvents(); + fileSave(); + + // fall through intended + case 1: // don't save + e->accept(); + break; + + case 2: // cancel + e->ignore(); + break; + + default: break; + } + } else + e->accept(); +} diff --git a/tools/qtconfig/mainwindow.h b/tools/qtconfig/mainwindow.h new file mode 100644 index 0000000..056edbb --- /dev/null +++ b/tools/qtconfig/mainwindow.h @@ -0,0 +1,104 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include "mainwindowbase.h" + + +class MainWindow : public MainWindowBase +{ + Q_OBJECT + +public: + MainWindow(); + ~MainWindow(); + + void closeEvent(QCloseEvent *); + + +public slots: + virtual void buildPalette(); + virtual void buildFont(); + virtual void tunePalette(); + virtual void paletteSelected(int); + virtual void styleSelected(const QString &); + virtual void familySelected(const QString &); + virtual void substituteSelected(const QString &); + virtual void removeSubstitute(); + virtual void addSubstitute(); + virtual void downSubstitute(); + virtual void upSubstitute(); + virtual void removeLibpath(); + virtual void addLibpath(); + virtual void downLibpath(); + virtual void upLibpath(); + virtual void browseLibpath(); + virtual void removeFontpath(); + virtual void addFontpath(); + virtual void downFontpath(); + virtual void upFontpath(); + virtual void browseFontpath(); + virtual void fileSave(); + virtual void fileExit(); + virtual void somethingModified(); + virtual void helpAbout(); + virtual void helpAboutQt(); + virtual void pageChanged(QWidget *); + + +private: + void buildActive(); + void buildActiveEffect(); + void buildInactive(); + void buildInactiveEffect(); + void buildDisabled(); + void buildDisabledEffect(); + + void updateColorButtons(); + void updateFontSample(); + + void setPreviewPalette(const QPalette &); + + void setModified(bool); + + QPalette editPalette, previewPalette; + QStyle *previewstyle; + QStringList fontpaths; + QStringList inputMethodIdentifiers; + bool modified; +}; + + +#endif // MAINWINDOW_H diff --git a/tools/qtconfig/mainwindowbase.ui b/tools/qtconfig/mainwindowbase.ui new file mode 100644 index 0000000..0cf65df --- /dev/null +++ b/tools/qtconfig/mainwindowbase.ui @@ -0,0 +1,1846 @@ + +MainWindowBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + MainWindowBase + + + + 0 + 0 + 700 + 600 + + + + Qt Configuration + + + appicon.png + + + + unnamed + + + 8 + + + 4 + + + + helpview + + + + 200 + 0 + + + + <p align=center><b>Documentation</b></p> +<p>This QTextView will display a brief explanation about the current page, so that the user isn't confused about the settings he/she is twiddling.</p> + + + + + TabWidget3 + + + + tab + + + Appearance + + + + unnamed + + + 4 + + + 4 + + + + GroupBox40 + + + GUI Style + + + + unnamed + + + 8 + + + 4 + + + + gstylebuddy + + + Select GUI &Style: + + + gstylecombo + + + + + gstylecombo + + + + + + + groupAutoPalette + + + + 5 + 4 + 0 + 0 + + + + Build Palette + + + AlignAuto + + + + unnamed + + + 8 + + + 4 + + + + labelMainColor + + + &3-D Effects: + + + buttonMainColor + + + + + buttonMainColor + + + + + labelMainColor2 + + + + 1 + 1 + 0 + 0 + + + + + 50 + 0 + + + + 1 + + + 0 + + + 0 + + + Back&ground: + + + AlignVCenter + + + buttonMainColor2 + + + + + buttonMainColor2 + + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 70 + 20 + + + + + + btnAdvanced + + + &Tune Palette... + + + + + + + GroupBox126 + + + + 5 + 7 + 0 + 0 + + + + Preview + + + + unnamed + + + 8 + + + 4 + + + + TextLabel1 + + + Select &Palette: + + + paletteCombo + + + + + + Active Palette + + + + + Inactive Palette + + + + + Disabled Palette + + + + paletteCombo + + + + + previewFrame + + + + 7 + 7 + 0 + 0 + + + + + 410 + 260 + + + + + + + + + + tab + + + Fonts + + + + unnamed + + + 8 + + + 4 + + + + GroupBox1 + + + Default Font + + + + unnamed + + + 8 + + + 4 + + + + stylecombo + + + true + + + false + + + + + familycombo + + + true + + + false + + + + + psizecombo + + + true + + + true + + + false + + + + + stylebuddy + + + &Style: + + + stylecombo + + + + + psizebuddy + + + &Point Size: + + + psizecombo + + + + + familybuddy + + + F&amily: + + + familycombo + + + + + samplelineedit + + + Sample Text + + + AlignHCenter + + + + + + + GroupBox2 + + + Box + + + Sunken + + + Font Substitution + + + + unnamed + + + 8 + + + 4 + + + + Layout2 + + + + unnamed + + + 0 + + + 4 + + + + famsubbuddy + + + S&elect or Enter a Family: + + + familysubcombo + + + + + familysubcombo + + + true + + + true + + + false + + + + + + + Line1 + + + HLine + + + Sunken + + + Horizontal + + + + + TextLabel5 + + + Current Substitutions: + + + + + sublistbox + + + + + Layout3 + + + + unnamed + + + 0 + + + 4 + + + + PushButton2 + + + Up + + + + + PushButton3 + + + Down + + + + + PushButton4 + + + Remove + + + + + + + Line2 + + + HLine + + + Sunken + + + Horizontal + + + + + Layout11 + + + + unnamed + + + 0 + + + 4 + + + + choosebuddy + + + Select s&ubstitute Family: + + + choosesubcombo + + + + + choosesubcombo + + + true + + + false + + + + + PushButton1 + + + Add + + + + + + + + + + + tab + + + Interface + + + + unnamed + + + + GroupBox4 + + + Feel Settings + + + + unnamed + + + 8 + + + 4 + + + + dcispin + + + ms + + + 10000 + + + 10 + + + + + dcibuddy + + + &Double Click Interval: + + + dcispin + + + + + cfispin + + + ms + + + 10000 + + + 9 + + + No blinking + + + + + cfibuddy + + + &Cursor Flash Time: + + + cfispin + + + + + wslspin + + + lines + + + 20 + + + 1 + + + + + wslbuddy + + + Wheel &Scroll Lines: + + + wslspin + + + + + resolvelinks + + + Resolve symlinks in URLs + + + + + + + GroupBox3 + + + GUI Effects + + + + unnamed + + + 8 + + + 4 + + + + effectcheckbox + + + &Enable + + + Alt+E + + + + + effectbase + + + NoFrame + + + Plain + + + + unnamed + + + 0 + + + 4 + + + + meffectbuddy + + + &Menu Effect: + + + menueffect + + + + + ceffectbuddy + + + C&omboBox Effect: + + + comboeffect + + + + + teffectbuddy + + + &ToolTip Effect: + + + tooltipeffect + + + + + beffectbuddy + + + Tool&Box Effect: + + + toolboxeffect + + + + + + Disable + + + + + Animate + + + + + Fade + + + + menueffect + + + 0 + + + true + + + + + + Disable + + + + + Animate + + + + comboeffect + + + + + + Disable + + + + + Animate + + + + + Fade + + + + tooltipeffect + + + + + + Disable + + + + + Animate + + + + toolboxeffect + + + + + + + + + GroupBox5 + + + Global Strut + + + + unnamed + + + 8 + + + 4 + + + + swbuddy + + + Minimum &Width: + + + strutwidth + + + + + shbuddy + + + Minimum Hei&ght: + + + strutheight + + + + + strutwidth + + + pixels + + + 1000 + + + + + strutheight + + + pixels + + + 1000 + + + + + + + rtlExtensions + + + Enhanced support for languages written right-to-left + + + + + inputStyleLabel + + + XIM Input Style: + + + + + + On The Spot + + + + + Over The Spot + + + + + Off The Spot + + + + + Root + + + + inputStyle + + + 0 + + + + + inputMethodLabel + + + Default Input Method: + + + + + inputMethodCombo + + + + + spacer5 + + + Vertical + + + Expanding + + + + 20 + 30 + + + + + + + + tab + + + Library Paths + + + + unnamed + + + 4 + + + 4 + + + + GroupBox39 + + + Library Paths + + + + unnamed + + + 8 + + + 4 + + + + Layout68 + + + + unnamed + + + 0 + + + 4 + + + + libpathlistbox + + + StyledPanel + + + Sunken + + + + + PushButton8 + + + Down + + + + + PushButton9 + + + Remove + + + + + PushButton7 + + + Up + + + + + + + Layout71 + + + + unnamed + + + 0 + + + 4 + + + + Spacer1_2 + + + Horizontal + + + Minimum + + + + 20 + 20 + + + + + + TextLabel15 + + + Press the <b>Browse</b> button or enter a directory and press Enter to add them to the list. + + + + + libpathlineedit + + + + + PushButton5 + + + Browse... + + + + + PushButton6 + + + Add + + + + + + + + + + + tab + + + Printer + + + + unnamed + + + 8 + + + 4 + + + + fontembeddingcheckbox + + + Enable Font embedding + + + true + + + + + GroupBox10 + + + + 5 + 7 + 0 + 0 + + + + Font Paths + + + + unnamed + + + 8 + + + 4 + + + + Layout9 + + + + unnamed + + + 0 + + + 4 + + + + PushButton11 + + + Up + + + + + PushButton13 + + + Remove + + + + + fontpathlistbox + + + + + PushButton12 + + + Down + + + + + + + Layout10 + + + + unnamed + + + 0 + + + 4 + + + + Spacer4 + + + Horizontal + + + Minimum + + + + 20 + 20 + + + + + + TextLabel15_2 + + + Press the <b>Browse</b> button or enter a directory and press Enter to add them to the list. + + + + + PushButton15 + + + Add + + + + + fontpathlineedit + + + + + PushButton14 + + + Browse... + + + + + + + + + + + + + + menubar + + + + + + + + + + + + + + + + ColorButton +
    colorbutton.h
    + + 40 + 25 + + 0 + + 5 + 5 + 0 + 0 + + image0 + clicked() + colorChanged(const QColor &) + changed() + color + pixmap + scale +
    + + PreviewFrame +
    previewframe.h
    + + 200 + 200 + + 0 + + 5 + 5 + 0 + 0 + + image1 +
    +
    + + + + fileSaveAction + + + + + + Save + + + &Save + + + Ctrl+S + + + + + fileExitAction + + + Exit + + + E&xit + + + + + + + + helpAboutAction + + + About + + + &About + + + + + + + + helpAboutQtAction + + + About Qt + + + About &Qt + + + + + + 789c6dd7594f23471007f0f7fd14d6d6db2aaaf58c3db647511eb831b7317794879ac30760cc61c010e5bba7dcf5af5688167664fdb66bbaababbb67cccf1f8dab93c3c68f9fdf5e16b298968d7222cf8d1fd5eb6cf6f1e75f7ffcfded7b9a3656ff9aad46fafdb76fdf078b46d9389a3fd42bf04841699e964933b830b79a7019dd0b96955b895b5a703bcd572e08eea576ff6570ae0eedd477b792103f854b8b2fc6d1163f77237e646e37113f89b6f8307e3bf1785a8b0eedbc696eb7ad9db7e01ee6476ee4ffe0c6fd158c7c69182cde4eec6e87fea50dfbf8176e6ba7d07f96669999cfa325ccaf862bcc97a36dbccf60f178cee11cde706761f16917ae30fe6b7488a7851bf14d7327417f676eb4f756eea41e2f57e6d83e83919f6cba117f04235fd9765b3b0fa36dfc398cf973edc67a6fb951ffe768ab6765ee26b8dff213ef5f4630e2b9e7463ea7ee8ee5ff60ee2618af8eb6fe3238437eb91bf1299cdbfacad3cadd5617f5a11738c7fe4adcb8ffd68d7aeec15e8fc3683b9f62ee2518ef33dafa3f75e3bc957086f86eb4d56f3db8e8e6dd56f01a5cc1bbe65e629673d8ebd18d0efdc9058cf9f2c08df9e630ce037db8719ec37c7a9a7fb708f10267b65e7cef46fb3e9ca3fd23dad6ef0cf67abe99f304f95ec3a8871cbb71be52d8d777e8b6fee412f6f958be3adf5ea817b561afe7d86ded7c67ce13c46fc37ede2766c17a17059cd9f38e466e8c3f8eb6fd700f0b9ef7095c37cd3d37de178f2be76dcf876fa343bd790267f012f67a77cc319f69b4ed872e2ca8e732daeabfe3c6fa9cc235f21f9b8bd4f2a5cd687bfedbfd659ee7ede017b842becf6eb44fa3cbd0df8559b0ffe808ceb0ff37e01afba3652e52cc87a26dbe276ecca7097790ff73b4cdef0616ac4fdf6df1c2d1d67ee8c6f80318eb4bd1180ff529513f0ecf7b694b62f5a002ceccb2662e523c2fb7605f9f0fd8fbbf75e3bc2dcd3e9ebcb9f17ce8c05e8f83685bcf701e44eb2db65e4fd1b65eebe62245be53b8c6f3ffdd8dfd3933fbf884761f5f0edcd88f951bf118bf44bde926dae24fe01ae7af76e3f9169e2f45bb143c0f5fdcf6fea23b18f773eac6f3e63ddac6db75e37df5e8c6fbae65aebcde6d37beaf84f528aa52f03c9dc3359ea79939c627d136deab1befaf75b883ef23e76e3ccfaea36d7dc2f795322b05ebfb0ad738af7db7ad371f99fd7e59b8b13f276e9cdf1318f5e54337e6d78cb67cf761ec170efba1acaa1afd9db92d3f3a36d729ea77efc6f33cbccf2beddfe6478fe6d85e45dbfd851bf1577007f5d877e3bc86f5a9ea3a2d6cffdfc1debe116df5db73a39e37b0e777191dda257c7fa83b6e8a2eaae00eeceb13d6b7d69f325b79b058fd32b170c1a55ebffaac2ccae2b9e6118f79c253bd6ef9ee3fd7587fef79c60f7acf3cc617fcc84ffcac6d8ffcc20b7ee5377ee7257ff027aff1bac66ff0269716cf5b1ab7cd3bbcabb17ddee37d3ee0433ee2633ee1019ff290cff89c2ff89229c48b66f1ac3d5df135df7093134eb9c56dcef4b3c35dee71ce393111dbfa8c784a4205955451cd1d1ad1982634a55bbad3f80eddd38c1ef882e66cf52ab5ff2b8d7ea4277aa6175ad06bb866f446efb4d4df0ffad4fed762ffb7b44e1b9cd2266dd142c75e5ddb3cd0bb3e347a477bd9d5f83ee245e3f7689f0ee830f67d44c77412ee186946033aa5e197fecfe85c7bf7be2fe892aee89a6ea84989f6bfa434f4eff9df52c509b5d0779b32ea684d13ea528f728d1e882ebfce37f6cf077422b4ea5b440ad14af1a15452ab473aee52c65ff39789b64fe955f44eb9937b5d858c5b32d377c0c32a7fee7ecd5fe61aff284ff22c2fb290577993775db1443fb53ef2219f5ff2bf93356d5b970dd9d41eb77820dbb223bbab155ed55ffab2f725ffb1eccb81aed6931cca116ab490633909d10339fd5ffdef795d869ae7923bc27226e772415d5986b51d683663b9d4fcfbb1ff190fe54aaec35aeaa577ee20f24673e94b531249a585fc2b69ebfe3ed7dae91f75ba964b5c03e9d344ba1add93bce0826c3f87f3b2a9fb6f18aeba10ba2f563f25eb1b563771a5d17531e2513c5fba538b3111cd690dd73c7ef6a95f4c8aa99de12fe77da4951de9ffffea730be7fd9fdfbffd0b690edc6c + + + 789c6d92cd4ec3300c80ef7d8a68b94da8dbba51a9423c02882312e210c7f95d3a241807847877eca4e93a84d54af9fcd5899374b316cf4f0f62bd693eceea1cb4d05ebd8b357e8ee3d7cbebfd77b3ea3a41cfae17bbd54db36a85168f6f27c3634563b9dfedb7db2da3acd8778cb1607f5bd0331ed4411f142330f65db5a1e0301444c64157d41507cd980a6a53d67515cbc723a3c66a6dc5624dc532d5a9a0b5058f8cd6566cdb56aaeba05436a0f43210a4826294369c31c63a4404002f55362c02e50d2f8001207a2f6531d4d131e729128227a32643152ed14ce86c4a09168605440ac031a57031b404091f3d861872d16c6ca9a01d87885cb430b9c29cac8b90122e0c7205094b4dd374b3a16d70056f15fc1f6323d8bc550757b3510680d3fc5e75e0f2b72e00f2212cbb464701d45d449796060199318490079775e8dc4b660e980c9dad9f1dd2f10428b7d02a991d9f58001ec0747374dbf24fa8c9fcff87fcdc35bf3990fd9c + + + + + fontpathlineedit + returnPressed() + MainWindowBase + addFontpath() + + + PushButton15 + clicked() + MainWindowBase + addFontpath() + + + PushButton6 + clicked() + MainWindowBase + addLibpath() + + + libpathlineedit + returnPressed() + MainWindowBase + addLibpath() + + + PushButton1 + clicked() + MainWindowBase + addSubstitute() + + + PushButton14 + clicked() + MainWindowBase + browseFontpath() + + + PushButton5 + clicked() + MainWindowBase + browseLibpath() + + + stylecombo + activated(int) + MainWindowBase + buildFont() + + + psizecombo + activated(int) + MainWindowBase + buildFont() + + + PushButton12 + clicked() + MainWindowBase + downFontpath() + + + PushButton8 + clicked() + MainWindowBase + downLibpath() + + + PushButton3 + clicked() + MainWindowBase + downSubstitute() + + + familycombo + activated(const QString&) + MainWindowBase + familySelected(const QString&) + + + fileExitAction + activated() + MainWindowBase + fileExit() + + + fileSaveAction + activated() + MainWindowBase + fileSave() + + + helpAboutAction + activated() + MainWindowBase + helpAbout() + + + helpAboutQtAction + activated() + MainWindowBase + helpAboutQt() + + + TabWidget3 + currentChanged(QWidget*) + MainWindowBase + pageChanged(QWidget*) + + + paletteCombo + activated(int) + MainWindowBase + paletteSelected(int) + + + PushButton13 + clicked() + MainWindowBase + removeFontpath() + + + PushButton9 + clicked() + MainWindowBase + removeLibpath() + + + PushButton4 + clicked() + MainWindowBase + removeSubstitute() + + + effectcheckbox + toggled(bool) + effectbase + setEnabled(bool) + + + fontembeddingcheckbox + toggled(bool) + GroupBox10 + setEnabled(bool) + + + toolboxeffect + activated(int) + MainWindowBase + somethingModified() + + + dcispin + valueChanged(int) + MainWindowBase + somethingModified() + + + cfispin + valueChanged(int) + MainWindowBase + somethingModified() + + + wslspin + valueChanged(int) + MainWindowBase + somethingModified() + + + menueffect + activated(int) + MainWindowBase + somethingModified() + + + comboeffect + activated(int) + MainWindowBase + somethingModified() + + + tooltipeffect + activated(int) + MainWindowBase + somethingModified() + + + strutwidth + valueChanged(int) + MainWindowBase + somethingModified() + + + strutheight + valueChanged(int) + MainWindowBase + somethingModified() + + + effectcheckbox + toggled(bool) + MainWindowBase + somethingModified() + + + resolvelinks + toggled(bool) + MainWindowBase + somethingModified() + + + fontembeddingcheckbox + clicked() + MainWindowBase + somethingModified() + + + rtlExtensions + toggled(bool) + MainWindowBase + somethingModified() + + + inputStyle + activated(int) + MainWindowBase + somethingModified() + + + inputMethodCombo + activated(int) + MainWindowBase + somethingModified() + + + gstylecombo + activated(const QString&) + MainWindowBase + styleSelected(const QString&) + + + familysubcombo + activated(const QString&) + MainWindowBase + substituteSelected(const QString&) + + + btnAdvanced + clicked() + MainWindowBase + tunePalette() + + + PushButton11 + clicked() + MainWindowBase + upFontpath() + + + PushButton7 + clicked() + MainWindowBase + upLibpath() + + + PushButton2 + clicked() + MainWindowBase + upSubstitute() + + + + helpview + TabWidget3 + familycombo + stylecombo + psizecombo + samplelineedit + familysubcombo + PushButton2 + PushButton3 + PushButton4 + choosesubcombo + PushButton1 + dcispin + cfispin + wslspin + effectcheckbox + menueffect + comboeffect + tooltipeffect + strutwidth + strutheight + libpathlineedit + PushButton5 + PushButton6 + PushButton7 + PushButton8 + PushButton9 + sublistbox + libpathlistbox + + + init() + destroy() + addFontpath() + addLibpath() + addSubstitute() + browseFontpath() + browseLibpath() + buildFont() + buildPalette() + downFontpath() + downLibpath() + downSubstitute() + familySelected( const QString & ) + fileExit() + fileSave() + helpAbout() + helpAboutQt() + new_slot() + pageChanged( QWidget * ) + paletteSelected( int ) + removeFontpath() + removeLibpath() + removeSubstitute() + somethingModified() + styleSelected( const QString & ) + substituteSelected( const QString & ) + tunePalette() + upFontpath() + upLibpath() + upSubstitute() + + + + + colorbutton.h + colorbutton.h + previewframe.h + +
    diff --git a/tools/qtconfig/paletteeditoradvanced.cpp b/tools/qtconfig/paletteeditoradvanced.cpp new file mode 100644 index 0000000..3944970 --- /dev/null +++ b/tools/qtconfig/paletteeditoradvanced.cpp @@ -0,0 +1,615 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "paletteeditoradvanced.h" +#include "colorbutton.h" + +#include +#include +#include +#include +#include +#include +#include + +/*! + Class used by PaletteEditor for bold combobox items +*/ + +class BoldListBoxText : public QListBoxText +{ +public: + BoldListBoxText( QString text, QListBox* lb = 0 ); + +protected: + virtual void paint( QPainter* ); +}; + +BoldListBoxText::BoldListBoxText( QString text, QListBox* lb ) + : QListBoxText( lb ) +{ + setText( text ); +} + +void BoldListBoxText::paint( QPainter* painter ) +{ + QFont f = painter->font(); + f.setBold( TRUE ); + painter->setFont( f ); + + QListBoxText::paint( painter ); +} + +PaletteEditorAdvanced::PaletteEditorAdvanced( QWidget * parent, + const char * name, bool modal, WFlags f ) + : PaletteEditorAdvancedBase( parent, name, modal, f ), selectedPalette(0) +{ + editPalette = QApplication::palette(); + setPreviewPalette( editPalette ); +} + +PaletteEditorAdvanced::~PaletteEditorAdvanced() +{ +} + +void PaletteEditorAdvanced::onToggleBuildInactive( bool v ) +{ + if (selectedPalette == 1) { + groupCentral->setDisabled(v); + groupEffect->setDisabled(v); + } + + if (v) { + buildInactive(); + updateColorButtons(); + } +} + +void PaletteEditorAdvanced::onToggleBuildDisabled( bool v ) +{ + if (selectedPalette == 2) { + groupCentral->setDisabled(v); + groupEffect->setDisabled(v); + } + + if (v) { + buildDisabled(); + updateColorButtons(); + } +} + +void PaletteEditorAdvanced::paletteSelected(int p) +{ + selectedPalette = p; + + if(p == 1) { // inactive + groupCentral->setDisabled(checkBuildInactive->isChecked()); + groupEffect->setDisabled(checkBuildInactive->isChecked()); + } + else if (p == 2) { // disabled + groupCentral->setDisabled(checkBuildDisabled->isChecked()); + groupEffect->setDisabled(checkBuildDisabled->isChecked()); + } + else { + groupCentral->setEnabled(TRUE); + groupEffect->setEnabled(TRUE); + } + updateColorButtons(); +} + +void PaletteEditorAdvanced::onChooseCentralColor() +{ + switch(selectedPalette) { + case 0: + default: + mapToActiveCentralRole( buttonCentral->color() ); + break; + case 1: + mapToInactiveCentralRole( buttonCentral->color() ); + break; + case 2: + mapToDisabledCentralRole( buttonCentral->color() ); + break; + } + updateColorButtons(); +} + +void PaletteEditorAdvanced::onChooseEffectColor() +{ + switch(selectedPalette) { + case 0: + default: + mapToActiveEffectRole( buttonEffect->color() ); + break; + case 1: + mapToInactiveEffectRole( buttonEffect->color() ); + break; + case 2: + mapToDisabledEffectRole( buttonEffect->color() ); + break; + } + updateColorButtons(); +} + +void PaletteEditorAdvanced::onToggleBuildEffects( bool on ) +{ + if (!on) return; + buildActiveEffect(); + buildInactiveEffect(); + buildDisabledEffect(); +} + +QColorGroup::ColorRole PaletteEditorAdvanced::centralFromItem( int item ) +{ + switch( item ) { + case 0: + return QColorGroup::Background; + case 1: + return QColorGroup::Foreground; + case 2: + return QColorGroup::Button; + case 3: + return QColorGroup::Base; + case 4: + return QColorGroup::Text; + case 5: + return QColorGroup::BrightText; + case 6: + return QColorGroup::ButtonText; + case 7: + return QColorGroup::Highlight; + case 8: + return QColorGroup::HighlightedText; + case 9: + return QColorGroup::Link; + case 10: + return QColorGroup::LinkVisited; + default: + return QColorGroup::NColorRoles; + } +} + +QColorGroup::ColorRole PaletteEditorAdvanced::effectFromItem( int item ) +{ + switch( item ) { + case 0: + return QColorGroup::Light; + case 1: + return QColorGroup::Midlight; + case 2: + return QColorGroup::Mid; + case 3: + return QColorGroup::Dark; + case 4: + return QColorGroup::Shadow; + default: + return QColorGroup::NColorRoles; + } +} + +void PaletteEditorAdvanced::onCentral( int item ) +{ + QColor c; + + switch(selectedPalette) { + case 0: + default: + c = editPalette.active().color( centralFromItem(item) ); + break; + case 1: + c = editPalette.inactive().color( centralFromItem(item) ); + break; + case 2: + c = editPalette.disabled().color( centralFromItem(item) ); + break; + } + + buttonCentral->setColor(c); +} + +void PaletteEditorAdvanced::onEffect( int item ) +{ + QColor c; + switch(selectedPalette) { + case 0: + default: + c = editPalette.active().color( effectFromItem(item) ); + break; + case 1: + editPalette.inactive().color( effectFromItem(item) ); + break; + case 2: + editPalette.disabled().color( effectFromItem(item) ); + break; + } + buttonEffect->setColor(c); +} + +void PaletteEditorAdvanced::mapToActiveCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.active(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setActive( cg ); + + buildActiveEffect(); + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToActiveEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.active(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setActive( cg ); + + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToActivePixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.active(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + editPalette.setActive( cg ); + + + buildActiveEffect(); + if(checkBuildInactive->isChecked()) + buildInactive(); + if(checkBuildDisabled->isChecked()) + buildDisabled(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactiveCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.inactive(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setInactive( cg ); + + buildInactiveEffect(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactiveEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.inactive(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setInactive( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToInactivePixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.inactive(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + editPalette.setInactive( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledCentralRole( const QColor& c ) +{ + QColorGroup cg = editPalette.disabled(); + cg.setColor( centralFromItem(comboCentral->currentItem()), c ); + editPalette.setDisabled( cg ); + + buildDisabledEffect(); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledEffectRole( const QColor& c ) +{ + QColorGroup cg = editPalette.disabled(); + cg.setColor( effectFromItem(comboEffect->currentItem()), c ); + editPalette.setDisabled( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::mapToDisabledPixmapRole( const QPixmap& pm ) +{ + QColorGroup::ColorRole role = centralFromItem(comboCentral->currentItem()); + QColorGroup cg = editPalette.disabled(); + if ( !pm.isNull() ) + cg.setBrush( role, QBrush( cg.color( role ), pm ) ); + else + cg.setBrush( role, QBrush( cg.color( role ) ) ); + + editPalette.setDisabled( cg ); + + setPreviewPalette( editPalette ); +} + +void PaletteEditorAdvanced::buildActiveEffect() +{ + QColorGroup cg = editPalette.active(); + QColor btn = cg.color( QColorGroup::Button ); + + QPalette temp( btn, btn ); + + for (int i = 0; i<5; i++) + cg.setColor( effectFromItem(i), temp.active().color( effectFromItem(i) ) ); + + editPalette.setActive( cg ); + setPreviewPalette( editPalette ); + + updateColorButtons(); +} + +void PaletteEditorAdvanced::buildInactive() +{ + editPalette.setInactive( editPalette.active() ); + if ( checkBuildEffect->isChecked() ) + buildInactiveEffect(); + else { + setPreviewPalette( editPalette ); + updateColorButtons(); + } + +} + +void PaletteEditorAdvanced::buildInactiveEffect() +{ + QColorGroup cg = editPalette.inactive(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setInactive( cg ); + setPreviewPalette( editPalette ); + updateColorButtons(); +} + +void PaletteEditorAdvanced::buildDisabled() +{ + QColorGroup cg = editPalette.active(); + cg.setColor( QColorGroup::ButtonText, darkGray ); + cg.setColor( QColorGroup::Foreground, darkGray ); + cg.setColor( QColorGroup::Text, darkGray ); + cg.setColor( QColorGroup::HighlightedText, darkGray ); + editPalette.setDisabled( cg ); + + if ( checkBuildEffect->isChecked() ) + buildDisabledEffect(); + else { + setPreviewPalette( editPalette ); + updateColorButtons(); + } +} + +void PaletteEditorAdvanced::buildDisabledEffect() +{ + QColorGroup cg = editPalette.disabled(); + + QColor light, midlight, mid, dark, shadow; + QColor btn = cg.color( QColorGroup::Button ); + + light = btn.light(150); + midlight = btn.light(115); + mid = btn.dark(150); + dark = btn.dark(); + shadow = black; + + cg.setColor( QColorGroup::Light, light ); + cg.setColor( QColorGroup::Midlight, midlight ); + cg.setColor( QColorGroup::Mid, mid ); + cg.setColor( QColorGroup::Dark, dark ); + cg.setColor( QColorGroup::Shadow, shadow ); + + editPalette.setDisabled( cg ); + setPreviewPalette( editPalette ); + updateColorButtons(); +} + +void PaletteEditorAdvanced::setPreviewPalette( const QPalette& pal ) +{ + QColorGroup cg; + + switch (selectedPalette) { + case 0: + default: + cg = pal.active(); + break; + case 1: + cg = pal.inactive(); + break; + case 2: + cg = pal.disabled(); + break; + } + previewPalette.setActive( cg ); + previewPalette.setInactive( cg ); + previewPalette.setDisabled( cg ); +} + +void PaletteEditorAdvanced::updateColorButtons() +{ + QColor central, effect; + switch (selectedPalette) { + case 0: + default: + central = editPalette.active().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.active().color( effectFromItem( comboEffect->currentItem() ) ); + break; + case 1: + central = editPalette.inactive().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.inactive().color( effectFromItem( comboEffect->currentItem() ) ); + break; + case 2: + central = editPalette.disabled().color( centralFromItem( comboCentral->currentItem() ) ); + effect = editPalette.disabled().color( effectFromItem( comboEffect->currentItem() ) ); + break; + } + + buttonCentral->setColor(central); + buttonEffect->setColor(effect); +} + +void PaletteEditorAdvanced::setPal( const QPalette& pal ) +{ + editPalette = pal; + setPreviewPalette( pal ); + updateColorButtons(); +} + +QPalette PaletteEditorAdvanced::pal() const +{ + return editPalette; +} + +void PaletteEditorAdvanced::setupBackgroundMode( BackgroundMode mode ) +{ + int initRole = 0; + + switch( mode ) { + case PaletteBackground: + initRole = 0; + break; + case PaletteForeground: + initRole = 1; + break; + case PaletteButton: + initRole = 2; + break; + case PaletteBase: + initRole = 3; + break; + case PaletteText: + initRole = 4; + break; + case PaletteBrightText: + initRole = 5; + break; + case PaletteButtonText: + initRole = 6; + break; + case PaletteHighlight: + initRole = 7; + break; + case PaletteHighlightedText: + initRole = 8; + break; + case PaletteLight: + initRole = 9; + break; + case PaletteMidlight: + initRole = 10; + break; + case PaletteDark: + initRole = 11; + break; + case PaletteMid: + initRole = 12; + break; + case PaletteShadow: + initRole = 13; + break; + default: + initRole = -1; + break; + } + + if ( initRole <= -1 ) return; + + if (initRole > 8 ) { + comboEffect->setCurrentItem( initRole - 9 ); + if ( comboEffect->listBox() ) { + QString text = comboEffect->currentText(); + comboEffect->listBox()->changeItem( new BoldListBoxText( text ), initRole - 9 ); + } + } + else { + comboCentral->setCurrentItem( initRole ); + if ( comboCentral->listBox() ) { + QString text = comboCentral->currentText(); + comboCentral->listBox()->changeItem( new BoldListBoxText( text ), initRole ); + } + } +} + +QPalette PaletteEditorAdvanced::getPalette( bool *ok, const QPalette &init, + BackgroundMode mode, QWidget* parent, + const char* name ) +{ + PaletteEditorAdvanced* dlg = new PaletteEditorAdvanced( parent, name, TRUE ); + dlg->setupBackgroundMode( mode ); + + if ( init != QPalette() ) + dlg->setPal( init ); + int resultCode = dlg->exec(); + + QPalette result = init; + if ( resultCode == QDialog::Accepted ) { + if ( ok ) + *ok = TRUE; + result = dlg->pal(); + } else { + if ( ok ) + *ok = FALSE; + } + delete dlg; + return result; +} diff --git a/tools/qtconfig/paletteeditoradvanced.h b/tools/qtconfig/paletteeditoradvanced.h new file mode 100644 index 0000000..aca4632 --- /dev/null +++ b/tools/qtconfig/paletteeditoradvanced.h @@ -0,0 +1,98 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PALETTEEDITORADVANCED_H +#define PALETTEEDITORADVANCED_H + +#include "paletteeditoradvancedbase.h" + +class PaletteEditorAdvanced : public PaletteEditorAdvancedBase +{ + Q_OBJECT +public: + PaletteEditorAdvanced( QWidget * parent=0, const char * name=0, + bool modal=FALSE, WFlags f=0 ); + ~PaletteEditorAdvanced(); + + static QPalette getPalette( bool *ok, const QPalette &pal, BackgroundMode mode = PaletteBackground, + QWidget* parent = 0, const char* name = 0 ); + +protected slots: + void paletteSelected(int); + + void onCentral( int ); + void onEffect( int ); + + void onChooseCentralColor(); + void onChooseEffectColor(); + + void onToggleBuildEffects( bool ); + void onToggleBuildInactive( bool ); + void onToggleBuildDisabled( bool ); + +protected: + void mapToActiveCentralRole( const QColor& ); + void mapToActiveEffectRole( const QColor& ); + void mapToActivePixmapRole( const QPixmap& ); + void mapToInactiveCentralRole( const QColor& ); + void mapToInactiveEffectRole( const QColor& ); + void mapToInactivePixmapRole( const QPixmap& ); + void mapToDisabledCentralRole( const QColor& ); + void mapToDisabledEffectRole( const QColor& ); + void mapToDisabledPixmapRole( const QPixmap& ); + + + void buildPalette(); + void buildActiveEffect(); + void buildInactive(); + void buildInactiveEffect(); + void buildDisabled(); + void buildDisabledEffect(); + +private: + void setPreviewPalette( const QPalette& ); + void updateColorButtons(); + void setupBackgroundMode( BackgroundMode ); + + QPalette pal() const; + void setPal( const QPalette& ); + + QColorGroup::ColorRole centralFromItem( int ); + QColorGroup::ColorRole effectFromItem( int ); + QPalette editPalette; + QPalette previewPalette; + + int selectedPalette; +}; + +#endif diff --git a/tools/qtconfig/paletteeditoradvancedbase.ui b/tools/qtconfig/paletteeditoradvancedbase.ui new file mode 100644 index 0000000..61f97b5 --- /dev/null +++ b/tools/qtconfig/paletteeditoradvancedbase.ui @@ -0,0 +1,682 @@ + +PaletteEditorAdvancedBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + PaletteEditorAdvancedBase + + + true + + + + 0 + 0 + 295 + 346 + + + + Tune Palette + + + true + + + <b>Edit Palette</b><p>Change the palette of the current widget or form.</p><p>Use a generated palette or select colors for each color group and each color role.</p><p>The palette can be tested with different widget layouts in the preview section.</p> + + + + unnamed + + + 11 + + + 6 + + + + Layout14 + + + + unnamed + + + 0 + + + 6 + + + + TextLabel1 + + + MShape + + + MShadow + + + Select &Palette: + + + paletteCombo + + + + + + Active Palette + + + + + Inactive Palette + + + + + Disabled Palette + + + + paletteCombo + + + + + + + ButtonGroup1 + + + + 5 + 4 + + + + Auto + + + + unnamed + + + 11 + + + 6 + + + + checkBuildInactive + + + Build inactive palette from active. + + + true + + + + + checkBuildDisabled + + + Build disabled palette from active. + + + true + + + + + + + groupCentral + + + Central color &roles + + + + unnamed + + + 11 + + + 6 + + + + + Background + + + + + Foreground + + + + + Button + + + + + Base + + + + + Text + + + + + BrightText + + + + + ButtonText + + + + + Highlight + + + + + HighlightText + + + + + Link + + + + + LinkVisited + + + + comboCentral + + + Choose central color role + + + <b>Select a color role.</b><p>Available central roles are: <ul> <li>Background - general background color.</li> <li>Foreground - general foreground color. </li> <li>Base - used as background color for e.g. text entry widgets, usually white or another light color. </li> <li>Text - the forground color used with Base. Usually this is the same as the Foreground, in what case it must provide good contrast both with Background and Base. </li> <li>Button - general button background color, where buttons need a background different from Background, as in the Macintosh style. </li> <li>ButtonText - a foreground color used with the Button color. </li> <li>Highlight - a color to indicate a selected or highlighted item. </li> <li>HighlightedText - a text color that contrasts to Highlight. </li> <li>BrightText - a text color that is very different from Foreground and contrasts well with e.g. black. </li> </ul> </p> + + + + + Layout32_2 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal_Spacing1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + labelCentral + + + + 1 + 1 + + + + + 0 + 0 + + + + &Select Color: + + + buttonCentral + + + + + buttonCentral + + + + 0 + 0 + + + + TabFocus + + + Choose a color + + + Choose a color for the selected central color role. + + + + + + + + + groupEffect + + + 3-D shadow &effects + + + + unnamed + + + 11 + + + 6 + + + + Layout32_3 + + + + unnamed + + + 0 + + + 6 + + + + checkBuildEffect + + + Build &from button color + + + true + + + Generate shadings + + + Check to let 3D-effect colors be calculated from button-color. + + + + + + Light + + + + + Midlight + + + + + Mid + + + + + Dark + + + + + Shadow + + + + comboEffect + + + Choose 3D-effect color role + + + <b>Select a color role.</b><p>Available effect roles are: <ul> <li>Light - lighter than Button color. </li> <li>Midlight - between Button and Light. </li> <li>Mid - between Button and Dark. </li> <li>Dark - darker than Button. </li> <li>Shadow - a very dark color. </li> </ul> + + + + + + + Layout31_2 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal_Spacing3 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + labelEffect + + + + 1 + 1 + + + + + 0 + 0 + + + + Select Co&lor: + + + buttonEffect + + + + + buttonEffect + + + + 0 + 0 + + + + TabFocus + + + Choose a color + + + Choose a color for the selected effect color role. + + + + + + + + + Layout3 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal_Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + OK + + + true + + + true + + + Close dialog and apply all changes. + + + + + buttonCancel + + + Cancel + + + true + + + Close dialog and discard all changes. + + + + + + + + + ColorButton +
    colorbutton.h
    + + 40 + 25 + + 0 + + 5 + 5 + + image0 + clicked() + colorChanged(const QColor &) + changed() + color + pixmap +
    +
    + + + 789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758 + + + + + buttonOk + clicked() + PaletteEditorAdvancedBase + accept() + + + buttonCancel + clicked() + PaletteEditorAdvancedBase + reject() + + + paletteCombo + activated(int) + PaletteEditorAdvancedBase + paletteSelected(int) + + + comboCentral + activated(int) + PaletteEditorAdvancedBase + onCentral(int) + + + buttonCentral + clicked() + PaletteEditorAdvancedBase + onChooseCentralColor() + + + buttonEffect + clicked() + PaletteEditorAdvancedBase + onChooseEffectColor() + + + comboEffect + activated(int) + PaletteEditorAdvancedBase + onEffect(int) + + + checkBuildEffect + toggled(bool) + PaletteEditorAdvancedBase + onToggleBuildEffects(bool) + + + checkBuildEffect + toggled(bool) + comboEffect + setDisabled(bool) + + + checkBuildEffect + toggled(bool) + buttonEffect + setDisabled(bool) + + + checkBuildInactive + toggled(bool) + PaletteEditorAdvancedBase + onToggleBuildInactive(bool) + + + checkBuildDisabled + toggled(bool) + PaletteEditorAdvancedBase + onToggleBuildDisabled(bool) + + init() + destroy() + onCentral(int) + onChooseCentralColor() + onChooseEffectColor() + onEffect(int) + onToggleBuildDisabled(bool) + onToggleBuildEffects(bool) + onToggleBuildInactive(bool) + paletteSelected(int) + + + buttonOk + buttonCancel + paletteCombo + checkBuildInactive + checkBuildDisabled + comboCentral + buttonCentral + checkBuildEffect + comboEffect + buttonEffect + +
    diff --git a/tools/qtconfig/previewframe.cpp b/tools/qtconfig/previewframe.cpp new file mode 100644 index 0000000..a16b566 --- /dev/null +++ b/tools/qtconfig/previewframe.cpp @@ -0,0 +1,63 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "previewframe.h" + +#include +#include + +PreviewFrame::PreviewFrame( QWidget *parent, const char *name ) + : QVBox( parent, name ) +{ + setMinimumSize(200, 200); + setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); + setLineWidth(1); + + Workspace * w = new Workspace( this ); + w->setEraseColor(colorGroup().dark()); + previewWidget = new PreviewWidget( w ); + previewWidget->move( 10, 10 ); +} + +void PreviewFrame::setPreviewPalette(QPalette pal) +{ + previewWidget->setPalette(pal); +} + +void Workspace::paintEvent( QPaintEvent* ) +{ + QPainter p ( this ); + p.setPen( QPen( white ) ); + p.drawText ( 0, height() / 2, width(), height(), AlignHCenter, + "The moose in the noose\nate the goose who was loose." ); +} diff --git a/tools/qtconfig/previewframe.h b/tools/qtconfig/previewframe.h new file mode 100644 index 0000000..f2281a7 --- /dev/null +++ b/tools/qtconfig/previewframe.h @@ -0,0 +1,67 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PREVIEWFRAME_H +#define PREVIEWFRAME_H + +#include "previewwidget.h" + +#include +#include + +class Workspace : public QWorkspace +{ + Q_OBJECT + +public: + Workspace( QWidget* parent = 0, const char* name = 0 ) + : QWorkspace( parent, name ) {} + ~Workspace() {} + +protected: + void paintEvent( QPaintEvent* ); +}; + +class PreviewFrame : public QVBox +{ + Q_OBJECT + +public: + PreviewFrame( QWidget *parent = 0, const char *name = 0 ); + void setPreviewPalette(QPalette); + +private: + PreviewWidget *previewWidget; +}; + +#endif diff --git a/tools/qtconfig/previewwidget.cpp b/tools/qtconfig/previewwidget.cpp new file mode 100644 index 0000000..cd88a29 --- /dev/null +++ b/tools/qtconfig/previewwidget.cpp @@ -0,0 +1,75 @@ +/********************************************************************** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "previewwidget.h" + +#include + +PreviewWidget::PreviewWidget( QWidget *parent, const char *name ) + : PreviewWidgetBase( parent, name ) +{ + // install event filter on child widgets + QObjectList *l = queryList("QWidget"); + QObjectListIt it(*l); + QObject * obj; + while ((obj = it.current()) != 0) { + ++it; + obj->installEventFilter(this); + ((QWidget*)obj)->setFocusPolicy(NoFocus); + } +} + + +void PreviewWidget::closeEvent(QCloseEvent *e) +{ + e->ignore(); +} + + +bool PreviewWidget::eventFilter(QObject *, QEvent *e) +{ + switch ( e->type() ) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::Enter: + case QEvent::Leave: + return TRUE; // ignore; + default: + break; + } + return FALSE; +} diff --git a/tools/qtconfig/previewwidget.h b/tools/qtconfig/previewwidget.h new file mode 100644 index 0000000..ca7e5bd --- /dev/null +++ b/tools/qtconfig/previewwidget.h @@ -0,0 +1,50 @@ +/********************************************************************** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PREVIEWWIDGET_H +#define PREVIEWWIDGET_H + +#include "previewwidgetbase.h" + +class PreviewWidget : public PreviewWidgetBase +{ + Q_OBJECT + +public: + PreviewWidget( QWidget *parent = 0, const char *name = 0 ); + + void closeEvent(QCloseEvent *); + bool eventFilter(QObject *, QEvent *); +}; + +#endif diff --git a/tools/qtconfig/previewwidgetbase.ui b/tools/qtconfig/previewwidgetbase.ui new file mode 100644 index 0000000..a03df6b --- /dev/null +++ b/tools/qtconfig/previewwidgetbase.ui @@ -0,0 +1,311 @@ + +PreviewWidgetBase +********************************************************************* +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Configuration. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + PreviewWidgetBase + + + + 0 + 0 + 378 + 236 + + + + + 1 + 1 + + + + Preview Window + + + + unnamed + + + 11 + + + 6 + + + + Layout6 + + + + unnamed + + + 0 + + + 6 + + + + Layout17 + + + + unnamed + + + 0 + + + 6 + + + + ButtonGroup1 + + + ButtonGroup + + + + unnamed + + + 11 + + + 6 + + + + RadioButton1 + + + RadioButton1 + + + true + + + + + RadioButton2 + + + RadioButton2 + + + + + RadioButton3 + + + RadioButton3 + + + + + + + ButtonGroup2 + + + ButtonGroup2 + + + + unnamed + + + 11 + + + 6 + + + + CheckBox1 + + + CheckBox1 + + + true + + + + + CheckBox2 + + + CheckBox2 + + + + + + + ProgressBar1 + + + 50 + + + + + + + Layout5 + + + + unnamed + + + 0 + + + 6 + + + + LineEdit1 + + + LineEdit + + + + + + ComboBox + + + + ComboBox1 + + + + + Layout13 + + + + unnamed + + + 0 + + + 6 + + + + SpinBox1 + + + + + PushButton1 + + + PushButton + + + + + + + ScrollBar1 + + + Horizontal + + + + + Slider1 + + + Horizontal + + + + + textView + + + + 32767 + 50 + + + + <p> +<a href="http://www.trolltech.com">http://www.trolltech.com</a> +</p> +<p> +<a href="http://www.kde.org">http://www.kde.org</a> +</p> + + + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + init() + destroy() + + diff --git a/tools/qtconfig/qtconfig.pro b/tools/qtconfig/qtconfig.pro new file mode 100644 index 0000000..aaef136 --- /dev/null +++ b/tools/qtconfig/qtconfig.pro @@ -0,0 +1,18 @@ +TEMPLATE = app +CONFIG += qt warn_on +LANGUAGE = C++ + +SOURCES += colorbutton.cpp main.cpp previewframe.cpp previewwidget.cpp mainwindow.cpp paletteeditoradvanced.cpp +HEADERS += colorbutton.h previewframe.h previewwidget.h mainwindow.h paletteeditoradvanced.h +FORMS = mainwindowbase.ui paletteeditoradvancedbase.ui previewwidgetbase.ui +IMAGES = images/appicon.png + +PROJECTNAME = Qt Configuration +TARGET = qtconfig +DESTDIR = ../../bin + +target.path=$$bins.path +INSTALLS += target +INCLUDEPATH += . +DBFILE = qtconfig.db +REQUIRES=full-config nocrosscompiler !win32* diff --git a/tools/qvfb/LICENSE.GPL b/tools/qvfb/LICENSE.GPL new file mode 100644 index 0000000..3221c03 --- /dev/null +++ b/tools/qvfb/LICENSE.GPL @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/tools/qvfb/README b/tools/qvfb/README new file mode 100644 index 0000000..c627041 --- /dev/null +++ b/tools/qvfb/README @@ -0,0 +1,55 @@ +Qt/Embedded Virtual Framebuffer +=============================== + +Please note that the qvfb program needs to be compiled with the X11 version +of Qt. + +The virtual frame buffer allows a Qt/Embedded program to be developed on your +desktop machine, without switching between consoles and X11. The virtual +framebuffer consists of a shared memory region (the virtual frame buffer) +and a utility to display the framebuffer in a window. The display is updated +periodically, so you will see discrete snapshots of the framebuffer rather +than each individual drawing operation. For this reason drawing problems +such as flickering may not be apparent until the program is run using a real +framebuffer. + +To use the virtual framebuffer: + +1. Ensure QT_NO_QWS_VFB is not set in qconfig.h (when you configure Qt, + add the -qvfb option). +2. Start qvfb (qvfb should be compiled as a normal Qt/X11 application, + NOT as a Qt/Embedded application!). +3. Start a Qt/Embedded server (i.e. construct QApplication with + QApplication::GuiServer flag, or run a client with the -qws option). + +qvfb supports the following command line options: + +[-width width] the width of the virtual framebuffer (default: 240). +[-height height] the height of the virtual framebuffer (default: 320). +[-depth depth] the depth of the virtual framebuffer (1,4,8 or 32, default: 8). +[-nocursor] do not display the X11 cursor in the framebuffer window. +[-qwsdisplay] the Qt/Embedded display ID, e.g. -qwsdisplay :1 (default :0). +[-skin skinfile] tells qvfb to load a skin file, e.g. -skin pda.skin + +Please refer to the file "pda.skin" for an example of what a skin file looks like. +The format for skin files is: + Image filename of skin with buttons in their up positions + Image filename of skin with buttons in their down positions + X offset of top left corner of the virtual screen on the skin image + Y offset of top left corner of the virtual screen on the skin image + Width of the virtual screen on the skin image + Height of the virtual screen on the skin image + Transparancy level of the Virtual Frame Buffer + Number of defined button regions +Then for each button region the format is: + Button identifier + Qt scan codes to generate for the button + Top left X coordinate of the button region + Top left Y coordinate of the button region + Bottom right X coordinate of the button region + Bottom right Y coordinate of the button region + +The virtual framebuffer is a development tool only. No security issues have +been considered in the virtual framebuffer design. It should not be used +in a production environment and QT_NO_QWS_VFB should always be in force +in production libraries. diff --git a/tools/qvfb/config.ui b/tools/qvfb/config.ui new file mode 100644 index 0000000..dc8a8d3 --- /dev/null +++ b/tools/qvfb/config.ui @@ -0,0 +1,1684 @@ + +Config +********************************************************************* +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +********************************************************************* + + + Config + + + + 0 + 0 + 481 + 645 + + + + Configure + + + logo.png + + + true + + + + unnamed + + + 11 + + + 6 + + + + ButtonGroup2 + + + Depth + + + + depth_1 + + + + 11 + 19 + 229 + 19 + + + + 1 bit monochrome + + + + + depth_4gray + + + + 11 + 44 + 229 + 19 + + + + 4 bit grayscale + + + + + depth_8 + + + + 11 + 69 + 229 + 19 + + + + 8 bit + + + + + depth_12 + + + + 11 + 94 + 229 + 19 + + + + 12 (16) bit + + + + + depth_16 + + + + 11 + 119 + 229 + 19 + + + + 16 bit + + + + + depth_32 + + + + 11 + 144 + 229 + 19 + + + + 32 bit + + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + true + + + + + + + touchScreen + + + Emulate touch screen (no mouse move). + + + + + GroupBox1 + + + Gamma + + + + unnamed + + + 11 + + + 6 + + + + TextLabel3 + + + Blue + + + + + bslider + + + + + + 0 + 0 + 0 + + + 0 + 0 + 255 + + + 127 + 127 + 255 + + + 63 + 63 + 255 + + + 0 + 0 + 127 + + + 0 + 0 + 170 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + 128 + 128 + 128 + + + 0 + 0 + 255 + + + 127 + 127 + 255 + + + 38 + 38 + 255 + + + 0 + 0 + 127 + + + 0 + 0 + 170 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 128 + 128 + 128 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + 0 + 0 + 255 + + + 127 + 127 + 255 + + + 38 + 38 + 255 + + + 0 + 0 + 127 + + + 0 + 0 + 170 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + + 400 + + + 100 + + + Horizontal + + + + + blabel + + + 1.0 + + + + + Spacer3 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + TextLabel2 + + + Green + + + + + gslider + + + + + + 0 + 0 + 0 + + + 0 + 255 + 0 + + + 127 + 255 + 127 + + + 63 + 255 + 63 + + + 0 + 127 + 0 + + + 0 + 170 + 0 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + 128 + 128 + 128 + + + 0 + 255 + 0 + + + 127 + 255 + 127 + + + 38 + 255 + 38 + + + 0 + 127 + 0 + + + 0 + 170 + 0 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 128 + 128 + 128 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + 0 + 255 + 0 + + + 127 + 255 + 127 + + + 38 + 255 + 38 + + + 0 + 127 + 0 + + + 0 + 170 + 0 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + + 400 + + + 100 + + + Horizontal + + + + + glabel + + + 1.0 + + + + + TextLabel7 + + + All + + + + + TextLabel8 + + + 1.0 + + + + + gammaslider + + + + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 127 + 127 + 127 + + + 170 + 170 + 170 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + 128 + 128 + 128 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 127 + 127 + 127 + + + 170 + 170 + 170 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 128 + 128 + 128 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 255 + 255 + 255 + + + 127 + 127 + 127 + + + 170 + 170 + 170 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + + 400 + + + 100 + + + Horizontal + + + + + TextLabel1_2 + + + Red + + + + + rlabel + + + 1.0 + + + + + rslider + + + + + + 0 + 0 + 0 + + + 255 + 0 + 0 + + + 255 + 127 + 127 + + + 255 + 63 + 63 + + + 127 + 0 + 0 + + + 170 + 0 + 0 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + 128 + 128 + 128 + + + 255 + 0 + 0 + + + 255 + 127 + 127 + + + 255 + 38 + 38 + + + 127 + 0 + 0 + + + 170 + 0 + 0 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 128 + 128 + 128 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + 0 + 0 + 0 + + + 255 + 0 + 0 + + + 255 + 127 + 127 + + + 255 + 38 + 38 + + + 127 + 0 + 0 + + + 170 + 0 + 0 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 255 + 255 + 255 + + + 220 + 220 + 220 + + + 0 + 0 + 0 + + + 10 + 95 + 137 + + + 255 + 255 + 255 + + + 0 + 0 + 0 + + + 0 + 0 + 0 + + + + + + 400 + + + 100 + + + Horizontal + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + Spacer4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + PushButton3 + + + Set all to 1.0 + + + + + MyCustomWidget1 + + + + + Spacer5 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + ButtonGroup1 + + + + 5 + 5 + 0 + 0 + + + + Size + + + + unnamed + + + 11 + + + 6 + + + + size_240_320 + + + 240x320 "PDA" + + + + + size_320_240 + + + 320x240 "TV" + + + + + size_640_480 + + + 640x480 "VGA" + + + + + Layout1_2 + + + + unnamed + + + 0 + + + 6 + + + + size_custom + + + Custom + + + + + size_width + + + 1280 + + + 1 + + + 16 + + + 400 + + + + + size_height + + + 1024 + + + 1 + + + 16 + + + 300 + + + + + + + Layout8 + + + + unnamed + + + 0 + + + 6 + + + + size_skin + + + + 0 + 0 + 0 + 0 + + + + Skin + + + + + + pda.skin + + + + + ipaq.skin + + + + + qpe.skin + + + + + cassiopeia.skin + + + + + other.skin + + + + skin + + + + 5 + 0 + 0 + 0 + + + + + + + + + + TextLabel1 + + + <p>Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth <i>above</i>. You may freely modify the Gamma <i>below</i>. + + + + + + + GammaView +
    gammaview.h
    + + 64 + 64 + + 0 + + 3 + 3 + 0 + 0 + + image0 +
    +
    + + + 789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758 + + + + + buttonOk + clicked() + Config + accept() + + + buttonCancel + clicked() + Config + reject() + + + + +
    diff --git a/tools/qvfb/gammaview.h b/tools/qvfb/gammaview.h new file mode 100644 index 0000000..b66b03f --- /dev/null +++ b/tools/qvfb/gammaview.h @@ -0,0 +1,49 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef GAMMAVIEW_H +#define GAMMAVIEW_H + +#include + +class GammaView: public QWidget +{ + Q_OBJECT +public: + GammaView( QWidget *parent = 0, + const char *name = 0, WFlags f = 0 ) : + QWidget(parent,name,f) + { } +}; + +#endif diff --git a/tools/qvfb/images/logo.png b/tools/qvfb/images/logo.png new file mode 100644 index 0000000..0cb2b68 Binary files /dev/null and b/tools/qvfb/images/logo.png differ diff --git a/tools/qvfb/main.cpp b/tools/qvfb/main.cpp new file mode 100644 index 0000000..50e11ec --- /dev/null +++ b/tools/qvfb/main.cpp @@ -0,0 +1,97 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qvfb.h" + +#include +#include +#include + +#include +#include + +void usage( const char *app ) +{ + printf( "Usage: %s [-width width] [-height height] [-depth depth] " + "[-nocursor] [-qwsdisplay :id]\n" + "Supported depths: 1, 4, 8, 32\n", app ); +} + +int main( int argc, char *argv[] ) +{ + QApplication app( argc, argv ); + + int width = 240; + int height = 320; + int depth = 32; + bool cursor = TRUE; + QString displaySpec( ":0" ); + QString skin; + + for ( int i = 1; i < argc; i++ ){ + QString arg = argv[i]; + if ( arg == "-width" ) { + width = atoi( argv[++i] ); + } else if ( arg == "-height" ) { + height = atoi( argv[++i] ); + } else if ( arg == "-skin" ) { + skin = argv[++i]; + } else if ( arg == "-depth" ) { + depth = atoi( argv[++i] ); + } else if ( arg == "-nocursor" ) { + cursor = FALSE; + } else if ( arg == "-qwsdisplay" ) { + displaySpec = argv[++i]; + } else { + printf( "Unknown parameter %s\n", arg.latin1() ); + usage( argv[0] ); + exit(1); + } + } + + int displayId = 0; + QRegExp rx( ":[0-9]" ); + int m = rx.search( displaySpec, 0 ); + if ( m >= 0 ) { + displayId = displaySpec.mid( m+1, rx.matchedLength()-1 ).toInt(); + } + + qDebug( "Using display %d", displayId ); + + QVFb mw( displayId, width, height, depth, skin ); + app.setMainWidget( &mw ); + mw.enableCursor(cursor); + mw.show(); + + return app.exec(); +} diff --git a/tools/qvfb/pda.skin b/tools/qvfb/pda.skin new file mode 100644 index 0000000..135e6b6 --- /dev/null +++ b/tools/qvfb/pda.skin @@ -0,0 +1,15 @@ +pda_up.png pda_down.png +57 81 +240 320 +0.5 +11 +"Power" 0x100a 277 36 302 57 +"F1" 0x1030 52 439 81 470 +"F2" 0x1031 101 422 130 451 +"F3" 0x1032 232 423 260 452 +"F4" 0x1033 279 445 309 473 +"Left" 0x1012 155 438 176 472 +"Down" 0x1015 169 471 203 486 +"Right" 0x1014 193 448 215 472 +"Up" 0x1013 166 427 199 451 +"Enter" 0x1005 177 448 193 468 diff --git a/tools/qvfb/pda_down.png b/tools/qvfb/pda_down.png new file mode 100644 index 0000000..bc1f5ee Binary files /dev/null and b/tools/qvfb/pda_down.png differ diff --git a/tools/qvfb/pda_up.png b/tools/qvfb/pda_up.png new file mode 100644 index 0000000..05e97df Binary files /dev/null and b/tools/qvfb/pda_up.png differ diff --git a/tools/qvfb/qanimationwriter.cpp b/tools/qvfb/qanimationwriter.cpp new file mode 100644 index 0000000..35d6131 --- /dev/null +++ b/tools/qvfb/qanimationwriter.cpp @@ -0,0 +1,414 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qanimationwriter.h" + +#define QT_CLEAN_NAMESPACE +#include + +#include +#include // for htonl + +class QAnimationWriterData { +public: + QAnimationWriterData(QIODevice* d) : dev(d) + { + framerate = 1000; + } + void setFrameRate(int d) { framerate = d; } + virtual ~QAnimationWriterData() { } + virtual void setImage(const QImage& src)=0; + virtual bool canCompose() const { return FALSE; } + virtual void composeImage(const QImage&, const QPoint& ) { } + +protected: + int framerate; + QIODevice* dev; +}; + + +class QAnimationWriterMNG : public QAnimationWriterData { + bool first; + png_structp png_ptr; + png_infop info_ptr; +public: + QAnimationWriterMNG(QIODevice* d) : QAnimationWriterData(d) + { + first = TRUE; + begin_png(); + } + + ~QAnimationWriterMNG() + { + if ( first ) { + // Eh? Not images. + QImage dummy(1,1,32); + setImage(dummy); + } + writeMEND(); + end_png(); + } + + void begin_png() + { + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); + info_ptr = png_create_info_struct(png_ptr); + png_set_compression_level(png_ptr,9); + png_set_write_fn(png_ptr, (void*)this, write, 0); + } + + void end_png() + { + png_destroy_write_struct(&png_ptr, &info_ptr); + } + + + static void write( png_structp png_ptr, png_bytep data, png_size_t length) + { + QAnimationWriterMNG* that = (QAnimationWriterMNG*)png_get_io_ptr(png_ptr); + /*uint nw =*/ that->dev->writeBlock((const char*)data,length); + } + + void writePNG(const QImage& image) + { + info_ptr->channels = 4; + png_set_sig_bytes(png_ptr, 8); // Pretend we already wrote the sig + png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), + 8, image.hasAlphaBuffer() + ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB, + 0, 0, 0); + png_write_info(png_ptr, info_ptr); + if ( !image.hasAlphaBuffer() ) + png_set_filler(png_ptr, 0, + QImage::systemByteOrder() == QImage::BigEndian ? + PNG_FILLER_BEFORE : PNG_FILLER_AFTER); + //if ( QImage::systemByteOrder() == QImage::BigEndian ) { + //png_set_swap_alpha(png_ptr); + //} + if ( QImage::systemByteOrder() == QImage::LittleEndian ) { + png_set_bgr(png_ptr); + } + + png_bytep* row_pointers; + uint height = image.height(); + uchar** jt = image.jumpTable(); + row_pointers=new png_bytep[height]; + uint y; + for (y=0; ywriteBlock("\212MNG\r\n\032\n", 8); + + struct { + int width; + int height; + int framerate; + int a,b,c; + int profile; + } chunk; + chunk.width = htonl(size.width()); + chunk.height = htonl(size.height()); + chunk.framerate = htonl(framerate); + chunk.a=0; + chunk.b=0; + chunk.c=0; + chunk.profile= htonl(0x00000003); + + png_write_chunk(png_ptr, (png_byte*)"MHDR", (png_byte*)&chunk, sizeof(chunk)); + } + + void writeMEND() + { + png_write_chunk(png_ptr, (png_byte*)"MEND", 0, 0); + } + + void writeDEFI( const QPoint& offset, const QSize& size ) + { + struct { + ushort o; + uchar s; + uchar concrete; + int x,y; + int lc,rc,tc,bc; + } chunk; + chunk.o=0; + chunk.s=0; + chunk.concrete=1; + chunk.x=htonl(offset.x()); + chunk.y=htonl(offset.y()); + chunk.lc=0; + chunk.rc=0; + chunk.tc=htonl(INT_MAX); + chunk.bc=htonl(INT_MAX); + + png_write_chunk(png_ptr, (png_byte*)"DEFI", (png_byte*)&chunk, sizeof(chunk)); + } + + void writeFRAM( const QSize& size ) + { + struct { + uchar mode; + uchar n; + uchar nu; + uchar d; + uchar t; + uchar clip; + uchar s; + uchar deltatype; + uint left; + uint right; + uint top; + uint bottom; + } chunk; + chunk.mode=1; + chunk.n='a'; + chunk.nu=0; + chunk.d=0; + chunk.clip=1; + chunk.t=0; + chunk.s=0; + chunk.deltatype=0; + chunk.left=0; + chunk.right=htonl(size.width()); + chunk.top=0; + chunk.bottom=htonl(size.height()); + + png_write_chunk(png_ptr, (png_byte*)"FRAM", (png_byte*)&chunk, sizeof(chunk)); + } + + void writeMOVE( const QPoint& offset ) + { + struct { + uchar filler[3]; + uchar z[5]; + int x,y; + } chunk; + memset(chunk.z,0,5); + chunk.x=htonl(offset.x()); + chunk.y=htonl(offset.y()); + + png_write_chunk(png_ptr, (png_byte*)"MOVE", ((png_byte*)&chunk)+3, sizeof(chunk)-3); + } + + void setImage(const QImage& src) + { + if ( first ) { + first = FALSE; + writeMHDR(src.size(),framerate); + } + composeImage(src,QPoint(0,0)); + } + + bool canCompose() const { return TRUE; } + + void composeImage(const QImage& src, const QPoint& offset) + { + writeMOVE(offset); + //writeFRAM(src.size()); + writePNG(src); + } +}; + +QAnimationWriter::QAnimationWriter( const QString& filename, const char* format ) +{ + if ( QCString(format) != "MNG" ) { + qWarning("Format \"%s\" not supported, only MNG", format); + dev = 0; + d = 0; + } else { + QFile *f = new QFile(filename); + f->open(IO_WriteOnly); + dev = f; + d = new QAnimationWriterMNG(dev); + } +} + +bool QAnimationWriter::okay() const +{ + return dev && dev->status() == IO_Ok; +} + +QAnimationWriter::~QAnimationWriter() +{ + delete d; + delete dev; +} + +void QAnimationWriter::setFrameRate(int r) +{ + if (d) d->setFrameRate(r); +} + +void QAnimationWriter::appendFrame(const QImage& frm, const QPoint& offset) +{ + QImage frame = frm.convertDepth(32); + const int alignx = 1; + if ( dev ) { + if ( prev.isNull() || !d->canCompose() ) { + d->setImage(frame); + } else { + bool done; + int minx, maxx, miny, maxy; + int w = frame.width(); + int h = frame.height(); + + QRgb** jt = (QRgb**)frame.jumpTable(); + QRgb** pjt = (QRgb**)prev.jumpTable() + offset.y(); + + // Find left edge of change + done = FALSE; + for (minx = 0; minx < w && !done; minx++) { + for (int ty = 0; ty < h; ty++) { + if ( jt[ty][minx] != pjt[ty][minx+offset.x()] ) { + done = TRUE; + break; + } + } + } + minx--; + + // Find right edge of change + done = FALSE; + for (maxx = w-1; maxx >= 0 && !done; maxx--) { + for (int ty = 0; ty < h; ty++) { + if ( jt[ty][maxx] != pjt[ty][maxx+offset.x()] ) { + done = TRUE; + break; + } + } + } + maxx++; + + // Find top edge of change + done = FALSE; + for (miny = 0; miny < h && !done; miny++) { + for (int tx = 0; tx < w; tx++) { + if ( jt[miny][tx] != pjt[miny][tx+offset.x()] ) { + done = TRUE; + break; + } + } + } + miny--; + + // Find right edge of change + done = FALSE; + for (maxy = h-1; maxy >= 0 && !done; maxy--) { + for (int tx = 0; tx < w; tx++) { + if ( jt[maxy][tx] != pjt[maxy][tx+offset.x()] ) { + done = TRUE; + break; + } + } + } + maxy++; + + if ( minx > maxx ) minx=maxx=0; + if ( miny > maxy ) miny=maxy=0; + + if ( alignx > 1 ) { + minx -= minx % alignx; + maxx = maxx - maxx % alignx + alignx - 1; + } + + int dw = maxx-minx+1; + int dh = maxy-miny+1; + + QImage diff(dw, dh, 32); + + diff.setAlphaBuffer(TRUE); + int x, y; + for (y = 0; y < dh; y++) { + QRgb* li = (QRgb*)frame.scanLine(y+miny)+minx; + QRgb* lp = (QRgb*)prev.scanLine(y+miny+offset.y())+minx+offset.x(); + QRgb* ld = (QRgb*)diff.scanLine(y); + if ( alignx ) { + for (x = 0; x < dw; x+=alignx) { + int i; + for (i=0; icomposeImage(diff,QPoint(minx,miny)+offset); + } + if ( prev.isNull() || prev.size() == frame.size() && offset == QPoint(0,0) ) { + prev = frame; + } else { + bitBlt(&prev,offset.x(),offset.y(),&frame,0,0,frame.width(),frame.height()); + } + } +} + +void QAnimationWriter::appendFrame(const QImage& frm) +{ + appendFrame(frm,QPoint(0,0)); +} + +void QAnimationWriter::appendBlankFrame() +{ + QImage i(1,1,32); + i.setAlphaBuffer(TRUE); + i.fill(0); + d->composeImage(i,QPoint(0,0)); +} diff --git a/tools/qvfb/qanimationwriter.h b/tools/qvfb/qanimationwriter.h new file mode 100644 index 0000000..2757fa8 --- /dev/null +++ b/tools/qvfb/qanimationwriter.h @@ -0,0 +1,59 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QANIMATIONWRITER_H +#define QANIMATIONWRITER_H + +#include + +class QAnimationWriterData; + +class QAnimationWriter +{ +public: + QAnimationWriter( const QString& filename, const char* format="MNG" ); + ~QAnimationWriter(); + + bool okay() const; + void setFrameRate(int); + void appendBlankFrame(); + void appendFrame(const QImage&); + void appendFrame(const QImage&, const QPoint& offset); + +private: + QImage prev; + QIODevice* dev; + QAnimationWriterData* d; +}; + +#endif diff --git a/tools/qvfb/qvfb.cpp b/tools/qvfb/qvfb.cpp new file mode 100644 index 0000000..1be15f8 --- /dev/null +++ b/tools/qvfb/qvfb.cpp @@ -0,0 +1,389 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qvfb.h" +#include "qvfbview.h" +#include "qvfbratedlg.h" +#include "config.h" +#include "skin.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QVFb::QVFb( int display_id, int w, int h, int d, const QString &skin, QWidget *parent, + const char *name, uint flags ) + : QMainWindow( parent, name, flags ) +{ + const QMimeSource *m = QMimeSourceFactory::defaultFactory()->data( "logo.png" ); + if ( m ) { + QPixmap pix; + QImageDrag::decode( m, pix ); + setIcon( pix ); + } + + imagesave = new QFileDialog( this, 0, TRUE ); + + rateDlg = 0; + view = 0; + init( display_id, w, h, d, skin ); + createMenu( menuBar() ); + adjustSize(); +} + +QVFb::~QVFb() +{ +} + +void QVFb::popupMenu() +{ + QPopupMenu *pm = new QPopupMenu( this ); + createMenu( pm ); + pm->exec(QCursor::pos()); +} + +void QVFb::init( int display_id, int w, int h, int d, const QString &skin_name ) +{ + setCaption( QString("Virtual framebuffer %1x%2 %3bpp Display :%4") + .arg(w).arg(h).arg(d).arg(display_id) ); + delete view; + + if ( !skin_name.isEmpty() && QFile::exists(skin_name) ) { + bool vis = isVisible(); + if ( vis ) hide(); + menuBar()->hide(); + Skin *skin = new Skin( this, skin_name, w, h ); + view = new QVFbView( display_id, w, h, d, skin ); + skin->setView( view ); + view->setMargin( 0 ); + view->setFrameStyle( QFrame::NoFrame ); + view->setFixedSize( w, h ); + setCentralWidget( skin ); + adjustSize(); + view->show(); + if ( vis ) show(); + } else { + if ( !currentSkin.isEmpty() ) { + clearMask(); + reparent( 0, 0, pos(), TRUE ); + } + menuBar()->show(); + view = new QVFbView( display_id, w, h, d, this ); + view->setMargin( 0 ); + view->setFrameStyle( QFrame::NoFrame ); + setCentralWidget( view ); + resize( sizeHint() ); + view->show(); + } + + currentSkin = skin_name; +} + +void QVFb::enableCursor( bool e ) +{ + view->viewport()->setCursor( e ? ArrowCursor : BlankCursor ); + viewMenu->setItemChecked( cursorId, e ); +} + +void QVFb::createMenu(QMenuData *menu) +{ + QPopupMenu *file = new QPopupMenu( this ); + file->insertItem( "&Configure...", this, SLOT(configure()), ALT+CTRL+Key_C ); + file->insertSeparator(); + file->insertItem( "&Save image...", this, SLOT(saveImage()), ALT+CTRL+Key_S ); + file->insertItem( "&Animation...", this, SLOT(toggleAnimation()), ALT+CTRL+Key_A ); + file->insertSeparator(); + file->insertItem( "&Quit", qApp, SLOT(quit()) ); + + menu->insertItem( "&File", file ); + + viewMenu = new QPopupMenu( this ); + viewMenu->setCheckable( TRUE ); + cursorId = viewMenu->insertItem( "Show &Cursor", this, SLOT(toggleCursor()) ); + enableCursor(TRUE); + viewMenu->insertItem( "&Refresh Rate...", this, SLOT(changeRate()) ); + viewMenu->insertSeparator(); + viewMenu->insertItem( "Zoom scale &1", this, SLOT(setZoom1()) ); + viewMenu->insertItem( "Zoom scale &2", this, SLOT(setZoom2()) ); + viewMenu->insertItem( "Zoom scale &3", this, SLOT(setZoom3()) ); + viewMenu->insertItem( "Zoom scale &4", this, SLOT(setZoom4()) ); + viewMenu->insertItem( "Zoom scale &0.5", this, SLOT(setZoomHalf()) ); + + menu->insertItem( "&View", viewMenu ); + + QPopupMenu *help = new QPopupMenu( this ); + help->insertItem("&About", this, SLOT(about())); + help->insertItem("About &Qt", this, SLOT(aboutQt())); + menu->insertSeparator(); + menu->insertItem( "&Help", help ); +} + +void QVFb::setZoom(double z) +{ + view->setZoom(z); +} + +void QVFb::setZoomHalf() +{ + setZoom(0.5); +} + +void QVFb::setZoom1() +{ + setZoom(1); +} + +void QVFb::setZoom2() +{ + setZoom(2); +} + +void QVFb::setZoom3() +{ + setZoom(3); +} + +void QVFb::setZoom4() +{ + setZoom(4); +} + +void QVFb::saveImage() +{ + QImage img = view->image(); + QString filename = imagesave->getSaveFileName("snapshot.png", "*.png", this, "", "Save Image"); + if ( !!filename ) + img.save(filename,"PNG"); +} + +void QVFb::toggleAnimation() +{ + if ( view->animating() ) { + view->stopAnimation(); + } else { + QString filename = imagesave->getSaveFileName("animation.mng", "*.mng", this, "", "Save animation"); + if ( !filename ) { + view->stopAnimation(); + } else { + view->startAnimation(filename); + } + } +} + +void QVFb::toggleCursor() +{ + enableCursor( !viewMenu->isItemChecked( cursorId ) ); +} + +void QVFb::changeRate() +{ + if ( !rateDlg ) { + rateDlg = new QVFbRateDialog( view->rate(), this ); + connect( rateDlg, SIGNAL(updateRate(int)), view, SLOT(setRate(int)) ); + } + + rateDlg->show(); +} + +void QVFb::about() +{ +#if defined( Q_WS_MAC ) + QString platform("Mac OS X"); + QString qt("Mac"); +#elif defined( Q_WS_WIN ) + QString platform("Windows"); + QString qt("Windows"); +#else + QString platform("X11"); + QString qt("X11"); +#endif + QMessageBox::about(this, "About QVFB", + "

    Qt/Embedded Virtual " + platform + " Framebuffer

    " + "

    " + "

    Version 1.0

    " + "

    Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.

    " + "

    " + "

    This program is licensed to you under the terms of the GNU General " + "Public License Version 2 as published by the Free Software Foundation. This " + "gives you legal permission to copy, distribute and/or modify this software " + "under certain conditions. For details, see the file 'LICENSE.GPL' that came with " + "this software distribution. If you did not get the file, send email to " + "info@trolltech.com.

    \n\n

    The program is provided AS IS with NO WARRANTY " + "OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS " + "FOR A PARTICULAR PURPOSE.

    " + ); +} + +void QVFb::aboutQt() +{ + QMessageBox::aboutQt( this, tr("QVFB") ); +} + +void QVFb::configure() +{ + config = new Config(this,0,TRUE); + + int w = view->displayWidth(); + int h = view->displayHeight(); + QString skin; + config->size_width->setValue(w); + config->size_height->setValue(h); + config->size_custom->setChecked(TRUE); // unless changed by settings below + config->size_240_320->setChecked(w==240&&h==320); + config->size_320_240->setChecked(w==320&&h==240); + config->size_640_480->setChecked(w==640&&h==480); + config->skin->setEditable(TRUE); + if (!currentSkin.isNull()) { + config->size_skin->setChecked(TRUE); + config->skin->setEditText(currentSkin); + } + config->touchScreen->setChecked(view->touchScreenEmulation()); + config->depth_1->setChecked(view->displayDepth()==1); + config->depth_4gray->setChecked(view->displayDepth()==4); + config->depth_8->setChecked(view->displayDepth()==8); + config->depth_12->setChecked(view->displayDepth()==12); + config->depth_16->setChecked(view->displayDepth()==16); + config->depth_32->setChecked(view->displayDepth()==32); + if ( view->gammaRed() == view->gammaGreen() && view->gammaGreen() == view->gammaBlue() ) { + config->gammaslider->setValue(int(view->gammaRed()*400)); + config->rslider->setValue(100); + config->gslider->setValue(100); + config->bslider->setValue(100); + } else { + config->gammaslider->setValue(100); + config->rslider->setValue(int(view->gammaRed()*400)); + config->gslider->setValue(int(view->gammaGreen()*400)); + config->bslider->setValue(int(view->gammaBlue()*400)); + } + connect(config->gammaslider, SIGNAL(valueChanged(int)), this, SLOT(setGamma400(int))); + connect(config->rslider, SIGNAL(valueChanged(int)), this, SLOT(setR400(int))); + connect(config->gslider, SIGNAL(valueChanged(int)), this, SLOT(setG400(int))); + connect(config->bslider, SIGNAL(valueChanged(int)), this, SLOT(setB400(int))); + updateGammaLabels(); + + double ogr=view->gammaRed(), ogg=view->gammaGreen(), ogb=view->gammaBlue(); + + if ( config->exec() ) { + int id = view->displayId(); // not settable yet + if ( config->size_240_320->isChecked() ) { + w=240; h=320; + } else if ( config->size_320_240->isChecked() ) { + w=320; h=240; + } else if ( config->size_640_480->isChecked() ) { + w=640; h=480; + } else if ( config->size_skin->isChecked() ) { + skin = config->skin->currentText(); + } else { + w=config->size_width->value(); + h=config->size_height->value(); + } + int d; + if ( config->depth_1->isChecked() ) + d=1; + else if ( config->depth_4gray->isChecked() ) + d=4; + else if ( config->depth_8->isChecked() ) + d=8; + else if ( config->depth_12->isChecked() ) + d=12; + else if ( config->depth_16->isChecked() ) + d=16; + else + d=32; + + if ( w != view->displayWidth() || h != view->displayHeight() + || d != view->displayDepth() || skin != currentSkin ) + init( id, w, h, d, skin ); + view->setTouchscreenEmulation( config->touchScreen->isChecked() ); + } else { + view->setGamma(ogr, ogg, ogb); + } + + delete config; + config=0; +} + +void QVFb::setGamma400(int n) +{ + double g = n/100.0; + view->setGamma(config->rslider->value()/100.0*g, + config->gslider->value()/100.0*g, + config->bslider->value()/100.0*g); + updateGammaLabels(); +} + +void QVFb::setR400(int n) +{ + double g = n/100.0; + view->setGamma(config->rslider->value()/100.0*g, + view->gammaGreen(), + view->gammaBlue()); + updateGammaLabels(); +} + +void QVFb::setG400(int n) +{ + double g = n/100.0; + view->setGamma(view->gammaRed(), + config->gslider->value()/100.0*g, + view->gammaBlue()); + updateGammaLabels(); +} + +void QVFb::setB400(int n) +{ + double g = n/100.0; + view->setGamma(view->gammaRed(), + view->gammaGreen(), + config->bslider->value()/100.0*g); + updateGammaLabels(); +} + +void QVFb::updateGammaLabels() +{ + config->rlabel->setText(QString::number(view->gammaRed(),'g',2)); + config->glabel->setText(QString::number(view->gammaGreen(),'g',2)); + config->blabel->setText(QString::number(view->gammaBlue(),'g',2)); +} diff --git a/tools/qvfb/qvfb.h b/tools/qvfb/qvfb.h new file mode 100644 index 0000000..aa959c8 --- /dev/null +++ b/tools/qvfb/qvfb.h @@ -0,0 +1,91 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +class QVFbView; +class QVFbRateDialog; +class QPopupMenu; +class QMenuData; +class QFileDialog; +class Config; + +class QVFb: public QMainWindow +{ + Q_OBJECT +public: + QVFb( int display_id, int w, int h, int d, const QString &skin, QWidget *parent = 0, + const char *name = 0, uint wflags = 0 ); + ~QVFb(); + + void enableCursor( bool e ); + void popupMenu(); + +protected slots: + void saveImage(); + void toggleAnimation(); + void toggleCursor(); + void changeRate(); + void about(); + void aboutQt(); + + void configure(); + + void setZoom(double); + void setZoom1(); + void setZoom2(); + void setZoom3(); + void setZoom4(); + void setZoomHalf(); + +protected: + void createMenu(QMenuData *menu); + +private: + void init( int display_id, int w, int h, int d, const QString &skin ); + QVFbView *view; + QVFbRateDialog *rateDlg; + QFileDialog* imagesave; + QPopupMenu *viewMenu; + int cursorId; + Config* config; + QString currentSkin; + +private slots: + void setGamma400(int n); + void setR400(int n); + void setG400(int n); + void setB400(int n); + void updateGammaLabels(); +}; + diff --git a/tools/qvfb/qvfb.pro b/tools/qvfb/qvfb.pro new file mode 100644 index 0000000..7896e7c --- /dev/null +++ b/tools/qvfb/qvfb.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +CONFIG += qt warn_on release +HEADERS = qvfb.h qvfbview.h qvfbratedlg.h qanimationwriter.h \ + gammaview.h skin.h +SOURCES = qvfb.cpp qvfbview.cpp qvfbratedlg.cpp \ + main.cpp qanimationwriter.cpp skin.cpp +INTERFACES = config.ui +IMAGES = images/logo.png +TARGET = qvfb +INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/libpng $$QT_SOURCE_TREE/src/3rdparty/zlib +DEPENDPATH = ../../include diff --git a/tools/qvfb/qvfbratedlg.cpp b/tools/qvfb/qvfbratedlg.cpp new file mode 100644 index 0000000..65c0fe2 --- /dev/null +++ b/tools/qvfb/qvfbratedlg.cpp @@ -0,0 +1,80 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qvfbratedlg.h" + +#include +#include +#include +#include + +QVFbRateDialog::QVFbRateDialog( int rate, QWidget *parent, const char *name, + bool modal ) + : QDialog( parent, name, modal ) +{ + oldRate = rate; + + QVBoxLayout *tl = new QVBoxLayout( this, 5 ); + + QLabel *label = new QLabel( "Target frame rate:", this ); + tl->addWidget( label ); + + QHBoxLayout *hl = new QHBoxLayout( tl ); + rateSlider = new QSlider( 1, 100, 10, rate, QSlider::Horizontal, this ); + hl->addWidget( rateSlider ); + connect( rateSlider, SIGNAL(valueChanged(int)), this, SLOT(rateChanged(int)) ); + rateLabel = new QLabel( QString( "%1fps" ).arg(rate), this ); + hl->addWidget( rateLabel ); + + hl = new QHBoxLayout( tl ); + QPushButton *pb = new QPushButton( "OK", this ); + connect( pb, SIGNAL(clicked()), this, SLOT(accept()) ); + hl->addWidget( pb ); + pb = new QPushButton( "Cancel", this ); + connect( pb, SIGNAL(clicked()), this, SLOT(cancel()) ); + hl->addWidget( pb ); +} + +void QVFbRateDialog::rateChanged( int r ) +{ + if ( rateSlider->value() != r ) + rateSlider->setValue( r ); + rateLabel->setText( QString( "%1fps" ).arg(r) ); + emit updateRate(r); +} + +void QVFbRateDialog::cancel() +{ + rateChanged( oldRate ); + reject(); +} diff --git a/tools/qvfb/qvfbratedlg.h b/tools/qvfb/qvfbratedlg.h new file mode 100644 index 0000000..e5d02cb --- /dev/null +++ b/tools/qvfb/qvfbratedlg.h @@ -0,0 +1,59 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +class QLabel; +class QSlider; + +class QVFbRateDialog : public QDialog +{ + Q_OBJECT +public: + QVFbRateDialog( int value, QWidget *parent=0, const char *name=0, + bool modal=FALSE ); + +signals: + void updateRate( int r ); + +protected slots: + void rateChanged( int r ); + void cancel(); + +private: + QLabel *rateLabel; + QSlider *rateSlider; + int oldRate; +}; + + diff --git a/tools/qvfb/qvfbview.cpp b/tools/qvfb/qvfbview.cpp new file mode 100644 index 0000000..781cf78 --- /dev/null +++ b/tools/qvfb/qvfbview.cpp @@ -0,0 +1,615 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qglobal.h" +#if !defined( Q_WS_QWS ) || defined( QT_NO_QWS_MULTIPROCESS ) +#define QLock QWSSemaphore +#undef QT_NO_QWS_MULTIPROCESS +#include "../../src/kernel/qlock.cpp" +#else +#include "qlock_p.h" +#endif + +#include "qvfbview.h" +#include "qvfbhdr.h" + +#define QTE_PIPE "QtEmbedded-%1" + +#include +#include +#include +#include +#include +#include +#include "qanimationwriter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define QT_QWS_EXPERIMENTAL_REVERSE_BIT_ENDIANNESS + +QVFbView::QVFbView( int display_id, int w, int h, int d, QWidget *parent, + const char *name, uint flags ) + : QScrollView( parent, name, flags ), emulateTouchscreen(FALSE), qwslock(NULL) +{ + displayid = display_id; + viewport()->setMouseTracking( TRUE ); + viewport()->setFocusPolicy( StrongFocus ); + zm = 1; + animation = 0; + int actualdepth=d; + + switch ( d ) { + case 12: + actualdepth=16; + break; + case 1: + case 4: + case 8: + case 16: + case 32: + break; + + default: + qFatal( "Unsupported bit depth %d\n", d ); + } + + mousePipe = QString(QT_VFB_MOUSE_PIPE).arg(display_id); + keyboardPipe = QString(QT_VFB_KEYBOARD_PIPE).arg(display_id); + + unlink( mousePipe.latin1() ); + mkfifo( mousePipe.latin1(), 0666 ); + + mouseFd = open( mousePipe.latin1(), O_RDWR | O_NDELAY ); + if ( mouseFd == -1 ) { + qFatal( "Cannot open mouse pipe" ); + } + + unlink( keyboardPipe ); + mkfifo( keyboardPipe, 0666 ); + keyboardFd = open( keyboardPipe, O_RDWR | O_NDELAY ); + if ( keyboardFd == -1 ) { + qFatal( "Cannot open keyboard pipe" ); + } + + key_t key = ftok( mousePipe.latin1(), 'b' ); + + int bpl; + if ( d == 1 ) + bpl = (w*d+7)/8; + else + bpl = ((w*actualdepth+31)/32)*4; + + int dataSize = bpl * h + sizeof( QVFbHeader ); + shmId = shmget( key, dataSize, IPC_CREAT|0666); + if ( shmId != -1 ) + data = (unsigned char *)shmat( shmId, 0, 0 ); + else { + struct shmid_ds shm; + shmctl( shmId, IPC_RMID, &shm ); + shmId = shmget( key, dataSize, IPC_CREAT|0666); + data = (unsigned char *)shmat( shmId, 0, 0 ); + } + + if ( (long)data == -1 ) + qFatal( "Cannot attach to shared memory" ); + + hdr = (QVFbHeader *)data; + hdr->width = w; + hdr->height = h; + viewdepth = d; + hdr->depth = actualdepth; + hdr->linestep = bpl; + hdr->numcols = 0; + hdr->dataoffset = sizeof( QVFbHeader ); + hdr->update = QRect(); + + resizeContents( w, h ); + + timer = new QTimer( this ); + connect( timer, SIGNAL(timeout()), this, SLOT(timeout()) ); + + gammatable=0; + setGamma(1.0,1.0,1.0); + setRate( 30 ); +} + +QVFbView::~QVFbView() +{ + stopAnimation(); + sendKeyboardData( 0, 0, 0, TRUE, FALSE ); // magic die key + delete qwslock; + struct shmid_ds shm; + shmdt( (char*)data ); + shmctl( shmId, IPC_RMID, &shm ); + ::close( mouseFd ); + ::close( keyboardFd ); + unlink( mousePipe ); + unlink( keyboardPipe ); +} + +QSize QVFbView::sizeHint() const +{ + int f = 2 * frameWidth(); + return QSize( contentsWidth() + f, contentsHeight() + f ); +} + +void QVFbView::setGamma(double gr, double gg, double gb) +{ + if ( viewdepth < 12 ) + return; // not implemented + + gred=gr; ggreen=gg; gblue=gb; + + switch ( viewdepth ) { + case 12: + rsh = 12; + gsh = 7; + bsh = 1; + rmax = 15; + gmax = 15; + bmax = 15; + break; + case 16: + rsh = 11; + gsh = 5; + bsh = 0; + rmax = 31; + gmax = 63; + bmax = 31; + break; + case 32: + rsh = 16; + gsh = 8; + bsh = 0; + rmax = 255; + gmax = 255; + bmax = 255; + } + int mm = QMAX(rmax,QMAX(gmax,bmax))+1; + if ( gammatable ) + delete [] gammatable; + gammatable = new QRgb[mm]; + for (int i=0; i 255 ) r = 255; + if ( g > 255 ) g = 255; + if ( b > 255 ) b = 255; + gammatable[i] = qRgb(r,g,b); +//qDebug("%d: %d,%d,%d",i,r,g,b); + } + + setDirty(rect()); +} + +void QVFbView::getGamma(int i, QRgb& rgb) +{ + if ( i > 255 ) i = 255; + if ( i < 0 ) i = 0; + rgb = qRgb(qRed(gammatable[i*rmax/255]), + qGreen(gammatable[i*rmax/255]), + qBlue(gammatable[i*rmax/255])); +} + +int QVFbView::displayId() const +{ + return displayid; +} + +int QVFbView::displayWidth() const +{ + return hdr->width; +} + +int QVFbView::displayHeight() const +{ + return hdr->height; +} + +int QVFbView::displayDepth() const +{ + return viewdepth; +} + +void QVFbView::setZoom( double z ) +{ + if ( zm != z ) { + zm = z; + setDirty(QRect(0,0,hdr->width,hdr->height)); + resizeContents( int(hdr->width*z), int(hdr->height*z) ); + updateGeometry(); + qApp->sendPostedEvents(); + topLevelWidget()->adjustSize(); + drawScreen(); + } +} + +void QVFbView::setRate( int r ) +{ + refreshRate = r; + timer->start( 1000/r ); +} + +#ifndef Q_WS_QWS +// Get the name of the directory where Qt/Embedded temporary data should +// live. +static QString qws_dataDir() +{ + QString username = "unknown"; + const char *logname = getenv("LOGNAME"); + if ( logname ) + username = logname; + + QString dataDir = "/tmp/qtembedded-" + username; + if ( mkdir( dataDir.latin1(), 0700 ) ) { + if ( errno != EEXIST ) { + qFatal( QString("Cannot create Qt/Embedded data directory: %1") + .arg( dataDir ) ); + } + } + + struct stat buf; + if ( lstat( dataDir.latin1(), &buf ) ) + qFatal( QString( "stat failed for Qt/Embedded data directory: %1" ) + .arg( dataDir ) ); + + if ( !S_ISDIR( buf.st_mode ) ) + qFatal( QString( "%1 is not a directory" ).arg( dataDir ) ); + + if ( buf.st_uid != getuid() ) + qFatal( QString( "Qt/Embedded data directory is not owned by user %1" ) + .arg( getuid() ) ); + + if ( (buf.st_mode & 0677) != 0600 ) + qFatal( QString( "Qt/Embedded data directory has incorrect permissions: %1" ) + .arg( dataDir ) ); + + dataDir += "/"; + + return dataDir; +} +#endif + +void QVFbView::initLock() +{ + QString username = "unknown"; + const char *logname = getenv("LOGNAME"); + if ( logname ) + username = logname; + qwslock = new QLock(qws_dataDir() + QString( QTE_PIPE ).arg( displayid ), + 'd', TRUE); +} + +void QVFbView::lock() +{ + if ( !qwslock ) + initLock(); + qwslock->lock(QLock::Read); +} + +void QVFbView::unlock() +{ + if ( qwslock ) + qwslock->unlock(); +} + +void QVFbView::sendMouseData( const QPoint &pos, int buttons ) +{ + write( mouseFd, &pos, sizeof( QPoint ) ); + write( mouseFd, &buttons, sizeof( int ) ); +} + +void QVFbView::sendKeyboardData( int unicode, int keycode, int modifiers, + bool press, bool repeat ) +{ + QVFbKeyData kd; + kd.unicode = unicode | (keycode << 16); + kd.modifiers = modifiers; + kd.press = press; + kd.repeat = repeat; + write( keyboardFd, &kd, sizeof( QVFbKeyData ) ); +} + +void QVFbView::timeout() +{ + lock(); + if ( animation ) { + QRect r( hdr->update ); + r = r.intersect( QRect(0, 0, hdr->width, hdr->height ) ); + if ( r.isEmpty() ) { + animation->appendBlankFrame(); + } else { + int l; + QImage img = getBuffer( r, l ); + animation->appendFrame(img,QPoint(r.x(),r.y())); + } + } + if ( hdr->dirty ) { + drawScreen(); + } + unlock(); +} + +QImage QVFbView::getBuffer( const QRect &r, int &leading ) const +{ + switch ( viewdepth ) { + case 12: + case 16: { + static unsigned char *imgData = 0; + if ( !imgData ) { + int bpl = ((hdr->width*32+31)/32)*4; + imgData = new unsigned char [ bpl * hdr->height ]; + } + QImage img( imgData, r.width(), r.height(), 32, 0, 0, QImage::IgnoreEndian ); + const int rsh = viewdepth == 12 ? 12 : 11; + const int gsh = viewdepth == 12 ? 7 : 5; + const int bsh = viewdepth == 12 ? 1 : 0; + const int rmax = viewdepth == 12 ? 15 : 31; + const int gmax = viewdepth == 12 ? 15 : 63; + const int bmax = viewdepth == 12 ? 15 : 31; + for ( int row = 0; row < r.height(); row++ ) { + QRgb *dptr = (QRgb*)img.scanLine( row ); + ushort *sptr = (ushort*)(data + hdr->dataoffset + (r.y()+row)*hdr->linestep); + sptr += r.x(); +#ifdef QT_QWS_REVERSE_BYTE_ENDIANNESS + for ( int col=0; col < r.width()/2; col++ ) { +#else + for ( int col=0; col < r.width(); col++ ) { +#endif + ushort s = *sptr++; +#ifdef QT_QWS_REVERSE_BYTE_ENDIANNESS + ushort s2 = *sptr++; + *dptr++ = qRgb(qRed(gammatable[(s2>>rsh)&rmax]),qGreen(gammatable[(s2>>gsh)&gmax]),qBlue(gammatable[(s2>>bsh)&bmax])); +#endif + *dptr++ = qRgb(qRed(gammatable[(s>>rsh)&rmax]),qGreen(gammatable[(s>>gsh)&gmax]),qBlue(gammatable[(s>>bsh)&bmax])); + //*dptr++ = qRgb(((s>>rsh)&rmax)*255/rmax,((s>>gsh)&gmax)*255/gmax,((s>>bsh)&bmax)*255/bmax); + } + } + leading = 0; + return img; + } + case 4: { + static unsigned char *imgData = 0; + if ( !imgData ) { + int bpl = ((hdr->width*8+31)/32)*4; + imgData = new unsigned char [ bpl * hdr->height ]; + } + QImage img( imgData, r.width(), r.height(), 8, hdr->clut, 16, + QImage::IgnoreEndian ); + for ( int row = 0; row < r.height(); row++ ) { + unsigned char *dptr = img.scanLine( row ); + unsigned char *sptr = data + hdr->dataoffset + (r.y()+row)*hdr->linestep; + sptr += r.x()/2; + int col = 0; +#ifdef QT_QWS_EXPERIMENTAL_REVERSE_BIT_ENDIANNESS + if ( r.x() & 1 ) { + *dptr++ = *sptr++ & 0x0f; + col++; + } + for ( ; col < r.width()-1; col+=2 ) { + unsigned char s = *sptr++; + *dptr++ = s >> 4; + *dptr++ = s & 0x0f; + } + if ( !(r.right() & 1) ) + *dptr = *sptr >> 4; +#else + if ( r.x() & 1 ) { + *dptr++ = *sptr++ >> 4; + col++; + } + for ( ; col < r.width()-1; col+=2 ) { + unsigned char s = *sptr++; + *dptr++ = s & 0x0f; + *dptr++ = s >> 4; + } + if ( !(r.right() & 1) ) + *dptr = *sptr & 0x0f; +#endif + } + leading = 0; + return img; + } + case 32: { + leading = r.x(); + return QImage( data + hdr->dataoffset + r.y() * hdr->linestep, + hdr->width, r.height(), hdr->depth, 0, + 0, QImage::LittleEndian ); + } + case 8: { + leading = r.x(); + return QImage( data + hdr->dataoffset + r.y() * hdr->linestep, + hdr->width, r.height(), hdr->depth, hdr->clut, + 256, QImage::LittleEndian ); + } + case 1: { + leading = r.x(); + return QImage( data + hdr->dataoffset + r.y() * hdr->linestep, + hdr->width, r.height(), hdr->depth, hdr->clut, +#ifndef QT_QWS_EXPERIMENTAL_REVERSE_BIT_ENDIANNESS + 0, QImage::LittleEndian ); +#else + 0, QImage::BigEndian ); +#endif + } + } + return QImage(); +} + +void QVFbView::drawScreen() +{ + QPainter p( viewport() ); + + p.translate( -contentsX(), -contentsY() ); + + lock(); + QRect r( hdr->update ); + hdr->dirty = FALSE; + hdr->update = QRect(); + // qDebug( "update %d, %d, %dx%d", r.y(), r.x(), r.width(), r.height() ); + r = r.intersect( QRect(0, 0, hdr->width, hdr->height ) ); + if ( !r.isEmpty() ) { + if ( int(zm) != zm ) { + r.rLeft() = int(int(r.left()*zm)/zm); + r.rTop() = int(int(r.top()*zm)/zm); + r.rRight() = int(int(r.right()*zm+zm+0.0000001)/zm+1.9999); + r.rBottom() = int(int(r.bottom()*zm+zm+0.0000001)/zm+1.9999); + r.rRight() = QMIN(r.right(),hdr->width-1); + r.rBottom() = QMIN(r.bottom(),hdr->height-1); + } + int leading; + QImage img( getBuffer( r, leading ) ); + QPixmap pm; + if ( zm == 1 ) { + pm.convertFromImage( img ); + } else if ( int(zm) == zm ) { + QWMatrix m; + m.scale(zm,zm); + pm.convertFromImage( img ); + pm = pm.xForm(m); + } else { + pm.convertFromImage( img.smoothScale(int(img.width()*zm),int(img.height()*zm)) ); + } + unlock(); + p.setPen( black ); + p.setBrush( white ); + p.drawPixmap( int(r.x()*zm), int(r.y()*zm), pm, + int(leading*zm), 0, pm.width(), pm.height() ); + } else { + unlock(); + } +} + +bool QVFbView::eventFilter( QObject *obj, QEvent *e ) +{ + if ( obj == viewport() && + (e->type() == QEvent::FocusIn || e->type() == QEvent::FocusOut) ) + return TRUE; + + return QScrollView::eventFilter( obj, e ); +} + +void QVFbView::viewportPaintEvent( QPaintEvent *pe ) +{ + QRect r( pe->rect() ); + r.moveBy( contentsX(), contentsY() ); + r = QRect(int(r.x()/zm),int(r.y()/zm), + int(r.width()/zm)+1,int(r.height()/zm)+1); + setDirty(r); + drawScreen(); +} + +void QVFbView::setDirty( const QRect& r ) +{ + lock(); + hdr->update |= r; + hdr->dirty = TRUE; + unlock(); +} + +void QVFbView::contentsMousePressEvent( QMouseEvent *e ) +{ + sendMouseData( e->pos()/zm, e->stateAfter() ); +} + +void QVFbView::contentsMouseDoubleClickEvent( QMouseEvent *e ) +{ + sendMouseData( e->pos()/zm, e->stateAfter() ); +} + +void QVFbView::contentsMouseReleaseEvent( QMouseEvent *e ) +{ + sendMouseData( e->pos()/zm, e->stateAfter() ); +} + +void QVFbView::contentsMouseMoveEvent( QMouseEvent *e ) +{ + if ( !emulateTouchscreen || (e->state() & MouseButtonMask ) ) + sendMouseData( e->pos()/zm, e->state() ); +} + + + +void QVFbView::keyPressEvent( QKeyEvent *e ) +{ + sendKeyboardData(e->text()[0].unicode(), e->key(), + e->stateAfter()&(ShiftButton|ControlButton|AltButton), + TRUE, e->isAutoRepeat()); +} + +void QVFbView::keyReleaseEvent( QKeyEvent *e ) +{ + sendKeyboardData(e->ascii(), e->key(), + e->stateAfter()&(ShiftButton|ControlButton|AltButton), + FALSE, e->isAutoRepeat()); +} + + +QImage QVFbView::image() const +{ + ((QVFbView*)this)->lock(); + int l; + QImage r = getBuffer( QRect(0, 0, hdr->width, hdr->height), l ).copy(); + ((QVFbView*)this)->unlock(); + return r; +} + +void QVFbView::startAnimation( const QString& filename ) +{ + delete animation; + animation = new QAnimationWriter(filename,"MNG"); + animation->setFrameRate(refreshRate); + animation->appendFrame(QImage(data + hdr->dataoffset, + hdr->width, hdr->height, hdr->depth, hdr->clut, + 256, QImage::LittleEndian)); +} + +void QVFbView::stopAnimation() +{ + delete animation; + animation = 0; +} + +void QVFbView::setTouchscreenEmulation( bool b ) +{ + emulateTouchscreen = b; +} diff --git a/tools/qvfb/qvfbview.h b/tools/qvfb/qvfbview.h new file mode 100644 index 0000000..69acddc --- /dev/null +++ b/tools/qvfb/qvfbview.h @@ -0,0 +1,126 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + +class QImage; +class QTimer; +class QAnimationWriter; +class QLock; +struct QVFbHeader; + +class QVFbView : public QScrollView +{ + Q_OBJECT +public: + QVFbView( int display_id, int w, int h, int d, QWidget *parent = 0, + const char *name = 0, uint wflags = 0 ); + ~QVFbView(); + + int displayId() const; + int displayWidth() const; + int displayHeight() const; + int displayDepth() const; + + bool touchScreenEmulation() const { return emulateTouchscreen; } + int rate() { return refreshRate; } + bool animating() const { return !!animation; } + QImage image() const; + + void setGamma(double gr, double gg, double gb); + double gammaRed() const { return gred; } + double gammaGreen() const { return ggreen; } + double gammaBlue() const { return gblue; } + void getGamma(int i, QRgb& rgb); + void skinKeyPressEvent( QKeyEvent *e ) { keyPressEvent(e); } + void skinKeyReleaseEvent( QKeyEvent *e ) { keyReleaseEvent(e); } + + double zoom() const { return zm; } + + QSize sizeHint() const; +public slots: + void setTouchscreenEmulation( bool ); + + void setRate( int ); + void setZoom( double ); + void startAnimation( const QString& ); + void stopAnimation(); + +protected slots: + void timeout(); + +protected: + void initLock(); + void lock(); + void unlock(); + QImage getBuffer( const QRect &r, int &leading ) const; + void drawScreen(); + void sendMouseData( const QPoint &pos, int buttons ); + void sendKeyboardData( int unicode, int keycode, int modifiers, + bool press, bool repeat ); + virtual bool eventFilter( QObject *obj, QEvent *e ); + virtual void viewportPaintEvent( QPaintEvent *pe ); + virtual void contentsMousePressEvent( QMouseEvent *e ); + virtual void contentsMouseDoubleClickEvent( QMouseEvent *e ); + virtual void contentsMouseReleaseEvent( QMouseEvent *e ); + virtual void contentsMouseMoveEvent( QMouseEvent *e ); + virtual void keyPressEvent( QKeyEvent *e ); + virtual void keyReleaseEvent( QKeyEvent *e ); + +private: + bool emulateTouchscreen; + void setDirty( const QRect& ); + int shmId; + unsigned char *data; + QVFbHeader *hdr; + int viewdepth; // "faked" depth + int rsh; + int gsh; + int bsh; + int rmax; + int gmax; + int bmax; + double gred, ggreen, gblue; + QRgb* gammatable; + QLock *qwslock; + QTimer *timer; + int mouseFd; + int keyboardFd; + int refreshRate; + QString mousePipe; + QString keyboardPipe; + QAnimationWriter *animation; + int displayid; + double zm; +}; + diff --git a/tools/qvfb/skin.cpp b/tools/qvfb/skin.cpp new file mode 100644 index 0000000..6322750 --- /dev/null +++ b/tools/qvfb/skin.cpp @@ -0,0 +1,174 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "skin.h" +#include "qvfb.h" +#include "qvfbview.h" + +#include +#include +#include +#include +#include +#ifdef Q_WS_MAC +# include +#endif + +Skin::Skin( QVFb *p, const QString &skinFile, int &viewW, int &viewH ) : QWidget(p) +{ + QFile f( skinFile ); + f.open( IO_ReadOnly ); + QTextStream ts( &f ); + ts >> skinImageUpFileName; + ts >> skinImageDownFileName; + ts >> viewX1; + ts >> viewY1; + ts >> viewW; + ts >> viewH; + ts >> transparancy; + ts >> numberOfAreas; +// Debug the skin file parsing +// printf("read: -%s- -%i- -%i- -%i-\n", skinImage.latin1(), viewX1, viewY1, numberOfAreas ); + areas = new ButtonAreas[numberOfAreas]; + + for (int i = 0; i < numberOfAreas; i++) { + ts >> areas[i].name; + ts >> areas[i].keyCode; + ts >> areas[i].x1; + ts >> areas[i].y1; + ts >> areas[i].x2; + ts >> areas[i].y2; +// Debug the skin file parsing +// printf("read: -%s- -%i- -%i- -%i- -%i- -%i-\n", areas[i].name.latin1(), +// areas[i].keyCode, areas[i].x1, areas[i].y1, areas[i].x2, areas[i].y2 ); + } + + parent = p; + skinImageUp = new QPixmap( skinImageUpFileName ); + skinImageDown = new QPixmap( skinImageDownFileName ); +// setPixmap( ipaq ); + setFixedSize( skinImageUp->size() ); + QBitmap mask = skinImageUp->createHeuristicMask(); + int wf = WStyle_Customize | WType_TopLevel | WStyle_NoBorder; + parent->reparent( 0, wf, pos(), TRUE ); + parent->setMask( mask ); + parent->setFixedSize( skinImageUp->size() ); + buttonPressed = FALSE; + buttonIndex = 0; +} + + +Skin::~Skin( ) +{ +} + + +void Skin::setView( QVFbView *v ) +{ + view = v; + view->move( viewX1, viewY1 ); +#ifdef Q_WS_MAC + QMacSavedPortInfo::setAlphaTransparancy(view, transparancy); +#endif +} + + +void Skin::paintEvent( QPaintEvent * ) +{ + QPainter p( this ); +// printf("read: -%s-\n", skinImageUp.latin1()); + if (skinImageUp) + p.drawPixmap( 0, 0, *skinImageUp ); + if (buttonPressed == TRUE) { + ButtonAreas *ba = &areas[buttonIndex]; + if (skinImageDown) + p.drawPixmap( ba->x1, ba->y1, *skinImageDown, ba->x1, ba->y1, ba->x2 - ba->x1, ba->y2 - ba->y1 ); + } +} + + +void Skin::mousePressEvent( QMouseEvent *e ) +{ + if (e->button() == RightButton) { + parent->popupMenu(); + } else { + buttonPressed = FALSE; + + for (int i = 0; i < numberOfAreas; i++) { + QPoint p1( areas[i].x1, areas[i].y1 ); + QPoint p2( areas[i].x2, areas[i].y2 ); + QRect r( p1, p2 ); + if ( r.contains( e->pos() ) ) { + buttonPressed = TRUE; + buttonIndex = i; + buttonCode = areas[buttonIndex].keyCode; + QKeyEvent keyEvent( QEvent::KeyPress, buttonCode, 0, 0 ); + if (view) + view->skinKeyPressEvent( &keyEvent ); +// Debug message to be sure we are clicking the right areas +// printf("%s clicked\n", areas[i].name); + ButtonAreas *ba = &areas[buttonIndex]; + repaint( ba->x1, ba->y1, ba->x2 - ba->x1, ba->y2 - ba->y1, FALSE ); + continue; + } + } + +// This is handy for finding the areas to define rectangles for new skins +// printf("Clicked in %i,%i\n", e->pos().x(), e->pos().y()); + clickPos = e->pos(); + } +} + + +void Skin::mouseMoveEvent( QMouseEvent *e ) +{ + if ( buttonPressed == FALSE ) { + QPoint newpos = e->globalPos() - clickPos; + parent->move( newpos ); + } +} + + +void Skin::mouseReleaseEvent( QMouseEvent * ) +{ + if ( buttonPressed ) { + QKeyEvent keyEvent( QEvent::KeyRelease, buttonCode, 0, 0 ); + if (view) + view->skinKeyReleaseEvent( &keyEvent ); + buttonPressed = FALSE; + ButtonAreas *ba = &areas[buttonIndex]; + repaint( ba->x1, ba->y1, ba->x2 - ba->x1, ba->y2 - ba->y1, FALSE ); + } +} + + diff --git a/tools/qvfb/skin.h b/tools/qvfb/skin.h new file mode 100644 index 0000000..7a5b287 --- /dev/null +++ b/tools/qvfb/skin.h @@ -0,0 +1,78 @@ +/********************************************************************** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt/Embedded virtual framebuffer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include + + +class QVFb; +class QVFbView; + + +class Skin : public QWidget +{ +public: + Skin( QVFb *p, const QString &skinFile, int &viewW, int &viewH ); + ~Skin( ); + void setView( QVFbView *v ); +protected: + virtual void paintEvent( QPaintEvent * ); + virtual void mousePressEvent( QMouseEvent *e ); + virtual void mouseMoveEvent( QMouseEvent *e ); + virtual void mouseReleaseEvent( QMouseEvent * ); +private: + QVFb *parent; + QVFbView *view; + QPoint clickPos; + bool buttonPressed; + int buttonCode; + int buttonIndex; + float transparancy; + + QString skinImageUpFileName; + QString skinImageDownFileName; + QPixmap *skinImageUp; + QPixmap *skinImageDown; + int viewX1, viewY1; + int numberOfAreas; + + typedef struct { + QString name; + int keyCode; + int x1, y1; + int x2, y2; + } ButtonAreas; + + ButtonAreas *areas; +}; + + diff --git a/tools/tools.pro b/tools/tools.pro new file mode 100644 index 0000000..e10c970 --- /dev/null +++ b/tools/tools.pro @@ -0,0 +1,18 @@ +TEMPLATE = subdirs +no-png { + message("Tools not available without PNG support") +} else { + SUBDIRS = assistant/lib \ + designer \ + assistant \ + linguist + unix:SUBDIRS += qtconfig \ + mergetr \ + qconfig \ + makeqpf \ + msg2qm \ + qembed +} + +CONFIG+=ordered +REQUIRES=full-config -- cgit v1.2.3