TDE graphics utilities
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

486 lines
13KB

  1. /*
  2. Copyright (C) 2001 The Kompany
  3. 2002-2003 Ilya Konstantinov <kde-devel@future.shiny.co.il>
  4. 2002-2003 Marcus Meissner <marcus@jet.franken.de>
  5. 2003 Nadeem Hasan <nhasan@nadmm.com>
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. */
  18. #include <tqlayout.h>
  19. #include <tqwidgetstack.h>
  20. #include <tqvbuttongroup.h>
  21. #include <tqvgroupbox.h>
  22. #include <tqcombobox.h>
  23. #include <tqlineedit.h>
  24. #include <tqradiobutton.h>
  25. #include <tqwhatsthis.h>
  26. #include <tqlabel.h>
  27. #include <tqgrid.h>
  28. #include <klocale.h>
  29. #include <tdeconfig.h>
  30. #include <klistview.h>
  31. #include <kmessagebox.h>
  32. #include <kdebug.h>
  33. #include "config.h"
  34. extern "C" {
  35. #include <gphoto2.h>
  36. }
  37. #include "kamera.h"
  38. #include "kameraconfigdialog.h"
  39. #include "kameradevice.moc"
  40. // Define some parts of the old API
  41. #define GP_PROMPT_OK 0
  42. #define GP_PROMPT_CANCEL -1
  43. static const int INDEX_NONE= 0;
  44. static const int INDEX_SERIAL = 1;
  45. static const int INDEX_USB= 3;
  46. static GPContext *glob_context = 0;
  47. KCamera::KCamera(const TQString &name, const TQString &path)
  48. {
  49. m_name = name;
  50. m_model = name;
  51. m_path = path;
  52. m_camera = NULL;
  53. }
  54. KCamera::~KCamera()
  55. {
  56. if(m_camera)
  57. gp_camera_free(m_camera);
  58. if(m_abilitylist)
  59. gp_abilities_list_free(m_abilitylist);
  60. }
  61. bool KCamera::initInformation()
  62. {
  63. if (!m_model)
  64. return false;
  65. if(gp_abilities_list_new(&m_abilitylist) != GP_OK) {
  66. emit error(i18n("Could not allocate memory for abilities list."));
  67. return false;
  68. }
  69. if(gp_abilities_list_load(m_abilitylist, glob_context) != GP_OK) {
  70. emit error(i18n("Could not load ability list."));
  71. return false;
  72. }
  73. int index = gp_abilities_list_lookup_model(m_abilitylist, m_model.local8Bit().data());
  74. if(index < 0) {
  75. emit error(i18n("Description of abilities for camera %1 is not available."
  76. " Configuration options may be incorrect.").arg(m_model));
  77. return false;
  78. }
  79. gp_abilities_list_get_abilities(m_abilitylist, index, &m_abilities);
  80. return true;
  81. }
  82. bool KCamera::initCamera()
  83. {
  84. if (m_camera)
  85. return m_camera;
  86. else {
  87. int result;
  88. initInformation();
  89. if (!m_model || !m_path)
  90. return false;
  91. result = gp_camera_new(&m_camera);
  92. if (result != GP_OK) {
  93. // m_camera is not initialized, so we cannot get result as string
  94. emit error(i18n("Could not access driver. Check your gPhoto2 installation."));
  95. return false;
  96. }
  97. // set the camera's model
  98. GPPortInfo info;
  99. GPPortInfoList *il;
  100. gp_port_info_list_new(&il);
  101. gp_port_info_list_load(il);
  102. gp_port_info_list_get_info(il, gp_port_info_list_lookup_path(il, m_path.local8Bit().data()), &info);
  103. gp_camera_set_abilities(m_camera, m_abilities);
  104. gp_camera_set_port_info(m_camera, info);
  105. gp_port_info_list_free(il);
  106. // this might take some time (esp. for non-existant camera) - better be done asynchronously
  107. result = gp_camera_init(m_camera, glob_context);
  108. if (result != GP_OK) {
  109. gp_camera_free(m_camera);
  110. m_camera = NULL;
  111. emit error(
  112. i18n("Unable to initialize camera. Check your port settings and camera connectivity and try again."),
  113. gp_result_as_string(result));
  114. return false;
  115. }
  116. return m_camera;
  117. }
  118. }
  119. Camera* KCamera::camera()
  120. {
  121. initCamera();
  122. return m_camera;
  123. }
  124. TQString KCamera::summary()
  125. {
  126. int result;
  127. CameraText summary;
  128. initCamera();
  129. result = gp_camera_get_summary(m_camera, &summary, glob_context);
  130. if (result != GP_OK)
  131. return i18n("No camera summary information is available.\n");
  132. return TQString(summary.text);
  133. }
  134. bool KCamera::configure()
  135. {
  136. CameraWidget *window;
  137. int result;
  138. initCamera();
  139. result = gp_camera_get_config(m_camera, &window, glob_context);
  140. if (result != GP_OK) {
  141. emit error(i18n("Camera configuration failed."), gp_result_as_string(result));
  142. return false;
  143. }
  144. KameraConfigDialog kcd(m_camera, window);
  145. result = kcd.exec() ? GP_PROMPT_OK : GP_PROMPT_CANCEL;
  146. if (result == GP_PROMPT_OK) {
  147. result = gp_camera_set_config(m_camera, window, glob_context);
  148. if (result != GP_OK) {
  149. emit error(i18n("Camera configuration failed."), gp_result_as_string(result));
  150. return false;
  151. }
  152. }
  153. return true;
  154. }
  155. bool KCamera::test()
  156. {
  157. // TODO: Make testing non-blocking (maybe via KIO?)
  158. // Currently, a failed serial test times out at about 30 sec.
  159. return camera() != 0;
  160. }
  161. void KCamera::load(TDEConfig *config)
  162. {
  163. config->setGroup(m_name);
  164. if (m_model.isNull())
  165. m_model = config->readEntry("Model");
  166. if (m_path.isNull())
  167. m_path = config->readEntry("Path");
  168. invalidateCamera();
  169. }
  170. void KCamera::save(TDEConfig *config)
  171. {
  172. config->setGroup(m_name);
  173. config->writeEntry("Model", m_model);
  174. config->writeEntry("Path", m_path);
  175. }
  176. TQString KCamera::portName()
  177. {
  178. TQString port = m_path.left(m_path.find(":")).lower();
  179. if (port == "serial") return i18n("Serial");
  180. if (port == "usb") return i18n("USB");
  181. return i18n("Unknown port");
  182. }
  183. void KCamera::setName(const TQString &name)
  184. {
  185. m_name = name;
  186. }
  187. void KCamera::setModel(const TQString &model)
  188. {
  189. m_model = model;
  190. invalidateCamera();
  191. initInformation();
  192. }
  193. void KCamera::setPath(const TQString &path)
  194. {
  195. m_path = path;
  196. invalidateCamera();
  197. }
  198. void KCamera::invalidateCamera()
  199. {
  200. if (m_camera) {
  201. gp_camera_free(m_camera);
  202. m_camera = NULL;
  203. }
  204. }
  205. bool KCamera::isTestable() const
  206. {
  207. return true;
  208. }
  209. bool KCamera::isConfigurable()
  210. {
  211. initInformation();
  212. return m_abilities.operations & GP_OPERATION_CONFIG;
  213. }
  214. TQStringList KCamera::supportedPorts()
  215. {
  216. initInformation();
  217. TQStringList ports;
  218. if (m_abilities.port & GP_PORT_SERIAL)
  219. ports.append("serial");
  220. if (m_abilities.port & GP_PORT_USB)
  221. ports.append("usb");
  222. return ports;
  223. }
  224. CameraAbilities KCamera::abilities()
  225. {
  226. return m_abilities;
  227. }
  228. // ---------- KameraSelectCamera ------------
  229. KameraDeviceSelectDialog::KameraDeviceSelectDialog(TQWidget *parent, KCamera *device)
  230. : KDialogBase(parent, "kkameradeviceselect", true, i18n("Select Camera Device"), Ok | Cancel, Ok, true)
  231. {
  232. m_device = device;
  233. connect(m_device, TQT_SIGNAL(error(const TQString &)),
  234. TQT_SLOT(slot_error(const TQString &)));
  235. connect(m_device, TQT_SIGNAL(error(const TQString &, const TQString &)),
  236. TQT_SLOT(slot_error(const TQString &, const TQString &)));
  237. TQWidget *page = new TQWidget( this );
  238. setMainWidget(page);
  239. // a layout with vertical boxes
  240. TQHBoxLayout *topLayout = new TQHBoxLayout(page, 0, KDialog::spacingHint());
  241. // the models list
  242. m_modelSel = new KListView(page);
  243. topLayout->addWidget( m_modelSel );
  244. m_modelSel->addColumn(i18n("Supported Cameras"));
  245. m_modelSel->setColumnWidthMode(0, TQListView::Maximum);
  246. connect(m_modelSel, TQT_SIGNAL(selectionChanged(TQListViewItem *)),
  247. TQT_SLOT(slot_setModel(TQListViewItem *)));
  248. // make sure listview only as wide as it needs to be
  249. m_modelSel->setSizePolicy(TQSizePolicy(TQSizePolicy::Maximum,
  250. TQSizePolicy::Preferred));
  251. TQVBoxLayout *rightLayout = new TQVBoxLayout(0L, 0, KDialog::spacingHint());
  252. topLayout->addLayout( rightLayout );
  253. m_portSelectGroup = new TQVButtonGroup(i18n("Port"), page);
  254. rightLayout->addWidget(m_portSelectGroup);
  255. m_portSettingsGroup = new TQVGroupBox(i18n("Port Settings"), page);
  256. rightLayout->addWidget(m_portSettingsGroup);
  257. // Create port type selection radiobuttons.
  258. m_serialRB = new TQRadioButton(i18n("Serial"), m_portSelectGroup);
  259. m_portSelectGroup->insert(m_serialRB, INDEX_SERIAL);
  260. TQWhatsThis::add(m_serialRB, i18n("If this option is checked, the camera would have to be connected one of the serial ports (known as COM in Microsoft Windows) in your computer."));
  261. m_USBRB = new TQRadioButton(i18n("USB"), m_portSelectGroup);
  262. m_portSelectGroup->insert(m_USBRB, INDEX_USB);
  263. TQWhatsThis::add(m_USBRB, i18n("If this option is checked, the camera would have to be connected to one of the USB slots in your computer or USB hub."));
  264. // Create port settings widget stack
  265. m_settingsStack = new TQWidgetStack(m_portSettingsGroup);
  266. connect(m_portSelectGroup, TQT_SIGNAL(clicked(int)),
  267. m_settingsStack, TQT_SLOT(raiseWidget(int)));
  268. // none tab
  269. m_settingsStack->addWidget(new TQLabel(i18n("No port type selected."),
  270. m_settingsStack), INDEX_NONE);
  271. // serial tab
  272. TQGrid *grid = new TQGrid(2, m_settingsStack);
  273. grid->setSpacing(KDialog::spacingHint());
  274. new TQLabel(i18n("Port:"), grid);
  275. m_serialPortCombo = new TQComboBox(TRUE, grid);
  276. TQWhatsThis::add(m_serialPortCombo, i18n("Here you should choose the serial port you connect the camera to."));
  277. m_settingsStack->addWidget(grid, INDEX_SERIAL);
  278. grid = new TQGrid(2, m_settingsStack);
  279. grid->setSpacing(KDialog::spacingHint());
  280. new TQLabel(i18n("Port"), grid);
  281. m_settingsStack->addWidget(new
  282. TQLabel(i18n("No further configuration is required for USB."),
  283. m_settingsStack), INDEX_USB);
  284. // query gphoto2 for existing serial ports
  285. GPPortInfoList *list;
  286. GPPortInfo info;
  287. int gphoto_ports=0;
  288. gp_port_info_list_new(&list);
  289. if(gp_port_info_list_load(list) >= 0) {
  290. gphoto_ports = gp_port_info_list_count(list);
  291. }
  292. for (int i = 0; i < gphoto_ports; i++) {
  293. if (gp_port_info_list_get_info(list, i, &info) >= 0) {
  294. #ifdef HAVE_GPHOTO2_5
  295. char *xpath;
  296. gp_port_info_get_path (info, &xpath);
  297. if (strncmp(xpath, "serial:", 7) == 0)
  298. m_serialPortCombo->insertItem(TQString::fromLatin1(xpath).mid(7));
  299. #else
  300. if (strncmp(info.path, "serial:", 7) == 0)
  301. m_serialPortCombo->insertItem(TQString::fromLatin1(info.path).mid(7));
  302. #endif
  303. }
  304. }
  305. gp_port_info_list_free(list);
  306. // add a spacer
  307. rightLayout->addStretch();
  308. populateCameraListView();
  309. load();
  310. enableButtonOK(false );
  311. m_portSelectGroup->setEnabled( false );
  312. m_portSettingsGroup->setEnabled( false );
  313. }
  314. bool KameraDeviceSelectDialog::populateCameraListView()
  315. {
  316. gp_abilities_list_new (&m_device->m_abilitylist);
  317. gp_abilities_list_load(m_device->m_abilitylist, glob_context);
  318. int numCams = gp_abilities_list_count(m_device->m_abilitylist);
  319. CameraAbilities a;
  320. if(numCams < 0) {
  321. // XXX libgphoto2 failed to get te camera list
  322. return false;
  323. } else {
  324. for(int x = 0; x < numCams; ++x) {
  325. if(gp_abilities_list_get_abilities(m_device->m_abilitylist, x, &a) == GP_OK) {
  326. new TQListViewItem(m_modelSel, a.model);
  327. }
  328. }
  329. return true;
  330. }
  331. }
  332. void KameraDeviceSelectDialog::save()
  333. {
  334. m_device->setModel(m_modelSel->currentItem()->text(0));
  335. if (m_portSelectGroup->selected()) {
  336. TQString type = m_portSelectGroup->selected()->text();
  337. if(type == i18n("Serial"))
  338. m_device->setPath("serial:" + m_serialPortCombo->currentText());
  339. else if(type == i18n("USB"))
  340. m_device->setPath("usb:");
  341. } else {
  342. // This camera has no port type (e.g. "Directory Browse" camera).
  343. // Do nothing.
  344. }
  345. }
  346. void KameraDeviceSelectDialog::load()
  347. {
  348. TQString path = m_device->path();
  349. TQString port = path.left(path.find(":")).lower();
  350. if (port == "serial") setPortType(INDEX_SERIAL);
  351. if (port == "usb") setPortType(INDEX_USB);
  352. TQListViewItem *modelItem = m_modelSel->firstChild();
  353. if( modelItem)
  354. {
  355. do {
  356. if (modelItem->text(0) == m_device->model()) {
  357. m_modelSel->setSelected(modelItem, true);
  358. m_modelSel->ensureItemVisible(modelItem);
  359. }
  360. } while ( ( modelItem = modelItem->nextSibling() ) );
  361. }
  362. }
  363. void KameraDeviceSelectDialog::slot_setModel(TQListViewItem *item)
  364. {
  365. enableButtonOK(true);
  366. m_portSelectGroup->setEnabled(true);
  367. m_portSettingsGroup->setEnabled(true);
  368. TQString model = item->text(0);
  369. CameraAbilities abilities;
  370. int index = gp_abilities_list_lookup_model(m_device->m_abilitylist, model.local8Bit().data());
  371. if(index < 0) {
  372. slot_error(i18n("Description of abilities for camera %1 is not available."
  373. " Configuration options may be incorrect.").arg(model));
  374. }
  375. int result = gp_abilities_list_get_abilities(m_device->m_abilitylist, index, &abilities);
  376. if (result == GP_OK) {
  377. // enable radiobuttons for supported port types
  378. m_serialRB->setEnabled(abilities.port & GP_PORT_SERIAL);
  379. m_USBRB->setEnabled(abilities.port & GP_PORT_USB);
  380. // turn off any selected port
  381. TQButton *selected = m_portSelectGroup->selected();
  382. if(selected != NULL)
  383. selected->toggle();
  384. // if there's only one available port type, make sure it's selected
  385. if (abilities.port == GP_PORT_SERIAL)
  386. setPortType(INDEX_SERIAL);
  387. if (abilities.port == GP_PORT_USB)
  388. setPortType(INDEX_USB);
  389. } else {
  390. slot_error(i18n("Description of abilities for camera %1 is not available."
  391. " Configuration options may be incorrect.").arg(model));
  392. }
  393. }
  394. void KameraDeviceSelectDialog::setPortType(int type)
  395. {
  396. // Enable the correct button
  397. m_portSelectGroup->setButton(type);
  398. // Bring the right tab to the front
  399. m_settingsStack->raiseWidget(type);
  400. }
  401. void KameraDeviceSelectDialog::slot_error(const TQString &message)
  402. {
  403. KMessageBox::error(this, message);
  404. }
  405. void KameraDeviceSelectDialog::slot_error(const TQString &message, const TQString &details)
  406. {
  407. KMessageBox::detailedError(this, message, details);
  408. }